Origin Function

make 에서 사용되는 변수는 makefile 에서 정의한 변수 외에 환경 변수나 명령 라인 에서 정의한 변수가 사용될 수 있습니다. origin 함수를 이용하면 어디서 정의된 변수가 최종적으로 사용되는지를 알 수 있습니다.

  • 먼저 변수가 사용되는 우선순위는

    1. Makefile 에서 직접 정의한 변수가 우선순위가 높고
    2. 그다음이 환경 변수에서 정의한 변수
    3. 만약에 아무 곳에도 변수가 정의되어 있지 않으면 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] :