在GNU Makefile
中,有两种类型的变量:
# simple variable (immediate evaluation):
VAR := some_assignment
# recursively expanded variable (deferred evaluation):
VAR = some_assignment
可以使用以下命令附加到递归扩展变量:
IMMEDIATE += DEFERRED or IMMEDIATE
对于追加运算符,' + =',考虑右侧 如果变量先前已设置为简单变量,则立即生效 (':='或' :: ='),否则延期。
有没有办法 prepend 到递归扩展变量?
我的动机示例是在$(LDLIBS)
:
# Unfortunately, newlib gets added to the end rather than the beginning.
LDLIBS += $(if $(later_condition),newlib.a)
# Unfortunately, the expression is evaluated now rather than being deferred.
LDLIBS := $(if $(later_condition),newlib.a) $(LDLIBS)
答案 0 :(得分:4)
我遇到了同样的问题。我的解决方案非常hacky,并使用$(value)和$(eval)函数。
对我来说重要的是,它保留了变量的风味(递归),因此在此操作期间既不会扩展前置变量,也不会扩展原始变量:
# Macro for prepending to a recursively expanded variable.
#
# Usage:
# * Prepending "text" to the VAR variable:
# $(call prepend,VAR,text)
#
# * Prepending "a word list" to the VAR variable -- remember
# to add any trailing separator character (e.g. space):
# $(call prepend,VAR,a word list )
#
# * Prepending OTHER_VAR variable to the VAR variable -- use $$
# to defer any variable expansions:
# $(call prepend,VAR,$$(OTHER_VAR))
define prepend
$(eval $(1) = $(2)$(value $(1)))
endef
# Macro for appending to a recursively expanded variable.
#
# Usage:
# * Appending "text" to the VAR variable:
# $(call append,VAR,text)
#
# * Appending "a word list" to the VAR variable -- remember
# to add any heading separator character (e.g. space):
# $(call append,VAR, a word list)
#
# * Appending OTHER_VAR variable to the VAR variable -- use $$
# to defer any variable expansions:
# $(call append,VAR,$$(OTHER_VAR))
define append
$(eval $(1) = $(value $(1))$(2))
endef
快速测试用例:
A = A
B = B
VAR = $(A)
$(info before: VAR=$(VAR) | value(VAR)=$(value VAR) | $(flavor VAR))
$(call prepend,VAR,$$(B))
$(info after : VAR=$(VAR) | value(VAR)=$(value VAR) | $(flavor VAR))
执行:
before: VAR=A | value(VAR)=$(A) | recursive
after : VAR=BA | value(VAR)=$(B)$(A) | recursive
make: *** No targets. Stop.
附加说明:
答案 1 :(得分:1)
使用此:
# Expand a variable, properly escaping '$' characters.
expand = $(if $(findstring simple,$(flavor $1)),$(subst $$,$$$$,$($1)),$(value $1))
# Prepend to a variable, preserving flavor.
prepend = \
$(if $(findstring simple,$(flavor $1)), \
$(eval $1 := $2 $(call expand,$1)), \
$(eval $1 = $2 $(call expand,$1)))
x := 1 $$ 2
$(call prepend,x,X)
$(info $x)
x = 1 $$ 2
$(call prepend,x,X)
$(info $x)
$(value)
不够好,因为在$(eval)
上下文中,$
个字符将被解析为变量引用。