Variable Assignment = := ;= += &= ?= in makeppfile
A variable can assume a value in several different ways:
-
A variable may be set inside a makefile. There are a number of different ways to do this; see below.
-
A variable's value may be specified on the command line, like this:
makepp CFLAGS=-O2 my_program
If more than one makefile is loaded, the CFLAGS variable is propagated to all of the makefiles. Variables set on the command line automatically override any setting of the variable in any of the makefiles.
If ever needed, the makefile must in turn explicitly override command line settings. The intention is not to ignore what the user requests, but rather a way to modify it. The
override
modifier may precede any assignment statement. But in the case of keyword statements, the order is important, which is why the override variant is always shown below. Theoverride
modifier applies only to any assignments where it is present, and does not influence later assignments to the variable. -
If a variable is set in the environment, it can be referenced as a makepp variable. Ordinarily assignments to variables inside a makefile override settings from the environment, but you can change this by using the
-e
or--environment-overrides
command line option.
Variables are assigned with one of several assignment expressions, like this
X = 1 MODULES := a b c d CC ?= gcc CFLAGS += -Wall define VAR var line 1 var line 2 enddef export PATH := $(PWD):$(PATH) global MYPROJECT.INFO = info to be seen in all makefiles |
Leading and trailing whitespace around values is always stripped off.
The different assignment operators have somewhat different meanings.
Simple assignment operators
- =
-
VARIABLE = text string
override
VARIABLE = text string
This is the usual assignment statement that all implementations of make support. The expression on the right hand side is not evaluated until the value of
$(VARIABLE)
is actually used somewhere. Thus, if you do the following:X = 1
Y = $(X)
X = 2
Then
$(Y)
later in the makefile will evaluate to "2".In general, you usually want to use
:=
(see below) instead of=
because it provides more predictable variable evaluation. However, there are times when you need to defer the variable evaluation. Also, if you're writing a makefile that must be backwards-compatible with some version of make other than GNU make, then you have no choice: you may only use=
. - :=
-
VARIABLE := expr
override
VARIABLE := expr
This is the same as
VARIABLE = expr
except that the right hand side is evaluated once and for all at the time of the assignment. Thus ifX := 1
Y := $(X)
X := 2
then
$(Y)
later in the makefile will evaluate to "1" since that's what$(X)
was when$(Y)
was defined. - ;=
-
VARIABLE ;= expr
override
VARIABLE ;= expr
This is the same as
VARIABLE := expr
except that the right hand side is evaluated only at the time of the first use and then remembered. This is useful for expensive commands, which always return the same value, but which you don't want to perform when building unrelated targets:VAR1 ;= $(perl expensive calculations)
VAR2 ;= $(shell external command)
Note that old makefiles will usually use
:=
here, to at least do this only once. But with this operator you can even additionally not do it, if you currently don't need the value. For values which are identical in several directories, you can optimize this further withglobal
, discussed below.However this is not intended as a clever way to force order of evaluation. If a variable defined like this includes the value of another variable, and that other one has a target specific value, and the first expansion is for that target, then the target specific value will stick for all other contexts as well. This is a bug and will hopefully be fixed in the future.
- +=
-
VARIABLE += expr
override
VARIABLE += expr
Appends the string to the previous contents of the variable, separated by a space. If the variable was previously assigned with
:=
, then the right hand side is evaluated before appending. - &=
-
VARIABLE &= expr
override
VARIABLE &= expr
Prepends the string to the previous contents of the variable, separated by a space. If the variable was previously assigned with
:=
, then the right hand side is evaluated before appending.For example one way of guaranteeing that
CFLAGS
, whatever else the user may put in, always starts with-Wall
are these two lines:CFLAGS = -O2
# Possibly overridden on the command line
override
CFLAGS &= -Wall
# Unconditionally prepended
In old makefiles you typically had to do something like this, which had the side effect of forcing the type to
:=
to prevent endless recursion:VARIABLE := expr $(VARIABLE)
- ?=
-
VARIABLE ?= expr
override
VARIABLE ?= expr
# Useless, but legal
Sets the value of the variable, but only if the variable is not specified earlier in the makefile, on the command line, or in the environment. The above assignment is exactly equivalent to
ifndef VARIABLE
VARIABLE = expr
endif
- !=
-
VARIABLE != shell command
override
VARIABLE != shell command
Runs the shell command and sets the variable to contain the command's standard output. This is exactly equivalent to
VARIABLE := $(shell command)
https://metacpan.org/release/PFEIFFER/makepp-2.0.99.2/view/pod/makepp_variables.pod#__