【发布时间】:2016-01-28 09:52:58
【问题描述】:
考虑这个makefile:
%: %.c
@echo making $@
@touch $@
.SECONDEXPANSION:
%.pid: $$(basename $$@)
$(<D)/$(<F) --pidfile=$<.pid
在这里,第一个规则构建一个程序,第二个规则启动它,生成一个 pid 文件。 注意:我知道这个例子不需要二次扩展;真正的makefile更复杂,我真的需要在那里进行二次扩展。
所以,输入 make foo.pid,我希望 Make 按照第一条规则从 foo.c 构建 foo,然后按照第二条规则运行 ./foo --pidfile=foo.pid。
但是,它似乎不起作用:
$ make -f Makefile.test foo.pid
make: *** No rule to make target 'foo.pid'. Stop.
这在某种程度上与模式规则提供的二级扩展依赖关系有关。如果我写任何一个
-
%.pid: %在第二条规则中(即摆脱二次扩展),或 -
foo: %: %.c在第一条规则中(即写一个显式的静态模式规则),
这一切都突然起作用了。为什么?这是 GNU Make 的限制吗?就我而言,我想避免在第一条规则中预先列出所有可能的程序。
【问题讨论】:
-
我不确定到底发生了什么,但如果你在中间文件中添加一个虚拟前缀,它会起作用,所以你使用
foo.c=>foo=>foo.pid而不是foo.c=>foo.b=>foo.pid。 (我使用的是 GNU Make 3.81) -
对于 %.pid: $$(basename $$@),$@ 仅在规则内部有意义,而不是在先决条件中有意义。