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

时间:2015-08-05 07:45:30

标签: makefile gnu-make gnu rule

在我的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和execute选择的。运行make -d甚至没有显示与词干foo匹配的尝试 - 仅考虑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/前缀,则会选择第二条

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 个答案:

答案 0 :(得分:4)

首先,请注意在GNU make 3.82中引入了模式匹配的“最短词干”方法。如果您使用的是GNU make 3.81,那么您的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

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