首页 > 解决方案 > Makefiles:它们如何确定构建目标?

问题描述

我在尝试为当前项目扩展的继承生成文件中遇到了有趣的行为。

LIBS := lib/precompiled1.a lib/precompiled2.a lib/mylib1.a lib/mylib2.a

mylib1-src := (source directory)
mylib1-obj := $(patsubst $(mylib1-src)/%.c, obj/LIB1/%.o, $(wildcard $(mylib1-src)/*.c))

mylib2-src := (source directory)
mylib2-obj := $(patsubst $(mylib2-src)/%.cpp, obj/LIB2/%.o, $(wildcard $(mylib2-src)/*.cpp))

default: all

lib/mylib1.a: $(mylib1-obj)
    ar -r $@ $^

lib/mylib2.a: $(mylib2-obj)
    ar -r $@ $^

all: exe/my_out

exe/my_out: $(my_out-obj)
    g++ $^ $(COMMON_FLAGS) $(LIBS) $(MY_FLAGS)

当我运行 make 时,我遇到了一个错误,它无法链接到 lib/mylib1.a,并且它中断了。很酷,我只需要确保正在构建 .a 目标。像这样天真地使用makefile:

lib/mylib1.a: $(mylib1-obj)
    ar -r $@ $^

lib/mylib2.a: $(mylib2-obj)
    ar -r $@ $^

default: all

这现在编译 mylib1.a 就好了,但既不编译 mylib2.a 也不编译'all'。

这就是我卡住的地方。如果我执行以下操作:

default: all

lib/mylib1.a: $(mylib1-obj)
    ar -r $@ $^

lib/mylib2.a: $(mylib2-obj)
    ar -r $@ $^

all: lib/mylib1.a exe/my_out

然后编译器抱怨 lib/mylib1.a 不是可执行文件。它不是,很好,但让我陷入了一个奇怪的境地。我可以单独编译 .a 文件。我可以将它们链接到可执行文件。我不能一次做所有这些事情,只能通过弄乱makefile,这在某种程度上违背了这一点。

我的问题是,为什么更改默认顺序会改变构建的内容?如何让所有 .a 文件构建并链接到主可执行文件,而无需每次都手动弄乱makefile?一般来说,我对 makefile 相当陌生,我不确定为什么会发生这种行为。

谢谢!

标签: gnu-makemakefile

解决方案


makefile 中目标的顺序无关紧要,但有一个例外:第一个是默认目标,即在没有目标的情况下调用make的目标。可以在 GNU make 中更改此行为.DEFAULT_GOAL := ...

依赖顺序

串行构建 ( make -j1) 中重要的是目标定义中的依赖顺序,例如

T: A B C

或者

T: A B
T: C
    rule

在串行构建make中,将首先实现“A”,然后是“B”,然后是“C”。如果“C”在构建“A”时缺少满足的依赖项,则构建将成功。将生成文件更改为

T: C A B

...并且串行构建将开始失败。

在并行构建 ( make -jN) 中,依赖顺序无关紧要,因为make如果允许,将尝试并行构建“A”、“B”和“C”。

不完全依赖

如果没有为目标“T”列出强制依赖项“D”,则make一旦满足列出的依赖项,将允许构建目标“T”。但它不会等待“D”完成。因此,构建成功取决于未定义的行为,要么

  1. “D”在构建开始之前已经存在并且当前构建没有触及,或者
  2. 目标“D”在目标“T”开始之前完成。

并行构建的最坏情况:如果“T”的规则在同时读取“D”和“D”时没有失败,那么最终构建成功,但构建工件无效。

不完全依赖的常用指标是

  • 从串行切换到并行时,构建开始(随机)失败,
  • 移动到另一台构建机器时构建开始随机失败,或者
  • 从具有奇怪测试失败的成功构建中构建工件。

解决方案

始终为所有目标指定完整的依赖关系。在您的情况下,这至少是:

# Add internal dependencies included in $(LIBS)
exe/my_out: $(my_out-obj) $(filter lib/%.a, $(LIBS))
    g++ $^ $(COMMON_FLAGS) $(LIBS) $(MY_FLAGS)

推荐阅读