【问题标题】:Avoid duplicating GNU Make rules避免重复 GNU Make 规则
【发布时间】:2011-08-22 15:43:39
【问题描述】:

我一直在编写一个生成一些依赖项的 Makefile,我发现自己不得不重复规则,因为(旧版)代码库包含 .cpp.cc 文件的混合。好像有点不好看。无论如何指定目标的先决条件可以是.cpp.cc 文件?

所以与其拥有:

%.d : %.cpp
    $(CPP) -MM $(CPPFLAGS) $<

%.d : %.cc
    $(CPP) -MM $(CPPFLAGS) $<

创建一些没有重复的东西,例如:

%.d : %.(cpp | cc)
    $(CPP) -MM $(CPPFLAGS) $<

或者这种强制冗余只是 GNU Make 设计的一个不幸元素?

【问题讨论】:

  • 如果你使用 GNU 自动工具,你可以使用 m4 宏

标签: makefile rules targets


【解决方案1】:

第一种选择,使用一个变量定义一次规则体,根据需要重复使用:

DEPGEN=$(CPP) -MM $(CPPFLAGS) $<
%.d: %.cpp ; $(DEPGEN)
%.d: %.cc  ; $(DEPGEN)

第二个选项,使用$(eval)动态生成规则:

$(foreach src,cpp cc,$(eval %.d: %.$(src) ; $$(CPP) -MM $$(CPPFLAGS) $$<))

【讨论】:

    【解决方案2】:

    这应该可行:

    %.d :: %.cpp
        $(CPP) -MM $(CPPFLAGS) $<
    
    %.d :: %.cc
        $(CPP) -MM $(CPPFLAGS) $<
    

    另一个想法:

    %.d : %.c
        $(CPP) -MM $(CPPFLAGS) $<
    
    %.c : %.cpp
        ln $< $@  # or cp -p
    

    另一个想法是让 GNU make 生成两个模式规则。 基本上有两种方法可以做到这一点:

    • 将它们写入您使用 GNU make 的 include 语句包含在实际 makefile 中的 makefile(%-cc.mk 或类似文件)
    • 使用 GNU make 的 $(eval)$(call) 函数内联生成和评估它们

    与 C/Unix 开发工具链中的大多数其他东西一样,这些技术本质上是一种预处理形式,以非常难以使用为代价(大量的双重或三重转义,非常难以保留)使它们易于理解跟踪什么时候扩展;调试可能是一件非常痛苦的事情,至少在我的经验中)。

    因此将它们保留用于更复杂的用例(其中 Stack Overflow 列出了一些)。

    【讨论】:

    • 这些选项似乎都不能生成更简洁的生成文件。我可能会坚持原来的形式。不过感谢您的建议。
    猜你喜欢
    • 2018-12-28
    • 2011-10-28
    • 2017-09-26
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多