考虑此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_1
和group_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
应该运行得更快(推断为更大的依赖树)。
答案 0 :(得分:1)
您无法轻松地对目标执行此操作。问题在于a.out
将取决于两个文件 group_1
和group_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)