Development Tip

GNU Makefile 변수 할당 =,? =, : = 및 + =의 차이점은 무엇입니까?

yourdevel 2020. 9. 29. 18:45
반응형

GNU Makefile 변수 할당 =,? =, : = 및 + =의 차이점은 무엇입니까?


누구나 Makefile에서 실제로 어떻게 변수 할당이 작동하는지에 대한 명확한 설명을 할 수 있습니까?

차이점은 무엇입니까?

 VARIABLE = value
 VARIABLE ?= value
 VARIABLE := value
 VARIABLE += value

GNU Make 매뉴얼 섹션읽었 지만 여전히 이해가되지 않습니다.


게으른 세트

VARIABLE = value

변수의 일반 설정-변수가 선언 될 때가 아니라 변수가 사용될 때 그 안의 값이 재귀 적으로 확장됩니다.

즉시 설정

VARIABLE := value

내부 값의 간단한 확장으로 변수 설정-그 안의 값은 선언시 확장됩니다.

부재시 설정

VARIABLE ?= value

값이없는 경우에만 변수 설정

추가

VARIABLE += value

제공된 값을 기존 값에 추가 (또는 변수가없는 경우 해당 값으로 설정)


를 사용 =하면 변수에 값이 할당됩니다. 변수에 이미 값이있는 경우 대체됩니다. 이 값은 사용될 때 확장됩니다. 예를 들면 :

HELLO = world
HELLO_WORLD = $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# This echoes "hello world!"
echo $(HELLO_WORLD)

를 사용하는 것은를 사용 :=하는 것과 비슷합니다 =. 그러나 값이 사용될 때 확장되는 대신 할당 중에 확장됩니다. 예를 들면 :

HELLO = world
HELLO_WORLD := $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# Still echoes "world world!"
echo $(HELLO_WORLD)

HELLO_WORLD := $(HELLO) world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

를 사용 하면 변수가 이전에 할당되지 않은 경우?= 변수에 값 이 할당됩니다. 변수가 이전에 빈 값을 (할당 된 경우 ), 그것은 여전히 세트로 간주됩니다 내 생각을 . 그렇지 않으면 .VAR==

Using += is like using =, but instead of replacing the value, the value is appended to the current one, with a space in between. If the variable was previously set with :=, it is expanded I think. The resulting value is expanded when it is used I think. For example:

HELLO_WORLD = hello
HELLO_WORLD += world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

If something like HELLO_WORLD = $(HELLO_WORLD) world! were used, recursion would result, which would most likely end the execution of your Makefile. If A := $(A) $(B) were used, the result would not be the exact same as using += because B is expanded with := whereas += would not cause B to be expanded.


I suggest you do some experiments using "make". Here is a simple demo, showing the difference between = and :=.

/* Filename: Makefile*/
x := foo
y := $(x) bar
x := later

a = foo
b = $(a) bar
a = later

test:
    @echo x - $(x)
    @echo y - $(y)
    @echo a - $(a)
    @echo b - $(b)

make test prints:

x - later
y - foo bar
a - later
b - later bar

Check more elaborate explanation here


When you use VARIABLE = value, if value is actually a reference to another variable, then the value is only determined when VARIABLE is used. This is best illustrated with an example:

VAL = foo
VARIABLE = $(VAL)
VAL = bar

# VARIABLE and VAL will both evaluate to "bar"

When you use VARIABLE := value, you get the value of value as it is now. For example:

VAL = foo
VARIABLE := $(VAL)
VAL = bar

# VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"

Using VARIABLE ?= val means that you only set the value of VARIABLE if VARIABLE is not set already. If it's not set already, the setting of the value is deferred until VARIABLE is used (as in example 1).

VARIABLE += value just appends value to VARIABLE. The actual value of value is determined as it was when it was initially set, using either = or :=.


In the above answers, it is important to understand what is meant by "values are expanded at declaration/use time". Giving a value like *.c does not entail any expansion. It is only when this string is used by a command that it will maybe trigger some globbing. Similarly, a value like $(wildcard *.c) or $(shell ls *.c) does not entail any expansion and is completely evaluated at definition time even if we used := in the variable definition.

Try the following Makefile in directory where you have some C files:

VAR1 = *.c
VAR2 := *.c
VAR3 = $(wildcard *.c)
VAR4 := $(wildcard *.c)
VAR5 = $(shell ls *.c)
VAR6 := $(shell ls *.c)

all :
    touch foo.c
    @echo "now VAR1 = \"$(VAR1)\"" ; ls $(VAR1)
    @echo "now VAR2 = \"$(VAR2)\"" ; ls $(VAR2)
    @echo "now VAR3 = \"$(VAR3)\"" ; ls $(VAR3)
    @echo "now VAR4 = \"$(VAR4)\"" ; ls $(VAR4)
    @echo "now VAR5 = \"$(VAR5)\"" ; ls $(VAR5)
    @echo "now VAR6 = \"$(VAR6)\"" ; ls $(VAR6)
    rm -v foo.c

Running make will trigger a rule that creates an extra (empty) C file, called foo.c but none of the 6 variables has foo.c in its value.

참고URL : https://stackoverflow.com/questions/448910/what-is-the-difference-between-the-gnu-makefile-variable-assignments-a

반응형