Makefile递归地应用规则,即使它不应该';T

Makefile递归地应用规则,即使它不应该';T,makefile,gnu-make,Makefile,Gnu Make,我对GNU make有一个非常奇怪的问题。我有以下文件: a/x.html b/Makefile b/c/Makefile a/x.html的内容是不相关的。b/Makefile的内容如下: SRC=../a all: x.html %.html: ${SRC}/%.html rsync $< $@ 如果我在b/c/中运行make,结果与预期一致: rsync ../../a/x.html x.html 并且x.html从a/复制到b/c/ 但是,如果我在b/中运行

我对GNU make有一个非常奇怪的问题。我有以下文件:

a/x.html
b/Makefile
b/c/Makefile
a/x.html
的内容是不相关的。
b/Makefile
的内容如下:

SRC=../a
all: x.html

%.html: ${SRC}/%.html
        rsync $< $@
如果我在
b/c/
中运行
make
,结果与预期一致:

rsync ../../a/x.html x.html
并且
x.html
a/
复制到
b/c/

但是,如果我在
b/
中运行
make
,我得到的输出是几行:

make: stat: ../a/../a/.. (repeated many times) ../a/x.html: File name too long

似乎
make
正在递归地应用
%.html
的规则,但是为什么呢?是否有明显的遗漏?

若要构建与模式
%.html
匹配的目标(即任何以
.html
结尾的目标名称),make将应用规则,如果它可以构建依赖关系(从带有
./a/
前缀的原始目标构建的目标)

  • 您要求构建
    x.html
    。这与模式
    %.html
    匹配,因此规则适用:make查看它是否可以构建
    。/a/x.html
  • 。/a/x.html
    匹配模式
    %.html
    ,因此规则适用:make查看它是否可以构建
    。/a/。/x.html
  • 。/../a/x.html
    匹配模式
    %.html
    ,因此规则适用,以此类推
  • 干字符可以匹配路径的任何部分,包括目录分隔符

    通过运行
    make-r-d
    -d
    显示调试输出,
    -r
    关闭会产生大量噪音的内置规则),您可以看到make正在尝试什么

    当您在
    b/c
    中时,这将在步骤2停止,因为
    ./../a/x.html
    存在,但
    ./../a/x.html
    不存在

    解决此问题的一种方法是列出要对其执行操作的文件。您可以从
    。/a
    中已经存在的文件列表中构建该列表:

    $(notdir $(wildcard ${SRC}/*.html)): %.html: ${SRC}/%.html
            rsync $< $@
    

    谢谢!我想我会使用abspath解决方案。
    $(notdir $(wildcard ${SRC}/*.html)): %.html: ${SRC}/%.html
            rsync $< $@
    
    %.html: $(abspath ${SRC})/%.html
            rsync $< $@