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

Makefile隐式规则匹配-前缀长度不影响匹配

  •  3
  • davidA  · 技术社区  · 9 年前

    在我的gnu-make-3.81 Makefile中,我希望定义两个隐式规则,使更具体的第一个规则优先于更一般的第二个规则:

    src/%_bar.o : src/%_bar.c
        $(CC) -Wall -Wno-unused-but-set-variable -c $^ -o $@
    
    src/%.o : src/%.c
        $(CC) -Wall -c $^ -o $@
    

    我的问题是foo_bar。c表示自动生成的代码,该代码触发了我更希望抑制的-Wall警告,因此第一条规则旨在捕捉这种特殊情况。

    根据 make's manual :

    可能有多个模式规则满足这些标准。在这种情况下,make将选择具有最短词干的规则(即最具体匹配的模式)。

    我以为文件名是 src/foo_bar.o ,第一条规则将生成词干 foo ,第二个将生成 foo_bar 。前者是最短的,所以我希望它适用。然而,情况似乎并非如此,第二条规则由make选择并执行。跑步 make -d 甚至没有显示出与阀杆匹配的尝试 食品 -仅 foo_bar(foo_bar) 考虑。

    如果我进行以下更改,通过将前缀从 src/ sr ,仍然选择第二条规则:

    src/%_bar.o : src/%_bar.c
        $(CC) -Wall -Wno-unused-but-set-variable -c $^ -o $@
    
    sr%.o : sr%.c
        $(CC) -Wall -c $^ -o $@
    

    我无法将此与make文档进行协调。

    此外,如果我删除 钢筋混凝土/ 完全前缀,第二条规则 挑选出来的:

    src/%_bar.o : src/%_bar.c
        $(CC) -Wall -Wno-unused-but-set-variable -c $^ -o $@
    
    %.o : %.c
        $(CC) -Wall -c $^ -o $@
    

    虽然这解决了我的问题,但它实际上并不适合,因为它覆盖了当前目录上我需要保留的另一个隐式规则/与之交互:

    %.o : %.c
        # do something else
    

    我的问题是为什么 make 在这种情况下,应该这样做,这与文档是否一致?如果是,有没有更好的方法来指定更专业的隐式规则?

    1 回复  |  直到 9 年前
        1
  •  4
  •   MadScientist    9 年前

    首先,请注意,模式匹配的“最短茎”方法是在GNU make 3.82中引入的。如果您使用的是GNU make 3.8 1,那么您的make版本使用的是“第一次匹配”的旧方法。如果可能的话,最好阅读发行版附带的文档,而不是web文档,因为web文档适用于GNU make的最新版本。GNU make 3.81于2006年4月发布……这已经很旧了。

    然而,您提供的示例实际上确实按照您希望的方式工作:

    src/%_bar.o : src/%_bar.c ; @echo shorter: $*
    
    src/%.o : src/%.c ; @echo longer: $*
    
    all: src/foo_bar.o
    
    $ make-3.81
    shorter: foo
    
    $ make-3.82
    shorter: foo
    

    我怀疑当你在这里提出问题时,你没有使用你在真实环境中使用的代码。在那种环境下,你必须有更短的模式 之后 较长的图案,如下所示:

    src/%.o : src/%.c ; @echo longer: $*
    
    src/%_bar.o : src/%_bar.c ; @echo shorter: $*
    
    all: src/foo_bar.o
    
    $ make-3.81
    longer: foo_bar
    
    $ make-3.82
    shorter: foo
    

    提问时,确保问题中的简化示例准确反映真实情况非常重要。