在构建具有递归依赖性的库时,我有这个片段:
$(LIBRARY) : $(OBJECTS) | $(LIBDIR) # objects is all the obj/*.o
$(AR) ...
obj/%.o : %.cpp obj/%.d
$(CC) ...
build : $(DEPENDENCIES) $(LIBRARY)
$(DEPENDENCIES):
$(MAKE) -C $(ROOT)/$@
Run Code Online (Sandbox Code Playgroud)
如果我跑,这是有效的make.一切按照正确的顺序按预期构建.但是如果我运行make -jN,那么库会以错误的顺序构建,因为我实际上没有设置任何依赖性排序规则,这会导致许多未定义的引用.
如果我添加规则:
$(OBJECTS) : $(DEPENDENCIES)
Run Code Online (Sandbox Code Playgroud)
然后运行make每次重建每个库,无论更改(DEPENDENCIES是假的,但我不明白为什么它实际上重建了一切).如何在不必每次重建所有内容的情况下为并行构建强制执行正确的排序?
我将为您提供如何设置makefile以保证的一般指导:
一个.重建那个,只有必要的,和
湾 正确地处理并行性.
有些人已经要求一些"好的原则",所以他们在这里.
使用这些原则重写您的makefile,您可以保证正常工作.
十诫:
你应该调用makemake target(或目标)或默认目标,这是你的Makefile中的第一个目标.你的Makefile中的目标位于.的左侧:
有两种目标:真实和"虚假".真正的目标是您想要(重新)创建的实际文件(或目录).伪目标是抽象概念,而不是真实文件,但它通常表示一组真实文件.
Makefile中列出的目标也可能有一个%,在这种情况下它是一个模式目标,可以匹配多个目标,真实或虚假.
源是未列为目标的文件,并且在make调用之前已存在.
目标"取决于"在:目标之后写入的"先决条件"
真正的目标必须有一个"配方",它是目标行下的shell脚本.配方应该只写一个文件和一个文件,即目标文件.目标文件应该$@在配方内部引用.
如果配方写入多个文件,请将其分解为单个目标的多个配方.
配方可能会读取许多文件:这些文件必须列为先决条件.
虚假的目标一定不能有食谱.
虚假目标可以依赖于其他虚假目标,真实目标或来源.真正的目标必须仅依赖于真实的目标或来源.最终(递归)一切都只取决于来源.
你不应该make在食谱中递归调用,除了一种情况和一种情况:你有一些完全自己构建的子目录,而不会读取你自己以外的任何源或目标.
在这种特殊情况下,你应该有一个虚假的目标子目录和配方:
.PHONY: subdirectory
subdirectory:
$(MAKE) -C $@
include则为它们.注意:我并不是说你不能在违反这些原则的情况下编写正确的Makefile.你可以而且有时是必要的.但要做到这一点,你必须知道自己在做什么,并了解更高级的概念.你不应该开始学习那种方式,但首先要按照上述原则开始编写Makefile.
| 归档时间: |
|
| 查看次数: |
2410 次 |
| 最近记录: |