【问题标题】:Why GNU Make's secondary expansion does not work with pattern rules for dependencies?为什么 GNU Make 的二次扩展不适用于依赖的模式规则?
【发布时间】: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=&gt;foo=&gt;foo.pid而不是foo.c=&gt;foo.b=&gt;foo.pid。 (我使用的是 GNU Make 3.81)
  • 对于 %.pid: $$(basename $$@),$@ 仅在规则内部有意义,而不是在先决条件中有意义。

标签: makefile gnu-make


【解决方案1】:

我认为您的情况在第 10.5.5 节“匹配任意模式规则”中有所描述。你这里有一个非终端匹配任何规则,它不允许匹配指示特定数据类型的文件名。

如果你有让我们说

%:: %.c
    @echo making $@
    @touch $@

它会起作用的。

【讨论】:

  • ...除了它没有。这是有道理的,因为我希望 match-anything 规则匹配 foo,这不是“特定类型的数据”——换句话说,没有适用于此目标的 non-match-anything 隐式规则。
猜你喜欢
  • 2017-09-26
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多