在 Makefile 中处理多个扩展的优雅方式
Posted
技术标签:
【中文标题】在 Makefile 中处理多个扩展的优雅方式【英文标题】:An elegant way to handle multiple extensions in Makefile 【发布时间】:2017-11-07 03:04:31 【问题描述】:我有一个由几个源头文件组成的小型 C++ 语言项目,我使用 Makefile 来构建我的项目。
最近我在我的项目中添加了一个 .c 文件,该文件最初只有 .cpp 文件。为了构建包括 .c 文件在内的整个项目,我修改了 Makefile,如下所示:
SRC_DIR := src
INC_DIR := include
BUILD_DIR := build
C_EXT := c
CPP_EXT := cpp
SOURCES := $(shell find $(SRC_DIR) -type f -name *.$(CPP_EXT))
$(shell find $(SRC_DIR) -type f -name *.$(C_EXT)) # Added!
...
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.$(CPP_EXT) $(INC_DIR)/%.h
@mkdir -p $(BUILD_DIR)
$(CXX) $(CFLAGS) -I $(INC_DIR) -c -o $@ $<
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.$(C_EXT) $(INC_DIR)/%.h # Added!
@mkdir -p $(BUILD_DIR) # Added!
$(CXX) $(CFLAGS) -I $(INC_DIR) -c -o $@ $< # Added!
但我认为它有点难看,因为有重复的命令。有什么方法可以去除重复并改进这个 Makefile 命令?
【问题讨论】:
如果您要使用相同的编译器编译它们,请重命名文件 else change.c 以使用 $CC @Waslap 这也是一个至关重要的信息。谢谢:D 【参考方案1】:Make 带有用于构建 C 和 C++ 的默认规则,因此对于基本用法,您不必担心这一点。由于您正在更改规则以创建更复杂的构建工具,因此您可能只想硬着头皮进行一些重复(在您的示例中并没有那么多)。您可以将这样的内容放在一个通用的 make include
文件中,并将其用于所有类似的项目——这样就不会弄乱您的项目特定的 makefile。
不过……
GNU make 确实提供了defining 和calling 函数,尽管它们可能不太清楚。
define do_compile
@mkdir -p $(BUILD_DIR)
$(CXX) $(CFLAGS) -I $(INC_DIR) -c -o $@ $<
endef
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.$(CPP_EXT) $(INC_DIR)/%.h
$(call do_compile)
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.$(C_EXT) $(INC_DIR)/%.h # Added!
$(call do_compile) # Added!
相关:functions in makefiles?
【讨论】:
如果您想变得更高级,请查看 gcc 的-MM
选项——它可以帮助您管理更具体的依赖关系树,因此您不必重新编译所有内容,因为任何包含文件已更改。不过请注意,这样做确实会带来一些新的挑战。以上是关于在 Makefile 中处理多个扩展的优雅方式的主要内容,如果未能解决你的问题,请参考以下文章
在 Watcom makefile 中扩展宏时 *$ 是啥意思?