【问题标题】:Makefile: How to write a pattern rule with prerequisite without suffixMakefile:如何编写具有先决条件而没有后缀的模式规则
【发布时间】:2021-06-14 10:57:23
【问题描述】:

在嵌入式项目中,您通常使用 objcopy 将 gcc 的 ELF 输出转换为原始二进制格式。我试图为此编写一个模式规则:%.bin: %(来自 gcc 的可执行输出没有后缀,至少在 Linux 上是这样)。这失败了make: *** No rule to make target ...

这是一个完整的测试用例:

test.c:

int main(int argc, char *argv[]) {
    return 0;
}

生成文件:

%.bin: %
    objcopy -O binary $< $@

这通过说make test test.bin 起作用,也就是说,通过明确要求它首先构建test 可执行文件。说make test.bin 是行不通的。在这种情况下,不知何故,make 没有意识到它可以使用内置规则创建先决条件。

我知道我可以通过将规则编写为 test.bin: test 来解决此问题,但我想知道,为什么此模式规则不起作用,我能否以某种方式使其起作用。

此外,我认为使其工作的显而易见且实用的方法打破了漂亮而优雅的内置规则系统。如果我可以将一个选项放入例如LDFLAGS 使链接器输出带有某些后缀的可执行文件,例如.elf(我还需要重写内置的链接规则吗?哦,好吧……)。

我承认,这纯属学究式的学术问题。

【问题讨论】:

    标签: makefile


    【解决方案1】:

    您的想法是正确的,但是您遇到了 make 的警告——make 不会将纯 % 目标与其他隐式规则链接起来——

    https://www.gnu.org/software/make/manual/html_node/Chained-Rules.html#Chained-Rules

    ... 出于性能原因 make 不会考虑非终端 搜索规则以构建 隐式规则的先决条件(请参阅 Match-Anything 规则)。

    【讨论】:

    • 好的,我已经阅读了该文本,但认为它不适用于此处,因为 '%' 在先决条件方面。但是现在我第二次考虑它,它开始变得有意义。然后,我想知道,链接的内置规则是如何编写的?它必须以特殊的方式在内部进行处理,不是吗?
    • "在搜索规则时构建隐式规则的先决条件" -- 在make test的情况下,test不是隐式规则的先决条件,所以它可以匹配链接目标。另一方面,如果您执行make test.bin,则test 隐式目标的先决条件,因此make不会搜索%
    • 您是说实际上内置的链接规则没有得到任何特殊处理?是的,这一切一直都在文档中。由于某种原因,我很难消化它。
    【解决方案2】:

    您可以通过传递带有名称和扩展名的输出-o 选项在gcc 中生成带有后缀的可执行输出。 示例:

    # Give your elf file name
    ELF_FILE= test.elf 
    
    $(ELF_FILE): $(OBJ_FILES)
        echo "Creating elf file"
        gcc.exe -o $(ELF_FILE) $(OBJ_FILES)
    
    %.bin: %.elf
        objcopy -O binary $< $@
    

    【讨论】:

    • 是的,谢谢,这显然是一个很好的实用解决方案,但是,以迂腐的方式思考,它有重写内置规则的缺点。我正在寻找一种方法来说服 make 它可以使用内置规则进行“测试”。我开始相信没有这样的方法。
    【解决方案3】:

    我的示例在像这样运行 make 时有效:make test test.bin 因为 IIUC,test 是首先构建的,然后构建 test.bin 的先决条件已经存在。利用这一点,我像这样修改了 Makefile:

    all: $(subst .bin, , $(filter %.bin, $(MAKECMDGOALS))) $(MAKECMDGOALS)
    
    %.bin: %
        objcopy -O binary $< $@
    

    现在我可以运行 make test.bin 并首先构建构建 test 然后 test.bin。或者我可以运行make foo bar.bin 并尝试构建 foo、bar 和 bar.bin。这是我能想到的最接近的事情。积极的一面是,Makefile 不必显式引用任何文件名,也不会重写任何内置规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      • 2011-04-13
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      相关资源
      最近更新 更多