Can anybody give a clear explanation of how variable assignment really works in Makefiles.
What is the difference between :
VARIABLE = value VARIABLE ?= value VARIABLE := value VARIABLE += value
I have read the section in GNU Make's manual, but it still doesn't make sense to me.
In short, variables defined with := are expanded once, but variables defined with = are expanded whenever they are used.
":=" is for defining simply expanded variable, which is expanded once and for all.
$(patsubst PATTERN,REPLACEMENT,TEXT) Finds whitespace-separated words in TEXT that match PATTERN and replaces them with REPLACEMENT. Here PATTERN may contain a % which acts as a wildcard, matching any number of any characters within a word.
Using =
causes the variable to be assigned a value. If the variable already had a value, it is replaced. This value will be expanded when it is used. For example:
HELLO = world HELLO_WORLD = $(HELLO) world! # This echoes "world world!" echo $(HELLO_WORLD) HELLO = hello # This echoes "hello world!" echo $(HELLO_WORLD)
Using :=
is similar to using =
. However, instead of the value being expanded when it is used, it is expanded during the assignment. For example:
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)
Using ?=
assigns the variable a value iff the variable was not previously assigned. If the variable was previously assigned a blank value (VAR=
), it is still considered set I think. Otherwise, functions exactly like =
.
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.
VARIABLE = value
Normal setting of a variable, but any other variables mentioned with the value
field are recursively expanded with their value at the point at which the variable is used, not the one it had when it was declared
VARIABLE := value
Setting of a variable with simple expansion of the values inside - values within it are expanded at declaration time.
VARIABLE ?= value
Setting of a variable only if it doesn't have a value. value
is always evaluated when VARIABLE
is accessed. It is equivalent to
ifeq ($(origin VARIABLE), undefined) VARIABLE = value endif
See the documentation for more details.
VARIABLE += value
Appending the supplied value to the existing value (or setting to that value if the variable didn't exist)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With