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_programIf 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
overridemodifier 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. Theoverridemodifier 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
-eor--environment-overridescommand line option.
Variables are assigned with one of several assignment expressions, like this
X = 1MODULES := a b c dCC ?= gccCFLAGS += -Walldefine VAR var line 1 var line 2enddefexport 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 stringoverrideVARIABLE = text stringThis 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 = 1Y = $(X)X = 2Then
$(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 := exproverrideVARIABLE := exprThis is the same as
VARIABLE = exprexcept that the right hand side is evaluated once and for all at the time of the assignment. Thus ifX := 1Y := $(X)X := 2then
$(Y)later in the makefile will evaluate to "1" since that's what$(X)was when$(Y)was defined. - ;=
-
VARIABLE ;= exproverrideVARIABLE ;= exprThis is the same as
VARIABLE := exprexcept 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 += exproverrideVARIABLE += exprAppends 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 &= exproverrideVARIABLE &= exprPrepends 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-Wallare these two lines:CFLAGS = -O2# Possibly overridden on the command lineoverrideCFLAGS &= -Wall# Unconditionally prependedIn 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 ?= exproverrideVARIABLE ?= expr# Useless, but legalSets 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 VARIABLEVARIABLE = exprendif - !=
-
VARIABLE != shell commandoverrideVARIABLE != shell commandRuns 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#__
浙公网安备 33010602011771号