为何Makefile生成的目标文件未存入指定build目录?求解答
问题分析与修正方案
核心问题点
- 编译目标文件未指定输出路径:你的隐式规则里编译命令没有用
-o $@指定输出文件,g++默认会把.o文件生成在当前工作目录,而非$(BUILD_DIR)下。 - 链接命令参数顺序错误:
-o选项后面必须直接跟输出程序名,你写的-o $(INCLUDES) $(PROG)会把第一个头文件当成输出目标,完全不符合预期。 - 编译阶段错误引入链接参数:
${LFLAGS}(-lstdc++fs)是链接阶段才需要的库参数,编译.cpp时不需要添加。 - 未自动创建build目录:如果
./build目录不存在,Make不会自动创建,导致编译时无法写入目标文件。
修正后的Makefile
BUILD_DIR:= ./build SRC_DIRS := ./src INCL_DIR := ./includes CC := /usr/bin/g++ #Compiler used LVERSION := -std=c++17 #Language Version CXXFLAGS := -g $(LVERSION) -I$(INCL_DIR) # 合并版本参数,添加头文件搜索路径 CFLAGS := -Wall #Compiler Flags LFLAGS := -lstdc++fs #Linker Flags SRCS := Audio.cpp Song.cpp Visual.cpp VisualSong.cpp INCLUDES := $(SRCS:%.cpp=$(INCL_DIR)/%.h) OBJS := $(SRCS:%.cpp=$(BUILD_DIR)/%.o) PROG := progName.exe # 确保build目录存在 $(BUILD_DIR): mkdir -p $@ progName: $(BUILD_DIR) $(OBJS) $(CC) $(CFLAGS) $(CXXFLAGS) $(OBJS) -o $(PROG) $(LFLAGS) # 修正编译规则:指定输出文件,移除链接参数 $(BUILD_DIR)/%.o: $(SRC_DIRS)/%.cpp $(INCL_DIR)/%.h $(CC) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ .PHONY: clean progName clean: /bin/rm -rf $(BUILD_DIR)/*.o $(PROG) $(INCL_DIR)/*.gch
关键修改说明
- 添加build目录创建规则:新增
$(BUILD_DIR)目标,用mkdir -p确保目录存在,作为progName的依赖,编译前自动创建。 - 修正编译命令:用
-c $< -o $@,其中$<表示第一个依赖文件(即.cpp源文件),$@表示当前目标(即$(BUILD_DIR)/%.o),明确指定输出路径。 - 调整链接命令参数顺序:
-o $(PROG)放在正确位置,链接库参数$(LFLAGS)放在最后(链接时库参数通常在目标文件之后)。 - 优化参数组织:把
$(LVERSION)合并到CXXFLAGS,并添加-I$(INCL_DIR)让编译器自动搜索头文件,不需要在编译命令里手动指定头文件路径。 - 修正clean目标路径:用变量
$(INCL_DIR)代替硬编码的includes,保持一致性。
内容的提问来源于stack exchange,提问作者Makore
相关产品推荐
相关产品推荐

