gpt4 book ai didi

Makefile 忽略模式中子目录的模式规则

转载 作者:行者123 更新时间:2023-12-04 01:37:21 24 4
gpt4 key购买 nike

考虑以下目录结构:

.
bar/
foo/
test.ext1
_foo/

我用以下规则编写了一个makefile:
_%.ext2: bar/%.ext1 # % should match foo/test
echo $*

但是正在运行 make _foo/test.ext2给出:
make: *** No rule to make target '_foo/test.ext2'.  Stop.

当我看着 make -d _foo/test.ext2 ,它甚至不考虑上述规则,即它直接跳转到尝试内置规则。我不明白这里发生了什么,所以有人可以向我解释一下吗?

编辑:
我希望能够从 bar 中的任意文件生成,例如:
  • bar/foo/test-2.ext1 -> _foo/test-2.ext2
  • bar/baz/another.ext1 -> _baz/another.ext2
  • _foo的存在和 _baz是有保证的。

    最佳答案

    这在 manual 中有解释:

    When the target pattern does not contain a slash (and it usually does not), directory names in the file names are removed from the file name before it is compared with the target prefix and suffix.





    When prerequisites are turned into file names, the directories from the stem are added at the front, while the rest of the stem is substituted for the %



    因此,使用类似 _%.ext2 的模式下划线与文件名匹配,而不是目录名。所以它不匹配 _foo/test.ext2但它会匹配 foo/_test.ext2 (并寻找 foo/bar/test.ext1 )。你自己看:
    $ cat Makefile
    _%.ext2: bar/%.ext1
    echo Making $@ from $<

    $ make -dr _foo/test.ext2
    ...
    Considering target file '_foo/test.ext2'.
    File '_foo/test.ext2' does not exist.
    Looking for an implicit rule for '_foo/test.ext2'.
    No implicit rule found for '_foo/test.ext2'.
    Finished prerequisites of target file '_foo/test.ext2'.
    Must remake target '_foo/test.ext2'.
    make: *** No rule to make target '_foo/test.ext2'. Stop.

    $ make -dr foo/_test.ext2
    ...
    Considering target file 'foo/_test.ext2'.
    File 'foo/_test.ext2' does not exist.
    Looking for an implicit rule for 'foo/_test.ext2'.
    Trying pattern rule with stem 'test'.
    Trying implicit prerequisite 'foo/bar/test.ext1'.
    Trying pattern rule with stem 'test'.
    Trying implicit prerequisite 'foo/bar/test.ext1'.
    Looking for a rule with intermediate file 'foo/bar/test.ext1'.
    Avoiding implicit rule recursion.
    No implicit rule found for 'foo/_test.ext2'.
    Finished prerequisites of target file 'foo/_test.ext2'.
    Must remake target 'foo/_test.ext2'.
    make: *** No rule to make target 'foo/_test.ext2'. Stop.

    修复它的最简单方法是使目标包含斜杠。如果您可以将输出移动到其他地方,则可以执行以下操作:
    $ cat Makefile
    OBJDIR := obj
    $(OBJDIR)/_%.ext2: bar/%.ext1
    echo Making $@ from $<

    $ make obj/_foo/test.ext2
    echo Making obj/_foo/test.ext2 from bar/foo/test.ext1
    Making obj/_foo/test.ext2 from bar/foo/test.ext1

    甚至
    $ cat Makefile
    _/%.ext2: bar/%.ext1
    echo Making $@ from $<

    $ make _/foo/test.ext2
    echo Making _/foo/test.ext2 from bar/foo/test.ext1
    Making _/foo/test.ext2 from bar/foo/test.ext1

    如果您不能这样做,您可以尝试通过完整路径进行引用,即:
    $ cat Makefile
    $(CURDIR)/_%.ext2: bar/%.ext1
    echo Making $@ from $<

    $ make $(pwd)/_foo/test.ext2
    echo Making /path/to/curdir/_foo/test.ext2 from bar/foo/test.ext1
    Making /path/to/curdir/_foo/test.ext2 from bar/foo/test.ext1

    请注意,使用 ./不起作用,因为 GNU make strips 领先 ./来自使模式再次不匹配的目标:
    $ cat Makefile
    ./_%.ext2: bar/%.ext1
    echo Making $@ from $<

    $ make -dr ./_foo/test.ext2
    ...
    Considering target file '_foo/test.ext2'.
    File '_foo/test.ext2' does not exist.
    Looking for an implicit rule for '_foo/test.ext2'.
    No implicit rule found for '_foo/test.ext2'.
    Finished prerequisites of target file '_foo/test.ext2'.
    Must remake target '_foo/test.ext2'.
    make: *** No rule to make target '_foo/test.ext2'. Stop.

    如果你想让你的同行评审同事紧张,你也可以使用一些二次扩展魔法来生成正确的先决条件名称,例如:
    $ cat Makefile
    percent := %
    .SECONDEXPANSION:
    %.ext2: bar/$$(patsubst _$$(percent),$$(percent),$$(@D))/$$*.ext1
    echo Making $@ from $<

    $ make _foo/test.ext2
    echo Making _foo/test.ext2 from bar/foo/test.ext1
    Making _foo/test.ext2 from bar/foo/test.ext1

    注: %必须通过 $(percent) 引用变量,否则 GNU make 解析器可能会提示或误解 patsubst功能。

    您的 final方法有效,因为您的最终解决方案是静态模式规则。它不应用相同的“ strip 目录”方法,而只是匹配字符串。

    关于Makefile 忽略模式中子目录的模式规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59048388/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com