所以我有一个makefile,我根据目录列表生成目标,例如:
DIRLIST := dir1 dir2 dir3
我正在生成特定于用例的目标,并在目录名称中添加了前缀,如下所示:
CLEANLIST := $(addprefix clean-,$(DIRLIST))
然后我想在目标/配方/规则中删除前缀,但我似乎无法将$ @读入变量:
$(CLEANLIST):
@(eval TARGET=$@) #<-- this part results in TARGET being empty
@(eval REALTARGET=$(TARGET:clean-%=%))
#...do stuff...
有没有办法在目标/配方/规则中填充一个变量,该变量的目录名称被剥去了前缀?
更新:感谢Etan指出我搞砸了语法。它应该是$(eval ...)
而不是@(eval ...)
。这是解决我问题的最直接的解决方案。
我的食谱的相关部分现在看起来像这样:
$(CLEANLIST):
$(eval REALTARGET=$(@:clean-%=%))
#...derive some exported variable values from REALTARGET for use by secondary.mk...
$(MAKE) -f secondary.mk clean
答案 0 :(得分:1)
有没有办法在目标/配方/规则中填充变量...
不确定。 Gnu make有能力定义target-specific variable values。您可以使用包含目标和赋值的单独行来执行此操作,例如:
$(CLEANLIST): TARGET = $@
当然,这很愚蠢,因为你可以在食谱中使用$@
。但您可能希望将TARGET
导出到子制作。你也可以这样做:
$(CLEANLIST): export TARGET = $@
...具有剥离前缀的目录名?
在特定于目标的变量赋值中,您可以通常的方式去除前缀:
$(CLEANLIST): REALTARGET = $(@:clean-%=%))
你不能(轻松)做的是在配方中设置 shell 变量,因为配方的每一行都在一个单独的shell中执行。要将shell分配从一个配方命令传递到下一个配方命令,您必须:
将分配和以下命令放在同一逻辑行中。将整个配方放在同一物理行中,或使用backslash-newline continuation组成逻辑行。在后一种情况下,请记住反斜杠换行符不会终止shell命令;在shell分配后你需要一个分号。
或使用.ONESHELL
声明。
请参阅Recipe Execution上的制作手册部分。
答案 1 :(得分:0)
感谢Etan指出我搞砸了语法。它应该是$(eval ...)
而不是@(eval ...)
。这是解决我问题的最直接的解决方案。
我的食谱的相关部分现在看起来像这样:
$(CLEANLIST):
$(eval REALTARGET=$(@:clean-%=%))
#...derive some exported variable values from REALTARGET for use by secondary.mk...
$(MAKE) -f secondary.mk clean