두 가지 형태의 변수가 있다:
recursive
, =
): 변수가 정의되는 시점이 아닌 사용되는 시점에서 관측한다.simply expanded
, :=
): 다른 프로그래밍 언어와 마찬가지로 정의된 시점으로 확장된다.# Recursive variable. This will print "later" below
one = one ${later_variable}
# Simply expanded variable. This will not print "later" below
two := two ${later_variable}
later_variable = later
all:
echo $(one)
echo $(two)
위 예제는 =
과 :=
의 사용을 보여준다. one
은 =
으로 정의되었기 때문에 사용되는 시점인 all
을 target
으로 가지는 rule
의 command
인 echo
가 실행되는 시점에서의 later_variable
을 출력하며 따라서 one
의 값은 one later
가 된다.
반면, two
는 :=
로 정의되었기 때문에 정의되는 시점의 later_variable
값이 대입되며 이는 현 시점에서 존재하지 않는 변수이므로 빈 문자열이 된다. 따라서 two
가 가지는 최종 결과값은 two
가 된다.
one = hello
# one gets defined as a simply expanded variable (:=) and thus can handle appending
one := ${one} there
all:
echo $(one)
단순 확장형은 변수의 덧붙임을 허용한다. 재귀형 선언은 무한 반복을 발생시켜 에러를 야기한다. 위 예제에서 one
의 재정의를 위해 =
를 사용하게 되면 무한 반복으로 make
가 종료된다:
?=
Variable ?=
은 해당 변수가 설정되지 않은 경우에만 설정한다:
one = hello
one ?= will not be set
two ?= will be set
all:
echo $(one)
echo $(two)
with_spaces = hello # with_spaces has many spaces after "hello"
after = $(with_spaces)there
nullstring =
space = $(nullstring) # Make a variable with a single space.
all:
echo "$(after)"
echo start"$(space)"end
줄 끝의 공백문자는 벗겨지지 않으며, 줄의 시작 또한 마찬가지이다. 변수의 단일 공백을 원한다면 $(nullstring)
을 사용하라.
all:
# Undefined variables are just empty strings!
echo $(nowhere)
정의되지 않은 변수는 사실상 빈 문자열이다.
+=
Variablefoo := start
foo += more
all:
echo $(foo)
덧붙이기 목적으로 +=
를 사용하라.
override
를 사용하여 command line
으로부터 전달된 변수를 덮어씌울(override) 수 있다:
# Overrides command line arguments
override option_one = did_override
# Does not override command line arguments
option_two = not_override
all:
@echo $(option_one)
@echo $(option_two)
함수와 같이 동작하는 것처럼 보이는 define directive
는 함수가 아니다. 자주 사용되어지진 않으나 canned recipes
에서 그리고 eval function
에서 또한 짝을 이루는 방식으로 주되게 사용한다:
one = export blah="I was set!"; echo $$blah
define two
export blah="I was set!"
echo $$blah
endef
all:
@echo "This prints 'I was set'"
@$(one)
@echo "This does not print 'I was set' because each command runs in a separate shell"
@$(two)
define
/undef
는 단순히 command
들의 목록이 대입된 변수를 만든다. 그러나 이는 세미콜론과 조금 다르게 동작하는데, 이는 앞장에서 살펴본 바와 같이 각각의 command
는 개별된 shell
에서 동작하기 때문이다.
variable
은 각각의 target
에 대해 대입되어 질 수 있다:
one='hello, '
cool='world '
all: one = cool
@echo one is defined: $(one)
other:
@echo one is nothing: $(one)
특정한 target
의 패턴에 대해서 변수를 대입할 수 있다:
%.c: one = cool
blah.c:
@echo one is defined: $(one)
other:
@echo one is nothing: $(one)
[사이트] https://www.gnu.org/software/make/manual/html_node/
[사이트] https://makefiletutorial.com/