【问题标题】:makefile enforce library dependency ordering [duplicate]makefile强制库依赖排序[重复]
【发布时间】:2014-09-26 18:07:31
【问题描述】:

在构建具有递归依赖关系的库时,我有这个片段:

$(LIBRARY) : $(OBJECTS) | $(LIBDIR) # objects is all the obj/*.o
    $(AR) ... 

obj/%.o : %.cpp obj/%.d
    $(CC) ...

build : $(DEPENDENCIES) $(LIBRARY)

$(DEPENDENCIES):
    $(MAKE) -C $(ROOT)/$@

如果我运行make,这将有效。一切都以正确的顺序按预期构建。但是如果我运行make -jN,库的构建顺序会很糟糕,因为我实际上没有设置任何依赖项排序规则,这会导致大量未定义的引用。

如果我添加规则:

$(OBJECTS) : $(DEPENDENCIES)

然后每次运行 make 都会重建每个库,无论更改如何(DEPENDENCIES 是假的,但我不明白为什么它实际上会重建所有内容)。为了并行构建的目的,我怎样才能强制执行正确的顺序,而不必每次都重新构建所有内容?

【问题讨论】:

  • @MichaelGrünewald 是的!谢谢你,你是我的英雄。

标签: c++ makefile


【解决方案1】:

我将为您提供如何设置 makefile 以保证的一般指南:

一个。重建那个并且只重建必要的那个,并且

b.正确使用并行性。

有些人已经要求一些“好的原则”,所以他们在这里。

用这些原则重写你的makefile,保证你能正常工作。

十诫:

  1. 您应该调用make 来创建target(或目标)或默认目标,这是您的Makefile 中的第一个目标。你的 Makefile 中的目标在:的左侧

  2. 有两种目标:真实的和“虚假的”。真正的目标是您想要(重新)创建的实际文件(或目录)。虚假目标是一个抽象概念,不是真实文件,但它通常意味着一组真实文件。

  3. Makefile 中列出的目标也可能有%,在这种情况下,它是一个模式目标,可以匹配多个目标,无论是真实的还是虚假的。

  4. 源是未列为目标的文件,在调用 make 之前已经存在。

  5. 目标“依赖”于写在:之后的“先决条件”,在目标之后

  6. 一个真正的目标必须有一个“配方”,它是目标行下的一个shell脚本。配方应该只写一个文件和一个文件,即目标文件。目标文件在配方中应称为$@

    如果配方写入多个文件,请将其分解为单个目标的多个配方。

    配方可能会读取许多文件:这些文件必须作为先决条件列出。

  7. 虚假目标不得有配方。

  8. 虚假目标可以依赖于其他虚假目标、真实目标或来源。真正的目标必须只依赖于真正的目标或来源。一切最终(递归地)仅取决于来源。

  9. 您不应在配方中递归调用 make,除非在一种情况下且仅在一种情况下:您有一些完全自行构建的子目录,无需读取任何外部资源或目标。
    在这种特殊情况下,您将拥有一个虚假的目标子目录和配方:

.PHONY: subdirectory subdirectory: $(MAKE) -C $@

  1. 如果你想使用其他makefile,但不满足上述异常,include他们。

注意:我并不是说你不能在违反这些原则的情况下编写正确的 Makefile。你可以而且有时是必要的。但要做到这一点,您必须知道自己在做什么并理解更高级的概念。你不应该这样开始学习,而是首先按照上述原则开始编写 Makefile。

【讨论】:

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