多目录C++项目如何编写Makefile实现指定exercise子项目一键构建
顶层Makefile编写方案
你原有Makefile的核心问题如下:
- 没有将
exercise_%目标和common目录的编译规则绑定,执行make exercise_xx时不会自动编译common下的.o文件 - 没有处理对应exercise目录下除了main.cpp之外的其他源文件(比如bar_x.cpp)的编译逻辑
- 直接用
common/*.o当依赖的写法有问题,当common目录还没生成.o文件时会识别失败
可用的完整Makefile代码
# 编译器配置 CXX = g++ CXXFLAGS = -Wall -g # 头文件搜索路径 INCLUDE = -I common/ # 生成common目录下所有的.o目标文件列表 COMMON_SRCS := $(wildcard common/*.cpp) COMMON_OBJS := $(patsubst %.cpp, %.o, $(COMMON_SRCS)) # 通用的.cpp生成.o的隐式规则 %.o: %.cpp $(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@ # exercise_%模式规则 exercise_%: common_build $(wildcard $@/*.cpp) # 编译当前exercise目录下所有的cpp为.o $(CXX) $(CXXFLAGS) $(INCLUDE) -c $(filter %.cpp, $^) # 把所有.o(common的+当前exercise的)链接生成可执行文件,放到对应exercise目录 $(CXX) $(CXXFLAGS) *.o $(COMMON_OBJS) -o $@/main # 不需要保留临时.o可以打开下面注释,清理顶层目录生成的exercise对应.o文件 # rm -f $(notdir $(patsubst %.cpp, %.o, $(wildcard $@/*.cpp))) # 编译common目录所有目标文件的伪目标 .PHONY: common_build clean common_build: $(COMMON_OBJS) # 全局清理规则:清理所有.o和所有exercise下的main可执行文件 clean: rm -f common/*.o rm -f exercise_*/main rm -f *.o
注意:Makefile中所有规则下的命令行开头必须是Tab字符,不能是空格,否则会报错。
使用方法
- 执行
make exercise_1就会自动编译common下所有源文件为.o,再编译exercise_1下所有cpp,链接后生成exercise_1/main可执行文件 - 执行
make exercise_10同理,只要对应exercise_10目录存在即可正常编译 - 执行
make clean可以一键清理所有编译生成的临时文件和可执行文件
内容的提问来源于stack exchange,提问作者Denisof
相关产品推荐
相关产品推荐

