Origin Function
make 에서 사용되는 변수는 makefile 에서 정의한 변수 외에 환경 변수나 명령 라인 에서
정의한 변수가 사용될 수 있습니다.
origin
함수를 이용하면 어디서 정의된 변수가 최종적으로 사용되는지를 알 수 있습니다.
먼저 변수가 사용되는 우선순위는
- Makefile 에서 직접 정의한 변수가 우선순위가 높고
- 그다음이 환경 변수에서 정의한 변수
- 만약에 아무 곳에도 변수가 정의되어 있지 않으면 make 에 default 로 포함된 변수값이 사용됩니다.( 예를 들어 CC 변수값은 cc 가 된다 )
- Makefile 에서 정의한 변수보다 우선순위가 높은게 있는데 바로 명령 라인 에서 정의할 경우입니다. 명령 라인에서 정의한 변수는 자동으로 export 되므로 sub-make 에서도 사용할 수 있습니다.
# Makefile 에서 정의한 변수 대신 CC 변수값으로 clang 이 사용된다.
sh$ make CC=clang
# Makefile 에서 정의한 변수 대신 환경 변수에서 정의한 값이 사용된다.
sh$ make -e # --environment-overrides
- 마지막으로 위에서 설명한 우선순위를 모두 무시하고 변수값이 사용되려면 Makefile 에서 변수를 정의할때 override 지시자를 사용하면 됩니다.
undefined
만약에 Makefile 에 foo 변수 정의가 존재하지 않고, 또한 환경 변수도 존재하지 않고, make 명령 실행시 명령 라인에서 변수값을 설정하지도 않았다면 foo 변수는 undefined 상태가 됩니다.
builtin 변수는 undefined 상태에 해당하지 않습니다.
$(info $(origin foo))
결과: undefined
default
make 실행시 default 로 설정되는 변수들입니다 ( make -p
명령으로 볼 수 있습니다 ).
만약에 아무 곳에도 변수가 정의되어 있지 않으면 여기에 설정되어 있는 값이 사용됩니다.
이 변수들은 -R
( --no-builtin-variables ) 옵션을 사용하면 삭제됩니다.
$(info $(origin CC))
결과: default
$(info $(CC))
결과: cc
environment
Makefile 내에는 CC 변수가 설정되어 있지 않지만 CC 환경 변수가 설정되어 있으면 환경 변수값이 사용됩니다.
sh$ export CC=clang # CC 환경 변수 설정
------------------
$(info $(origin CC))
결과: environment
$(info $(CC))
결과: clang
environment override
이것은 make 명령을 실행 할때 -e
( --environment-overrides ) 옵션을 사용할 경우를 나타냅니다.
그러면 Makefile 내에서 직접 설정한 변수값 대신에 환경 변수값이 사용됩니다.
sh$ export CC=clang # CC 환경 변수 설정
--------------------
CC := gcc # Makefile 내에서 CC 값을 gcc 로 설정
--------------------
sh$ make -e # make 명령 실행시 '-e' 옵션 사용
--------------------
$(info $(origin CC))
결과: environment override
$(info $(CC)) # Makefile 에서 설정한 값 대신 환경 변수값이 사용된다.
결과: clang
file
Makefile 에서 설정한 변수값이 사용될 경우 입니다.
CC := gcc # Makefile 에서 CC 값을 gcc 로 설정
---------------
$(info $(origin CC))
결과: file
command line
make 명령의 command line 에서 변수값을 설정하면 Makefile 에서 설정한 값에 우선해서 적용됩니다.
CC := gcc # Makefile 내에서 CC 값을 gcc 로 설정
------------------
sh$ make CC=clang # make 명령의 command line 에서 CC 값을 clang 으로 설정
------------------
$(info $(origin CC))
결과: command line
$(info $(CC)) # Makefile 에서 설정한 값 대신에 command line 에서 설정한 값이 사용된다.
결과: clang
override
Makefile 에서 변수값을 정의할때 override
지시자를 사용하면
1 . make 명령의 command line 에서 설정한 값이 적용되지 않습니다.
override CC := gcc # Makefile 에서 CC 변수를 정의할때 override 지시자를 사용
-------------------
sh$ make CC=clang
# 또는
sh$ make -e
-------------------
$(info $(origin CC))
결과: override
$(info $(CC)) # make 명령의 command line 에서 설정한 값이 적용되지 않는다.
결과: gcc
2 . 또한 include 한 파일에서 설정한 값도 적용되지 않습니다.
sh$ cat inc.mk
CC := clang
-------------------
override CC := gcc # Makefile 에서 CC 변수를 정의할때 override 지시자를 사용
include inc.mk
$(info $(origin CC))
결과: override
$(info $(CC)) # inc.mk 에서 설정한 값이 적용되지 않는다.
결과: gcc
3 . override 기능은 override 지시자를 사용한 해당 Makefile 에서만 적용되고 sub-make 까지 적용되지는 않습니다.
automatic
recipe 실행 시에 설정되는 automatic 변수들
all:
@echo $(origin @) # $@ 변수
결과: automatic
예제 )
다음은 print_var
함수를 정의하여 변수 정보를 표시하는 예입니다.
SRCS := foo.c bar.c zoo.c
print_var = $(foreach v,$(1), \
$(info $v [$(origin $v)] : $($v)))
$(call print_var,CC SRCS release foo bar)
########## 실행 결과 ##########
sh$ foo=100 make release=1
CC [default] : cc
SRCS [file] : foo.c bar.c zoo.c
release [command line] : 1
foo [environment] : 100
bar [undefined] :