[makefile] makefile 기호 $ @와 $ <는 무엇을 의미합니까?
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
무엇을 $@하고 $<정확합니까?
답변
$@생성되는 파일의 이름이며 $<첫 번째 전제 조건 (일반적으로 소스 파일)입니다. GNU Make 매뉴얼 에서 이러한 모든 특수 변수 목록을 찾을 수 있습니다 .
예를 들어 다음 선언을 고려하십시오.
all: library.cpp main.cpp
이 경우 :
$@~에 평가하다all$<~에 평가하다library.cpp$^~에 평가하다library.cpp main.cpp
답변
$@및 $<호출되는 자동 변수를 . 변수 $@는 작성된 파일 이름 (예 : 대상)을 $<나타내고 출력 파일을 작성하는 데 필요한 첫 번째 전제 조건을 나타냅니다.
예를 들면 다음과 같습니다.
hello.o: hello.c hello.h
gcc -c $< -o $@
여기서, hello.o출력 파일입니다. 이것이 $@확장되는 것입니다. 첫 번째 종속성은 hello.c입니다. 그것이 $<확장되는 것입니다.
-c플래그는 생성 .o파일을; man gcc자세한 설명 은 참조하십시오 . 는 -o만들 수있는 출력 파일을 지정합니다.
자세한 내용은 Linux Makefiles에 대한이 기사를 읽으십시오 .
또한 GNU make매뉴얼을 확인할 수 있습니다 . Makefile을보다 쉽게 만들고 디버깅 할 수 있습니다.
이 명령을 실행하면 makefile 데이터베이스가 출력됩니다.
make -p
답변
에서 GNU의 메이크업, 제 3 판, P와 프로젝트 관리. 16 ( GNU Free Documentation License 하에 있음 ) :
자동 변수 는
make규칙이 일치 한 후에 설정됩니다 . 대상 및 전제 조건 목록에서 요소에 대한 액세스를 제공하므로 파일 이름을 명시 적으로 지정할 필요가 없습니다. 코드 중복을 피하는 데 매우 유용하지만보다 일반적인 패턴 규칙을 정의 할 때 중요합니다.7 가지“핵심”자동 변수가 있습니다 :
$@: 대상을 나타내는 파일 이름입니다.
$%: 아카이브 멤버 스펙의 파일 이름 요소입니다.
$<: 첫 번째 전제 조건의 파일 이름입니다.
$?: 대상보다 최신 인 모든 전제 조건의 이름을 공백으로 구분합니다.
$^: 모든 전제 조건의 파일 이름을 공백으로 구분합니다. 이 목록에는 편집, 복사 등과 같은 대부분의 용도에서 중복을 원하지 않기 때문에 중복 된 파일 이름이 제거되었습니다.
$+:와 유사하게$^, 이것은$+중복 을 포함하는 것을 제외하고 공백으로 구분 된 모든 전제 조건의 이름입니다 . 이 변수는 중복 값이 의미가있는 링커에 대한 인수와 같은 특정 상황을 위해 만들어졌습니다.
$*: 대상 파일 이름의 스템입니다. 줄기는 일반적으로 접미사가없는 파일 이름입니다. 패턴 규칙 외부에서의 사용은 권장하지 않습니다.또한 위의 각 변수에는 다른 제조사와의 호환성을 위해 두 가지 변형이 있습니다. 하나의 변형은 값의 디렉토리 부분 만 반환합니다. 이것은 심볼에 “D”를 추가하여 표시되는
$(@D),$(<D)등의 다른 변형 반환 값의 파일 부. 이것은, 기호에 “F”를 추가로 표시됩니다$(@F),$(<F)이러한 변형의 이름은 괄호로 묶어야합니다 둘 이상의 문자 길이 너무 있다는 등 참고. GNU make는 dir 및 notdir 함수에 대한보다 읽기 쉬운 대안을 제공합니다.
답변
$@와는 $<특별한 매크로입니다.
어디:
$@ 대상의 파일 이름입니다.
$< 첫 번째 종속성의 이름입니다.
답변
메이크는 빌드 hello중 하나가 있다면 실행을 main.cpp, hello.cpp, factorial.cpp변경. 해당 사양을 달성 할 수있는 가장 작은 Makefile은 다음과 같습니다.
hello: main.cpp hello.cpp factorial.cpp
g++ -o hello main.cpp hello.cpp factorial.cpp
- 프로 : 매우 읽기 쉽다
- 단점 : 유지 관리의 악몽, C ++ 종속성의 중복
- 단점 : 효율성 문제, 하나만 변경된 경우에도 모든 C ++를 다시 컴파일
위의 내용을 개선하기 위해 편집 된 C ++ 파일 만 컴파일합니다. 그런 다음 결과 객체 파일을 서로 연결하면됩니다.
OBJECTS=main.o hello.o factorial.o
hello: $(OBJECTS)
g++ -o hello $(OBJECTS)
main.o: main.cpp
g++ -c main.cpp
hello.o: hello.cpp
g++ -c hello.cpp
factorial.o: factorial.cpp
g++ -c factorial.cpp
- 프로 : 효율성 문제 해결
- 죄수 : 새로운 유지 관리 악몽, 객체 파일 규칙의 오타 가능성
이를 개선하기 위해 모든 객체 파일 규칙을 단일 .cpp.o규칙으로 바꿀 수 있습니다 .
OBJECTS=main.o hello.o factorial.o
hello: $(OBJECTS)
g++ -o hello $(OBJECTS)
.cpp.o:
g++ -c $< -o $@
- 찬성 : 짧은 makefile로 돌아가서 약간 읽기 쉽다.
여기에 .cpp.o규칙을 구축하는 방법을 정의 anyfile.o에서 anyfile.cpp.
$<이 경우 첫 번째 종속성과 일치합니다.anyfile.cpp$@이 경우 타겟과 일치합니다anyfile.o.
Makefile에 존재하는 다른 변경 사항은 다음과 같습니다.
- 컴파일러를 g ++에서 C ++ 컴파일러로 쉽게 변경할 수 있습니다.
- 컴파일러 옵션을보다 쉽게 변경할 수 있습니다.
- 링커 옵션을보다 쉽게 변경할 수 있습니다.
- C ++ 소스 파일 및 출력을보다 쉽게 변경할 수 있습니다.
- 응용 프로그램 빌드를 시도하기 전에 모든 소스 파일이 있는지 확인하는 빠른 검사 역할을하는 기본 규칙 ‘all’이 추가되었습니다.
답변
소스를 컴파일하고 싶지만 다른 디렉토리에 객체가있는 경우 예를 들어 :
당신은해야합니다 :
gcc -c -o <obj/1.o> <srcs/1.c> <obj/2.o> <srcs/2.c> ...
그러나 대부분의 매크로에서 결과는 다음과 같이 모든 객체와 모든 소스가 뒤 따릅니다.
gcc -c -o <all OBJ path> <all SRC path>
그래서 이것은 아무것도 컴파일하지 않을 것입니다 ^^ 객체 파일을 다른 디렉토리에 넣을 수 없습니다 🙁
해결책은 이러한 특수 매크로를 사용하는 것입니다
$@ $<
이것은 SRC (src / file.c)의 각 .c 파일에 대해 .o 파일 (obj / file.o)을 생성합니다.
$(OBJ):$(SRC)
gcc -c -o $@ $< $(HEADERS) $(FLAGS)
그 뜻은 :
$@ = $(OBJ)
$< = $(SRC)
그러나 OBJ의 모든 라인의 INSTEAD 라인과 SRC의 모든 라인
답변
