在单个makefile中从相同的源代码构建多个配置



我有一小组c语言的源代码文件,我正试图为它们拼凑一个Makefile,从同一组源代码构建几个不同的输出。每个输出都使用特定于目标的变量进行定制。

(现实世界的例子是运行在几个不同的电路板版本上的固件,但由相同的源代码构建并使用条件编译自定义。)

下面是一个示例Makefile,说明了我遇到的问题:

CINPUTFILES = Testfile.c
all: v12target v13target
# the same source code is built several different ways depending on a
# list of preset configurations
v12target: lots_of_common_variables = hello
v12target: more_variables = v12_specific
v12target: Rev12Output.mycommontargets
v13target: lots_of_common_variables = hello
v13target: more_variables = v13_specific
v13target: Rev13Output.mycommontargets
# (more vXXtarget targets omitted)
# TODO:  why is @echo required?
%.mycommontargets: %.hex %.elf
    @echo
# TODO: why are these output files deleted?
%.elf: $(CINPUTFILES)
    cp $< $@
%.hex: %.elf
    cp $< $@
# TODO: correct way of adding the dummy mycommontargets to PHONY?
.PHONY : all clean

这个想法是all目标构建几个不同的目标——每个硬件版本一个。因为除了配置变量列表之外,每个构建过程都是相同的,所以它调用了许多设置变量的vXXtarget目标,然后调用了一个公共目标:%.mycommontargets。这个目标然后开始生成实际的输出文件。

注意TODO标记…

  1. %.mycommontargets:由于某种原因,如果我删除@echo,我得到一个错误消息:

    make: *** No rule to make target `Rev12Output.mycommontargets', needed by `v12target'.  Stop.
    

    为什么会发生这种情况,我需要做些什么来摆脱它?

  2. 如果我把@echo留在原地,构建确实成功完成。但随后make决定继续并删除输出!

    $ make
    cp Testfile.c Rev12Output.elf
    cp Rev12Output.elf Rev12Output.hex
    cp Testfile.c Rev13Output.elf
    cp Rev13Output.elf Rev13Output.hex
    rm Rev12Output.hex Rev12Output.elf Rev13Output.hex Rev13Output.elf
    

    为什么要这样做?什么决定它什么时候做,什么时候不做?我以前从未意识到make甚至有这样的删除文件的功能;它与增量构建的整个理念背道而驰,我认为make应该帮助解决这个问题。我宁愿保留所有中间和输出文件…

  3. mycommontargets模式添加到.PHONY的正确方法是什么?

我想我可以把@echo留在原地,然后把每个目标添加到.PRECIOUS。但即使我没有太多的make经验,我有一种强烈的感觉,如果我必须使用像@echo这样的黑客,并使用像.PRECIOUS这样更模糊的特殊目标,我做错了。就是感觉不对。

(很抱歉在空格里问了3个问题,但我觉得它们之间有很强的联系…)

  1. 问题是每个非虚假目标都需要一个规则来创建。但是,您不能使模式规则的目标是虚假的。在你的情况下,我建议留下@echo(更好:用@true代替它,以避免输出虚假行)。
  2. 输出文件是中间文件,即在Makefile中没有明确提到,但模式规则要求。默认情况下,make将删除所有中间文件。在这里禁用自动删除最简单的方法是在没有先决条件的情况下提到.SECONDARY目标,即在某处添加一行,只是说:

    。二级:

  3. 如果你真的需要。phony在这里,你必须生活在没有模式规则。这在你的布局中是很不可取的,所以最好顺其自然。

总的来说,我建议在这里使用更正统的布局。通常,您会将交叉编译问题从Makefile中删除,并将主机板(autotools术语:主机板是软件将运行的板)作为configure的参数。让configure从一个中央源代码树为每个主机板生成一个构建树,并在这些构建树中进行构建。

最新更新