【问题标题】:How do I create a static implicit rule in a Makefile?如何在 Makefile 中创建静态隐式规则?
【发布时间】:2014-09-27 13:59:27
【问题描述】:

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

%$(EXESUFIX) : %.c
    $(CC) -o $* $

但问题是在 OS X 和 Linux 上 $(EXESUFFIX) 是空白的,这会导致规则匹配错误的内容。所以我尝试如下使用static pattern rule

$(EXECS) : %$(EXESUFIX) : %.c
    $(CC) -o $* $

其中$(EXECS) 是目标,因此没有扩展名。但是现在,最重要的规则是针对以 .cpp 结尾的源运行。我该如何解决这个问题?

举个完整的例子:

生成文件:

后缀 = 执行 = 测试 $(EXECS) : %$(EXESUFIX) : %.c $(CC) -o $* $

test.cpp:

#include int main(int argc, char *argv[]){ printf("你好世界\n"); 返回0; }

这会打印出错误:

Makefile:8: 警告:覆盖目标“测试”的命令
Makefile:5:警告:忽略目标“测试”的旧命令
make: *** 没有规则来制作目标 `test.c',`test' 需要。停止。

【问题讨论】:

  • 您可能想要粘贴整个 makefile 和源目录的 ls
  • 该规则错误地匹配了哪些“错误”?这可能是一个比这个更容易解决的问题。
  • @user657267 我正在尝试这样做,以便如果存在以.cpp 结尾的文件并且没有扩展名的文件名在$(EXECS) 列表中,则执行底部规则,如果它结束与.cpp 一起做最重要的规则。这个想法适用于大写情况(没有静态模式规则),但不适用于静态模式规则。
  • 为了清楚起见重写我的 cmets:你有两个规则要创建 test,有两个先决条件,但 test.c 不存在并且 make 不知道如何创建它。为什么首先需要为 test 制定单独的规则?
  • @user657267 它不是专门用于测试的,如果有第二个可执行文件的源是 c 文件怎么办?是的,我可以将“C 可执行文件”和“c++ 可执行文件”分开,但如果没有必要,我宁愿不这样做。

标签: c++ c makefile


【解决方案1】:

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

4.12.2 静态模式规则与隐式规则

静态模式规则与定义为模式规则的隐式规则有很多共同之处>(请参阅定义和重新定义模式规则)。两者都有目标模式和构建先决条件名称的模式。不同之处在于 make 如何决定何时应用规则。

隐式规则可以应用于与其模式匹配的任何目标,但它仅在目标没有另外指定配方时才适用,并且仅在可以找到先决条件时才适用。 如果出现多个隐含规则适用,则只有一个适用;选择取决于规则的顺序。

相比之下,静态模式规则适用于您在规则中指定的精确目标列表。 它不能应用于任何其他目标,并且总是适用于指定的每个目标。如果两个相互冲突的规则适用,并且都有配方,那就是错误。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多