首页 文章

如何在Makefile中创建静态隐式规则?

提问于
浏览
2

我最初有两个隐含规则(为简洁起见而简化):

%$(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结尾的源代码运行 . 我该如何解决?

有关完整示例:

Makefile文件:

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.

2 回答

  • 0

    您链接到的GNU Make手册非常清楚静态规则和隐式规则之间的区别 .

    4.12.2静态模式规则与隐式规则静态模式规则与定义为模式规则的隐式规则有很多共同之处>(请参阅定义和重新定义模式规则) . 两者都有目标模式和构建先决条件名称的模式 . 不同之处在于make决定何时适用规则 . 隐式规则可以应用于与其模式匹配的任何目标,但只有在目标没有另外指定的配方时才会应用,并且只有在可以找到先决条件时才适用 . 如果多个隐式规则适用,则只适用一个;选择取决于规则的顺序 . 相反,静态模式规则适用于您在规则中指定的精确目标列表 . 它不能适用于任何其他目标,并且它总是适用于指定的每个目标 . 如果两个冲突的规则适用,并且两个都有配方,那就是错误 .

    我建议在C和C程序之间拆分可执行文件,并为每个程序定义独立的规则 .

  • 3

    我无法重现您的错误,但这适用于GNUMake 3.81:

    %$(EXESUFFIX) : %.c
        $(CC) -o $* $<
    
    %$(EXESUFFIX) : %.cpp
        $(CXX) -o $* $<
    

    具有适合相同目标的两个不同规则对于普通模式规则是合法的,但对于静态模式规则则不合法 .

相关问题