Reputation: 1469
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
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