在我们的makefile中,我们有一个配方将所有对象和库文件链接在一起以生成可执行文件(.elf文件)。作为副作用,此步骤还会生成映射文件和Intel .hex文件:
$(ELF_FILE) : <list of dependencies here>
<linker command line>
到目前为止,由于我们从未实际拥有$(MAP_FILE)
或$(HEX_FILE)
目标,当另一个目标依赖于其中一个$(ELF_FILE)
的副产品时,我们只是将其声明为依赖$(ELF_FILE)
,即使该目标的配方根本不想访问$(ELF_FILE)
本身。例如:
# Target that needs map-file, which is a side product of the $(ELF_FILE) target.
$(TARGET_THAT_NEEDS_MAP_FILE) : $(ELF_FILE)
<build-recipe>
# Target that needs hex-file, which is also a side product of the $(ELF_FILE) target.
$(TARGET_THAT_NEEDS_HEX_FILE) : $(ELF_FILE)
<build-recipe>
我们最近发现一个配方可以用于多个目标,如下所示:
$(MAP_FILE) $(HEX_FILE) $(ELF_FILE) : <list of dependencies here>
<linker command line>
通过这些新发现的知识,我们认为我们可以摆脱上述“黑客”并直接说明每个目标的直接依赖关系:
$(TARGET_THAT_NEEDS_MAP_FILE) : $(MAP_FILE)
<build-recipe>
$(TARGET_THAT_NEEDS_HEX_FILE) : $(HEX_FILE)
<build-recipe>
实施了这些变化后,我们现在观察到一种奇怪的效果,使我们怀疑我们误解了make
的多目标单配方功能,或者我们没有正确使用它。奇怪的结果是生成.elf,.map和.hex文件的配方现在看起来运行两次。这似乎没有造成任何直接问题,但它似乎表明这里有些东西可疑。所以我的问题是,我们的新方法是否可行,或者我们应该坚持上述的黑客攻击?
编辑:我们以多线程方式运行make
(即使用-j)。
答案 0 :(得分:1)
当make尝试更新目标时(无论是$(MAP_FILE)
,$(HEX_FILE)
还是$(ELF_FILE)
,它可能不知道其配方还会更新另一个目标,因此它也开始为那个配方,即使它是相同的。
当然,只有在使用-j选项时才会发生这种情况。 (你有没有可能尝试没有?)
举例说明:
$(TARGET): $(ELF_FILE) $(MAP_FILE)
<update target>
此处制作将尝试更新$(ELF_FILE)
和$(MAP_FILE)
,然后两次点击食谱。 (如果依赖项位于不同的目标上,这也应该适用,只要目标通过make的一次执行更新,并且它们之间没有瓶颈。
我对此并不完全确定,但可能能够知道这是同一个食谱。
==
此answer可能对您有用。 具体来说:
但是,如果输出文件和输入文件共享一个公共库, 你可以编写这样的模式规则:
%.foo %.bar %.baz : %.boz ; $(BUILDIT)
奇怪的是,对于具有多个目标的隐式规则,GNU make假定 单个调用配方将构建所有目标,它将完全按照您的意愿运行。
MadScientist
它指的是制作手册的那部分:
模式规则可能有多个目标。与普通规则不同,这个 不具有相同先决条件的许多不同规则 食谱。如果模式规则有多个目标,make就知道了 规则的配方负责制定所有目标。食谱 只执行一次以制作所有目标。搜索时 模式规则匹配目标,规则的目标模式其他 比匹配需要规则的目标的是偶然的: 只关心给文件的配方和先决条件 目前有问题。但是,当运行此文件的配方时, 其他目标被标记为已自行更新。