【问题标题】:Question about GNU make built-in function subst with secondary expansion关于 GNU make 内置函数 subst 二次扩展的问题
【发布时间】:2020-03-01 15:54:44
【问题描述】:

我对带有二级扩展功能的 GNU make 有一些疑问。

这是我的项目结构(仅作为示例)

.
├── build
├── Makefile
└── src
    └── a.c

这是我的启用二级扩展的 Makefile

.SECONDEXPANSION:

%.o: $$(subst build,src,%.c)
        @echo $^

我输入make build/a.o,GNU make 抱怨:

make: *** No rule to make target `build/a.o'.  Stop.

看起来 make 没有找到先决条件,所以它停止了。

为了进一步调试,我在build目录中添加a.c并重新输入make build/a.o,GNU make输出这些

build/a.c

输出很奇怪,因为我预计输出将是 src/a.c 而不是 build/a.c

似乎内置文本功能subst不能二次展开。

有人知道我的 Makefile 出了什么问题吗?

谢谢

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    当您执行.SECONDEXPANSION 时,如果您想操作先决条件,则需要使用$$* 而不是%,即:

    $ cat Makefile
    .SECONDEXPANSION:
    
    %.o: $$(subst /build,/src,$$(@D))/$$*.c
            @echo Making $@ from $<
    

    输出:

    $ make -r OtherDirectory/build/foo.o SomeOtherDirectory/build/bar.o
    Making OtherDirectory/build/foo.o from OtherDirectory/src/foo.c
    Making SomeOtherDirectory/build/bar.o from SomeOtherDirectory/src/bar.c
    

    【讨论】:

    • 为什么$$*是有效的而不是%符号,我分不清这两个指令的区别。谢谢~
    • 我还有一个关于如何将先决条件解释为 OtherDirectory/src/foo.c 而不是 OtherDirectory/src/OtherDirectory/build/foo.c 的问题,因为 $$*OtherDirectory/build/foo 并且在字符串替换后在 OtherDirectory/src 之后连接。跨度>
    • 坦率地说我不知道​​。在规则评估级别,它尝试使用“foo”的词干而不是“OtherDirectory/build/foo”,这就是我添加 $$(@D) 来获取目录的原因。我认为这种结构是一种非常不标准的用途,可能是一种极端情况,但至少它有效。
    【解决方案2】:

    这是你想要达到的目标吗?

    build/%.o: src/%.c
        @echo $^
    

    观察:

    $ make build/a.o
    src/a.c
    

    与模式规则和目录中的文件相结合的第二次扩展是一个艰难的野兽。我还没有完全理解为什么你的构造不起作用。只是它不起作用。当我完全理解时会更新帖子。

    更多信息:

    【讨论】:

    • 谢谢!!!!你的解释很好。顺便说一句,如果目标名称是这种形式 OtherDirectory/build/a.o 并且预期的先决条件是这种形式 OtherDirectory/src/a.c,是否可以使用 patsubst 进行替换?谢谢!
    • 这里描述的阶段实际上并不正确。二次扩展发生在要构建目标时,在分配自动变量之后。在开始尝试运行recipe之前,make不会遍历所有规则并解决所有二次扩展。
    • 我又读了一遍手册。你说的对。我的解释并不完全正确。我将尝试改写我的解释,以便更正确。
    • @lesmana 你对这个问题有什么想法吗?我认为问题在于 subst 找不到目标来进行替换,因为我输入了make -Rd build/a.o,它告诉我找不到build/a.c。但我真的不知道你这行不通。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 2010-10-09
    相关资源
    最近更新 更多