代码之家  ›  专栏  ›  技术社区  ›  ABu

GNU制造,虚假的先决条件

  •  0
  • ABu  · 技术社区  · 6 年前

    考虑这个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 docs, group_1 group_2 必须是 .PHONY 目标,因为它们不是真正的目标,只是用相同的配置对一组目标进行分组的一种方式。

    但同时, 假的 目标不应作为文件建议的其他目标的先决条件。所以我不知道用什么方法来指定这样的依赖结构。

    这样做的目的是,如果我没有错,优化的目的。我想要 CXXFLAGS 尽可能少的评估,我假设 Makefile 喜欢

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

    将被评估 克星旗 每个先决条件一次,而使用前面的方法时,每个组仅一次,因此我的第一个 生成文件 应该运行得更快(外推到更大的依赖树)。

    1 回复  |  直到 6 年前
        1
  •  1
  •   MadScientist    6 年前

    你不能用目标轻易做到这一点。问题是 a.out 将取决于两个 文件夹 group_1 group_2 . 这些文件根本不存在,所以 A. 总是被认为是过时的。

    至于变量展开问题,你的假设是不正确的。即使在你的第一个例子中 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)