Automatic Variables
recipe 실행 시 자동으로 설정되는 변수들입니다.
기본적으로 1 문자 변수인데 뒤에 D
가 붙은 것은 Directory 부분을,
F
가 붙은 것은 File 부분을 나타냅니다.
automatic 변수는 eval 함수로 재정의해 사용할 수 없습니다.
$@ , $(@D) , $(@F)
타겟 파일 이름을 나타냅니다.
foo/bar/zoo.o :
@echo $@ : $(@D) : $(@F)
###### 실행 결과 ######
foo/bar/zoo.o : foo/bar : zoo.o
$< , $(<D) , $(<F)
prerequisite 리스트에서 첫 번째 파일을 나타냅니다.
소스 파일을 컴파일 해서 오브젝트 파일을 만들때 $<
를 사용해야지 $^
를 사용하면
헤더 파일까지 컴파일됩니다.
main : aaa/bbb/foo.o ccc/ddd/bar.o eee/fff/zoo.o
@echo $< : $(<D) : $(<F)
.DEFAULT: ;
###### 실행 결과 ######
aaa/bbb/foo.o : aaa/bbb : foo.o
-------------------------------------------
lib/%.o: lib/%.c lib/%.h
@echo $< : $(<D) : $(<F)
%.c %.h: ;
###### 실행 결과 ######
sh$ make lib/foo/bar.o
lib/foo/bar.c : lib/foo : bar.c
$^ , $(^D) , $(^F)
$+ , $(+D) , $(+F)
prerequisites 에 존재하는 파일 리스트 전체를 나타냅니다.
$^
는 중복되는 파일이 있을 경우 제거되는데 반해, $+
는 중복을 포함하여 있는 그대로 출력합니다.
링크 시에는 라이브러리가 중복되어 나타날 수 있는데 그때 사용할 수 있습니다.
여기에 order-only prerequisites 은 포함되지 않습니다.
main : xxx/yyy/libfoo.a aaa/bbb/libbar.a xxx/yyy/libfoo.a
@echo $^ # xxx/yyy/libfoo.a 는 중복되는 파일
@echo $(^D) : $(^F)
@echo
@echo $+
@echo $(+D) : $(+F)
.DEFAULT: ;
###### 실행 결과 ######
xxx/yyy/libfoo.a aaa/bbb/libbar.a # '$^' 는 xxx/yyy/libfoo.a 중복이 제거된다.
xxx/yyy aaa/bbb : libfoo.a libbar.a
xxx/yyy/libfoo.a aaa/bbb/libbar.a xxx/yyy/libfoo.a # '$+' 는 있는 그대로 출력된다.
xxx/yyy aaa/bbb xxx/yyy : libfoo.a libbar.a libfoo.a
$? , $(?D) , $(?F)
prerequisites 리스트에서 타겟 파일보다 newer 파일이 있을 경우 설정됩니다.
# prog 파일보다 xxx/yyy/zoo.o 파일이 최신이라면
prog : aaa/bbb/foo.o ccc/ddd/bar.o xxx/yyy/zoo.o
@echo $?
@echo $(?D) : $(?F)
.DEFAULT: ;
###### 실행 결과 ######
xxx/yyy/zoo.o # aaa/bbb/foo.o ccc/ddd/bar.o 파일은 제외된다.
xxx/yyy : zoo.o
$* , $(*D) , $(*F)
pattern rule 에서 stem ( %
패턴에 해당하는 부분 ) 을 나타냅니다.
lib/%.o: lib/%.c
@echo $* : $(*D) : $(*F)
%.c: ;
###### 실행 결과 ######
sh$ make lib/foo/bar/zoo.o
foo/bar/zoo : foo/bar : zoo
다음은 활용하여 make 변수값을 조회하는 예입니다.
AA := 100
print-%:
@echo $* = $($*) from $(origin $*)
###### 실행 결과 ######
sh$ make print-AA # 변수 AA 값을 조회
AA = 100 from file
sh$ BB=200 make print-BB
BB = 200 from environment
sh$ make print-CC
CC = cc from default
sh$ make print-DD DD=300
DD = 300 from command line
$%
타겟 파일이 archive 파일( .a )의 멤버일 경우 설정됩니다 ( ( )
안에 들어있는 파일 ).
이때 $@
값은 archive 파일 이름이 됩니다.
이 변수를 pattern rule 의 stem 을 나타내는 변수로 사용하는 것이 더 좋아 보이기는 하지만 원래 make 초기에는 implicit rule 로 pattern rule 대신에 suffix rule 이 사용됐기 때문에 그런것 같습니다.
libfoo.a(aaa/bbb/foo.o ccc/ddd/bar.o) :
@echo $% : $(%D) : $(%F)
@echo $@
###### 실행 결과 ######
sh$ make
aaa/bbb/foo.o : aaa/bbb : foo.o # 디폴트 타겟은 첫 번째 멤버 파일이 된다.
libfoo.a # '$@' 값은 archive 파일 이름
sh$ make 'libfoo.a(aaa/bbb/foo.o)' # 같은 결과
aaa/bbb/foo.o : aaa/bbb : foo.o
libfoo.a
sh$ make 'libfoo.a(ccc/ddd/bar.o)'
ccc/ddd/bar.o : ccc/ddd : bar.o
libfoo.a
$|
rule 정의에서 |
문자 뒤에 오는 order-only prerequisite 리스트를 나타냅니다.
이 변수는 따로 $(|D)
, $(|F)
변수가 없습니다.
main : aaa bbb ccc | foo bar zoo
@echo $|
.DEFAULT: ;
###### 실행 결과 ######
foo bar zoo