2014-09-26 32 views
0

在建设有递归依赖一个图书馆,我有这样的片段:makefile文件执行库的依赖订货

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

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

build : $(DEPENDENCIES) $(LIBRARY) 

$(DEPENDENCIES): 
    $(MAKE) -C $(ROOT)/[email protected] 

,如果我跑make这工作。一切按正确顺序按预期构建。但是如果我运行make -jN,库的构建顺序很糟糕,因为我实际上没有任何依赖关系排序规则集,导致大量未定义的引用。

如果我添加规则:

$(OBJECTS) : $(DEPENDENCIES) 

然后运行make每次重建每个库,无论变化的(DEPENDENCIES是假的,但我不明白为什么它实际上重建的一切)。我如何为平行构建的目的执行正确的排序而不必每次都重建所有内容?

+0

@MichaelGrünewaldYES !!!谢谢你,你是我的英雄。 – Barry 2014-09-26 19:02:43

回答

4

我打算给你一些指导如何设置makefiles来保证:

a。重建和只有那是必要的,并且

b。正确使用并行性。

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

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

十戒:

  1. 汝等调用make作出target(或目标)或默认的目标,这是在你生成文件的第一个目标。您的Makefile中的目标位于左侧:

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

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

  4. 源文件没有被列为目标,并且在调用make之前已经存在。

  5. 一个目标“取决于”其上的:后写了“先决条件”,目标

  6. 一个真正的目标必须有一个“秘方”,这是目标线下的shell脚本之后。配方应该只写一个文件和一个文件,目标文件。配方中的目标文件应该被称为[email protected]

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

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

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

  8. 假目标可以依赖于其他假目标,真实目标或来源。真正的目标只能依靠真实的目标或来源。一切最终(递归)只取决于来源。

  9. 不应该在配方中递归地调用make,除了一种情况和一种情况:你有一些完全由自己构建的子目录,没有读取你自己以外的任何源或目标。
    在这种特殊情况下,你不可有假目标子目录和配方:

.PHONY: subdirectory subdirectory: $(MAKE) -C [email protected]

  • 如果你想使用其他的makefile,但不要满足以上例外,include他们。
  • 注意:我并不是说你不能在违反这些原则的情况下编写正确的Makefile。你可以并且有时这是必要的。但要做到这一点,你必须知道你在做什么,并理解更高级的概念。你不应该开始这样学习,而是首先按照上述原则开始写Makefiles。