【问题标题】:Working with multiple source file extensions in a makefile在 makefile 中使用多个源文件扩展名
【发布时间】:2012-01-23 08:48:55
【问题描述】:

我有一个 c++ 项目,其中包含各种源文件扩展名(.cpp、.c、.cc)和各种头文件扩展名(.hpp、.h、.hh)。源文件位于名为 SRC 的目录中,而头文件可预见地位于名为 INC 的目录中。

我想用这样的规则编译源代码

vpath %.c $(SRC)

%.o: %.c
    $(COMPILER) $(FLAGS) $< $(INCFLAG)$(INC)

如果我知道源文件的格式为 %.c,这当然可行,但在多个可能的文件扩展名的情况下,我还需要为 %.cpp 和 %.cc 构建类似的规则.当然,编写三个规则并不是什么大不了的事,但是如果能够将此 makefile 用作任何项目的拖放功能,即使是使用不同的语言,也无需重新编写规则,那就太好了。

那么我该如何编写一个规则(或实现相同目标的其他构造),其工作方式如下:

SRC_EXT = cpp c cc
vpath %.$(SRC_EXT) $(SRC)

%.o: %.$(SRC_EXT)
    $(COMPILER) $(FLAGS) $< $(INCFLAG)$(INC)

感谢您的帮助。

【问题讨论】:

    标签: makefile rules file-extension


    【解决方案1】:

    您不能在标准 POSIX 中制作。但是,由于您提到 vpath,我假设您使用的是 GNU make。如果您有足够新的版本(3.81 或更高版本),您可以使用 call 和 eval 轻松完成此操作:

    SRC_EXT = cpp c cc
    
    define compile_rule
    %.o : %.$1
            $$(COMPILER) $$(FLAGS) $$< $$(INCFLAG)$$(INC)
    endef    
    $(foreach EXT,$(SRC_EXT),$(eval $(call compile_rule,$(EXT))))
    

    如果您没有足够新的 GNU make,或者更喜欢替代解决方案,您可以对生成的 makefile 执行相同的操作。

    【讨论】:

    • 啊哈!伟大的!我想知道如何调用编译规则,但是首先如何调用 foreach 呢?它只是坐在文件中,因为它在您设置 SRC_EXT 变量后立即被调用?即使 .o 是最新的,这是否会强制重新编译所有源文件?
    • Makefile 解析都是关于扩展的。每当 make 在“直接上下文”中遇到变量或函数时(参见 GNU make 手册中的“Make 如何读取 Makefile”),它都会扩展它。当然,这可能涉及许多步骤。一旦扩展完成,剩下的任何东西都会被解析为一个makefile。 eval 函数非常特殊。基本上,这个 foreach 循环在读取 makefile 时由 make 扩展和解析,并且它定义规则的方式与您将它们写出的方式相同。因此它的行为与任何其他 make 规则一样(不会强制重新编译)。
    • 我不明白EXT 是什么意思,谁能解释一下?编辑:没关系,似乎是for 循环中的i
    猜你喜欢
    • 2020-01-11
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多