Makefile:如何存储和操作当前目标/配方/规则的值?

时间:2015-10-13 23:54:14

标签: makefile

所以我有一个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

2 个答案:

答案 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