[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의 모든 라인


답변