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. The override 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 if

X := 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 with global, 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#__

posted on 2022-08-06 21:27  guolongnv  阅读(86)  评论(0)    收藏  举报