【发布时间】:2018-03-08 02:12:32
【问题描述】:
我正在尝试改进我们当前基于 GNU Make 的构建系统。它是半非递归和半递归的。
按照[1],它在目录树上是非递归的。虽然源是在逻辑模块中跨目录组织的,但它们最终会被引入单个依赖关系图。
但是,它也是类似于 [2] 中描述的多架构构建(例如 32 位 vs 64 位,还有 RELEASE vs DEBUG 和 Internal vs External,导致大量可能的组合),并且那个方面是递归的:顶级makefile使用给定的apps目标和不同的变量(CPU_WIDTH=32或=64)调用自身。
这经常会导致问题,因为某些目标只需要在顶层构建一次,而大多数其他目标需要在递归级别中为每个架构使用适当的标志构建。我们经常会发现一些构建一次的目标实际上被构建了多次,不知何故被扫入了递归的依赖树。
我如何设计一个 Makefile,使其在一次非递归的 Make 调用中包含整个多架构依赖图?
我觉得一个关键特性是使用target-specific variables,它在依赖关系图中至关重要地传播。不幸的是,一个给定的命名目标只会被构建一次,即使它应该使用不同的选项构建多次。解决此问题的一种方法是在目标名称中添加一些特定于架构的信息(例如,而不是目标foo.o,使其成为32/foo.o 和64/foo.o),但在以下天真示例中这不起作用:
.PHONY: all exe32 exe64 baz-$(ARCH)
all: exe32 exe64
exe32: ARCH = 32
exe32: baz-$(ARCH)
@echo in $@ ARCH is $(ARCH)
exe64: ARCH = 64
exe64: baz-$(ARCH)
@echo in $@ ARCH is $(ARCH)
baz-$(ARCH):
@echo in $@ ARCH is $(ARCH)
这会导致错误的输出:
in baz- ARCH is 32
in exe32 ARCH is 32
in exe64 ARCH is 64
【问题讨论】:
-
我认为放弃在同一棵树中构建会更容易 - 使用第二个参考中描述的 VPATH 方法。然后您可以更简单地构建:
make -C arm64 -f ../src/Makefile && make -C arm32 -f ../src/Makefile(甚至是顶级 Makefile 中的all: $(ARCHES)和%:⤶↦$(MAKE) -C $@的某些版本)。