Linux下如何修改Makefile实现先编译source目录再编译根目录C++源码并输出至obj目录
没问题,我来帮你调整Makefile,让它既能编译根目录的源码,也能处理source/目录的文件,所有目标文件都乖乖放到obj/里。先梳理下原文件的核心局限,再直接上修改后的完整代码,最后讲清楚关键改动点。
原Makefile的核心局限
- 仅抓取了
source/目录下的.cpp文件,完全没处理根目录的file1.cpp、file2.cpp等源码 - 编译和依赖生成规则都只针对
source/的文件,根目录源码没有对应的编译逻辑 - 缺少
obj/目录的自动创建保障(虽然你说当前目录已存在,但新增目标文件时还是容易因目录缺失报错)
修改后的完整Makefile
CC = g++ CXXFLAGS = -std=c++11 -Wall LDFLAGS = -pthread APPNAME = trading_app EXT = .cpp SRCDIR = source OBJDIR = obj # 收集根目录 + source/目录下的所有.cpp文件 SRC = $(wildcard *$(EXT)) $(wildcard $(SRCDIR)/*$(EXT)) # 将所有源文件映射到obj/目录下的.o文件(去掉路径后统一替换后缀) OBJ = $(patsubst %$(EXT),$(OBJDIR)/%.o,$(notdir $(SRC))) # 生成每个.o对应的依赖文件.d DEP = $(OBJ:$(OBJDIR)/%.o=%.d) RM = rm DELOBJ = $(OBJ) # 确保obj目录存在,避免编译时因目录缺失报错 $(OBJDIR): mkdir -p $(OBJDIR) all: $(OBJDIR) $(APPNAME) $(APPNAME): $(OBJ) @echo "building the executable..." $(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) # 处理根目录源文件的依赖生成 %.d: %$(EXT) @$(CPP) $(CXXFLAGS) $< -MM -MT $(OBJDIR)/$*.o >$@ # 处理source/目录源文件的依赖生成 %.d: $(SRCDIR)/%$(EXT) @$(CPP) $(CXXFLAGS) $< -MM -MT $(OBJDIR)/$*.o >$@ # 编译根目录的.cpp到obj/下的.o $(OBJDIR)/%.o: %$(EXT) $(CC) $(CXXFLAGS) -o $@ -c $< # 编译source/目录的.cpp到obj/下的.o $(OBJDIR)/%.o: $(SRCDIR)/%$(EXT) $(CC) $(CXXFLAGS) -o $@ -c $< # 自动加载依赖文件,处理头文件修改后的重编译 -include $(DEP) # 新增clean规则,方便清理生成文件 clean: $(RM) -f $(DELOBJ) $(DEP) $(APPNAME)
关键改动点解释
收集全量源码文件
修改SRC变量,用$(wildcard *$(EXT))抓取根目录的所有.cpp文件,再和source/目录的文件合并,确保所有源码都被纳入编译范围。统一目标文件路径
用$(notdir $(SRC))去掉所有源文件的路径前缀,再通过$(patsubst)将每个.cpp替换为obj/%.o——不管源文件在根目录还是source/,生成的目标文件都会统一放在obj/目录下。保障目录存在
添加$(OBJDIR)目标和mkdir -p命令,确保编译前obj/目录一定存在(即使原本没有也会自动创建,避免报错)。覆盖两种源文件的编译规则
新增针对根目录源文件的编译规则$(OBJDIR)/%.o: %$(EXT),和原有的source/目录规则配合,确保所有源文件都能被正确编译到obj/目录。完善依赖处理
新增根目录源文件的依赖生成规则,同时添加-include $(DEP)让Make自动加载依赖文件,这样头文件修改时,对应的目标文件会自动重编译。实用的clean规则
补充了clean目标,方便一键清理生成的目标文件、依赖文件和可执行文件,日常开发更省心。
这样修改后,Makefile会先编译所有源文件(根目录+source/)到obj/目录,再链接生成最终的可执行文件,完全满足你的需求。
内容的提问来源于stack exchange,提问作者ekremer

