鉴于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 = $|
Run Code Online (Sandbox Code Playgroud)
考虑目标“ build / utility / debug.js”。上面规则的输出将是这样的:
output-only = utility/debug.js ./
Run Code Online (Sandbox Code Playgroud)
dir在先决条件列表中调用该函数的输出。my_dir在先决条件列表中调用my 函数的输出。如果我更改my_dir为:
my_dir = $(1)
Run Code Online (Sandbox Code Playgroud)
输出保持不变。如果我将其更改为:
my_dir = "foo"
Run Code Online (Sandbox Code Playgroud)
然后使抱怨没有规则使“ foo”(这是预期的)。看来,这$(1)并没有限制到的调用中my_dir。
这是怎么回事?为什么不能将词干传递给函数?我有一个使用二级扩展的解决方法,但是我想知道为什么我不能用这种方式编写规则。
编辑:我是stackoverflow的新手,如果这不是这里做事情的方式,请原谅我。
我想要$(1),因为my_dir正如Alex指出的那样,我将茎作为参数传递给。
我不知道为什么有人建议我要“ $”。我不认为$本身可以在任何情况下扩展到任何东西。
我知道自动变量仅在配方中可用。我没有在前提条件中使用自动变量-我正在使用词干:
每个目标都与目标模式匹配,以提取目标名称的一部分,称为词干。该词干被替换为每个prereq模式中的一个,以制成先决条件名称(每个prereq模式中的一个)。-手册
通过示例演示了词干可用的事实:词干在单独使用时会扩展到正确的值,但在传递给函数时不会扩展。
从GNU make 手册的本节中可以看出,先决条件列表中的变量和函数引用在读入阶段立即展开。这意味着,在完成任何模式匹配之前,因此%还没有特殊含义;它被解释为两个函数引用中的文字字符,$(dir %)和$(call my_dir,%),两者都有./结果,它们被合并到$|配方中的引用中。
除了您已经找到的解决方法(即二次扩展)之外,我不知道还有其他解决方法。