如何在仅限订单的先决条件中调用函数?

时间:2012-03-02 00:19:42

标签: makefile

鉴于Makefile的这一点:

# for pattern matching
$(OBJDIR) := build

# just to see if a level of indirection will work
my_dir = $(dir $(1))

$(OBJECTS) : $(OBJDIR)/% : $(HEADERS) $(SRCDIR)/% | % $(dir %) $(call my_dir,%)
  @echo output-only = $|

这是static pattern rule order-only prerequisites

考虑目标“build / utility / debug.js”。上述规则的输出将是:

output-only = utility/debug.js ./
  • 第一个组件“utility / debug.js”从词干(%)中正确复制。
  • 第二个组件“./”是在先决条件列表中调用dir函数的输出。
  • 第三个组件是一个空字符串,是在先决条件列表中调用我的my_dir函数的输出。

如果我将my_dir更改为:

my_dir = $(1)

输出保持不变。如果我改成它:

my_dir = "foo"

然后抱怨没有规则来制作“foo”(这是预期的)。然后,似乎$(1)未在my_dir的调用中受到约束。

发生了什么事?为什么我不能将词干传递给函数?我有一个使用二次扩展的解决方法,但我想知道为什么我不能这样写我的规则。

编辑:我是stackoverflow的新手,请原谅我,如果这不是在这里完成的事情。

我想要$(1)因为我将词干作为my_dir的参数传递,正如亚历克斯指出的那样。

我不知道为什么建议我要“$”。我不相信美元本身可以扩展到任何环境中的任何东西。

我知道自动变量仅在配方中可用。我没有在先决条件中使用自动变量 - 我正在使用词干:

  

每个目标与目标模式匹配,以提取目标名称的一部分,称为词干。该词干被替换为每个先决条件模式以生成先决条件名称(每个先决条件模式中的一个)。 - the manual

实例证明了干可用的事实:当单独使用时,干扩展到正确的值,但在传递给函数时则不会。

2 个答案:

答案 0 :(得分:2)

注意$1不是一个特殊变量,它扩展为与模式规则(或静态模式规则)相关的任何有趣内容。 $1变量仅在$(call ...)函数调用的用户定义宏的上下文中具有唯一行为。

您想使用$*,而不是$1; $*是一个自动变量,它扩展到规则目标的主干。

但是,在所有版本的make(包括make的POSIX标准定义)中,自动变量(包括$*$<$@$^等。 )仅在配方的上下文中可用。它们在目标或先决条件列表的上下文中不可用。有关详细信息,请参阅GNU make manual section on Automatic Variables

正如您所建议的那样,.SECONDEXPANSION伪目标启用了一个GNU特定于make的功能,它提供了一种避免此限制的方法。

答案 1 :(得分:2)

this section of the GNU make manual可以看出,在读入阶段,先决条件列表中的变量和函数引用会立即展开。这意味着,在完成任何模式匹配之前,%还没有特殊意义;它被解释为两个函数引用$(dir %)$(call my_dir,%)中的文字字符,两者都有./作为结果,它们被合并到$|的引用中配方

我不知道除了你已经发现的任何其他解决方法,即二次扩展。