Dan Stahlke
Dan Stahlke

Reputation: 1469

Make: how to force immediate expansion of a variable?

Consider the following GNU makefile snippet:

# this code is not under my control
A = aaa
B = bbb

# this code is under my control
A += $B

B = ccc
# Prints "aaa ccc".  I would rather "aaa bbb".
$(info $A)

The issue is that since A is initially created as a deferred variable, the value of the RHS of the += is taken as a deferred value. Is there something like A += $(immediate B) that I can use?

The following somewhat gets there:

TMP := $B
A += $TMP

but is not an option since this will be in an include file, and gets used several times (in the context of a non-recursive make system). So TMP would get clobbered each time.

UPDATE

A little more justification. This is a non-recursive build, and variable d holds the name of the directory being processed. An include file is invoked for each subdirectory, setting up some variables. For example:

$d.LIBS += $($d.target_dir)/lib.a
LD_FLAGS += $($d.LIBS)

The problem here is that d is ephemeral, with its value changing as soon as the next directory is processed. LD_FLAGS and, for that matter, $d.LIBS may need to remain as deferred variables but d needs to be evaluated immediately here.

Upvotes: 2

Views: 2971

Answers (1)

MadScientist
MadScientist

Reputation: 100781

If you don't mind A becoming immediate, then you can just use this:

A := $A $B

If you want A to continue to be deferred, but to expand $B immediately, you can use eval because eval expands its argument:

$(eval A += $B)

This will expand $B first, so you get A += bbb, then evaluate that.

If you want some aspects of the value expanded and others not, just escape the not-to-be-expanded content:

$(eval LD_FLAGS += $$($d.LIBS))

I should say, though, that usually the things you're trying to do are handled more by constructed variable names based on the target name, so something like:

LD_FLAGS += $($@_LDFLAGS)

or whatever.

Upvotes: 3

Related Questions