在我的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将选择具有最短词干的规则(即,最具体匹配的模式)。
我认为对于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
在这种情况下会这样做,这与文档一致吗?如果是这样,是否有更好的方法来指定更专业的隐式规则?
答案 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
在提问时,确保问题中的简化示例准确反映实际情况非常重要。