Gnu Make,虚假先决条件

时间:2018-12-13 02:11:51

标签: makefile gnu-make

考虑此Makefile

all: a.out

a.out: group_1 group_2
group_1: CXXFLAGS = -Wall
group_2: CXXFLAGS = -Wextra
group_1: a.o b.o
group_2: c.o

尽管它可能会很好地工作,但我想知道什么是正确的写法,因为根据GNU Make文档,group_1group_2必须为.PHONY目标,因为它们不是真正的目标,而只是一种将具有相同配置的一组目标分组的方法。

但是,与此同时,不应将.PHONY目标用作文档建议的其他目标的先决条件。所以我不知道指定这样的依赖结构的正确方法是什么。

这样做的目的是,如果我没有记错的话,就是优化目的。我希望对CXXFLAGS进行尽可能少的评估,并假设像{p1

Makefile

每个先决条件将对all: a.out a.out: a.o b.o c.o a.o b.o: CXXFLAGS = -Wall c.o: CXXFLAGS = -Wextra 进行一次评估,而对于前一种方法,每个组仅评估一次,因此我的第一个CXXFLAGS应该运行得更快(推断为更大的依赖树)。

1 个答案:

答案 0 :(得分:1)

您无法轻松地对目标执行此操作。问题在于a.out将取决于两个文件 group_1group_2。这些文件从不存在,因此a.out将始终被视为过时。

关于变量扩展问题,您的假设是不正确的。即使在第一个示例中,CXXFLAGS也会在每次构建任何目标时进行评估。一定要这样,因为变量赋值可能类似于:

group_1: CXXFLAGS = -DNAME='$@'

我不确定您为什么会认为变量的扩展会影响性能,但是如果它们确实花费很长时间(也许它们调用了shell之类的东西),那么您肯定会发现变量没有对要构建的特定目标的任何引用,并且您想强制它们仅扩展一次,则可以执行以下操作:

CXXFLAGS_1 := -Wall
CXXFLAGS_2 := -Wextra

GROUP_1 := a.o b.o
GROUP_2 := c.o

a.out: $(GROUP_1) $(GROUP_2)
$(GROUP_1): CXXFLAGS := $(CXXFLAGS_1)
$(GROUP_2): CXXFLAGS := $(CXXFLAGS_2)