Makefile 为什么GNU制造';s的二级扩展不适用于依赖项的模式规则?

Makefile 为什么GNU制造';s的二级扩展不适用于依赖项的模式规则?,makefile,gnu-make,Makefile,Gnu Make,考虑这个makefile: %: %.c @echo making $@ @touch $@ .SECONDEXPANSION: %.pid: $$(basename $$@) $(<D)/$(<F) --pidfile=$<.pid 这在某种程度上与模式规则提供的二级扩展依赖项有关。如果我写 %.pid:%%在第二条规则中(即摆脱二次扩展),或 foo:%:%.c在第一个规则中(即编写一个显式的静态模式规则) 这一切都突然发生了。为什么?这是G

考虑这个makefile:

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

.SECONDEXPANSION:
%.pid: $$(basename $$@)
    $(<D)/$(<F) --pidfile=$<.pid
这在某种程度上与模式规则提供的二级扩展依赖项有关。如果我写

  • %.pid:%%
    在第二条规则中(即摆脱二次扩展),或
  • foo:%:%.c
    在第一个规则中(即编写一个显式的静态模式规则)

这一切都突然发生了。为什么?这是GNU制造的限制吗?就我而言,我希望避免在第一条规则中预先列出所有可能的程序。

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

如果你有

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

它会起作用。

…但它不会。这很有意义,因为我希望match anything规则匹配
foo
,这不是一种“特定类型的数据”-换句话说,没有任何不匹配的隐式规则适用于此目标。我不确定到底发生了什么,但如果您向中间文件添加一个伪前缀,因此,使用
foo.c=>foo=>foo.pid
而不是
foo.c=>foo.b=>foo.pid
。(我使用GNU Make 3.81)For%.pid:$$(basename$$@),$@仅在规则内部有意义,而不是在前提条件中。
%:: %.c
    @echo making $@
    @touch $@