":=" is for defining simply expanded variable, which is expanded once and for all.
There is no difference between () and {} for Make. If you use $$ in a recipe, then $ is "escaped" and passed to the shell. The shell may then make a difference between $() or ${} . But that is entirely up to the shell, and has nothing to do with Make or makefiles.
The ifneq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared.
makefile and Makefile are special names because if make is called without the -f option it automatically searches for them, in this order, and use the first it finds. Note that GNU make also considers GNUmakefile , and prefers it over makefile and Makefile . Other make implementations can have other default names.
This is described in the GNU Make documentation, in the section titled 6.2 The Two Flavors of Variables .
In short, variables defined with :=
are expanded once, but variables defined with =
are expanded whenever they are used.
:=
A simple assignment expression is evaluated only once, at the very first occurrence.
For example, if CC :=${GCC} ${FLAGS}
during the first encounter is evaluated to gcc -W
then
each time ${CC}
occurs it will be replaced with gcc -W
.
=
A Recursive assignment expression is evaluated everytime the variable is encountered
in the code. For example, a statement like CC = ${GCC} {FLAGS}
will be evaluated only when
an action like ${CC} file.c
is executed. However, if the variable GCC
is reassigned i.e
GCC=c++
then the ${CC}
will be converted to c++ -W
after the reassignment.
?=
Conditional assignment assigns a value to a variable only if it does not have a value
+=
Assume that CC = gcc
then the appending operator is used like CC += -w
then CC
now has the value gcc -W
For more check out these tutorials
For me, the best way to see it in practice is during this Makefile snippet:
XX := $(shell date) // date will be executed once
tt:
@echo $(XX)
$(shell sleep 2)
@echo $(XX)
Running
make tt
Will produce:
sex 22 jan 2021 14:56:08 -03
sex 22 jan 2021 14:56:08 -03
( Same value )
XX = $(shell date) // date will be executed every time you use XX
tt:
@echo $(XX)
$(shell sleep 2)
@echo $(XX)
Running
make tt
Will produce:
sex 22 jan 2021 14:56:08 -03
sex 22 jan 2021 14:56:10 -03
Different values
From http://www.gnu.org/software/make/manual/make.html#Flavors:
=
defines a recursively-expanded variable. :=
defines a simply-expanded variable.
This is an old question but this example helps me understand the difference whenever I forget.
Running make
with the following Makefile will instantly exit:
a = $(shell sleep 3)
Running make
with the following Makefile will sleep for 3 seconds, and then exit:
a := $(shell sleep 3)
In the former Makefile, a
is not evaluated until it's used elsewhere in the Makefile, while in the latter a
is evaluated immediately even though it's not used.
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