我最初有两个隐含规则(为简洁起见而简化):
%$(EXESUFFIX) : %.c $(CC) -o $* $< %$(EXESUFFIX) : %.cpp $(CXX) -o $* $<
但问题是在OS X和Linux上$(EXESUFFIX)
是空白的,这导致规则匹配错误的东西。所以我试图使用static pattern rule如下:
$(EXECS) : %$(EXESUFFIX) : %.c $(CC) -o $* $< $(EXECS) : %$(EXESUFFIX) : %.cpp $(CXX) -o $* $<
$(EXECS)
是目标,因此没有扩展名。但现在,最重要的规则是以.cpp结尾的源代码运行。我该如何解决这个问题?
完整的例子:
生成文件:
EXESUFFIX = EXECS = test $(EXECS) : %$(EXESUFFIX) : %.c $(CC) -o $* $< $(EXECS) : %$(EXESUFFIX) : %.cpp $(CXX) -o $* $<
TEST.CPP:
#include <stdio.h> int main(int argc, char *argv[]){ printf("Hello World\n"); return 0; }
这会打印出错误:
Makefile:8: warning: overriding commands for target `test' Makefile:5: warning: ignoring old commands for target `test' make: *** No rule to make target `test.c', needed by `test'. Stop.
答案 0 :(得分:3)
您链接到的GNU Make手册非常清楚静态规则和隐式规则之间的区别。
4.12.2静态模式规则与隐式规则
静态模式规则与定义为模式规则的隐式规则有很多共同之处。 (请参阅定义和重新定义模式规则)。两者都有目标模式和构建先决条件名称的模式。不同之处在于决定何时适用规则。
隐式规则可以应用于与其模式匹配的任何目标,但只有在目标没有指定配方时才会应用,并且仅在找到先决条件时才适用。 如果出现多个隐式规则,则只适用一个;选择取决于规则的顺序。
相比之下,静态模式规则适用于您在规则中指定的精确目标列表。 它不能适用于任何其他目标,并且它总是适用于指定的每个目标。如果两个冲突的规则适用,并且都有配方,那就是错误。
我建议在C和C ++程序之间拆分可执行文件,并为每个程序定义独立的规则。
答案 1 :(得分:0)
我无法重现您的错误,但这适用于GNUMake 3.81:
%$(EXESUFFIX) : %.c
$(CC) -o $* $<
%$(EXESUFFIX) : %.cpp
$(CXX) -o $* $<
使用适合同一目标的两个不同规则对于普通模式规则是合法的,但对于静态模式规则则不合法。