鉴于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 ./
dir
函数的输出。my_dir
函数的输出。如果我将my_dir
更改为:
my_dir = $(1)
输出保持不变。如果我改成它:
my_dir = "foo"
然后抱怨没有规则来制作“foo”(这是预期的)。然后,似乎$(1)
未在my_dir
的调用中受到约束。
发生了什么事?为什么我不能将词干传递给函数?我有一个使用二次扩展的解决方法,但我想知道为什么我不能这样写我的规则。
编辑:我是stackoverflow的新手,请原谅我,如果这不是在这里完成的事情。
我想要$(1)因为我将词干作为my_dir
的参数传递,正如亚历克斯指出的那样。
我不知道为什么建议我要“$”。我不相信美元本身可以扩展到任何环境中的任何东西。
我知道自动变量仅在配方中可用。我没有在先决条件中使用自动变量 - 我正在使用词干:
每个目标与目标模式匹配,以提取目标名称的一部分,称为词干。该词干被替换为每个先决条件模式以生成先决条件名称(每个先决条件模式中的一个)。 - the manual
实例证明了干可用的事实:当单独使用时,干扩展到正确的值,但在传递给函数时则不会。
答案 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,%)
中的文字字符,两者都有./
作为结果,它们被合并到$|
的引用中配方
我不知道除了你已经发现的任何其他解决方法,即二次扩展。