Makefile编译多独立cpp文件输出exe到bin目录的报错排查
问题根因
你写的Makefile触发警告、无法实现需求的核心问题有3个:
- 目标依赖关系完全错误:规则
$(BIN): $(OBJS)给bin目录下的每一个可执行文件,都绑定了src目录下所有cpp生成的.o文件作为依赖,完全不符合「单个cpp编译为单个独立可执行文件」的需求。 - 冗余的错误编译命令:上述规则下执行的
$(CXX) -c $(CXXFLAGS) -o $(OBJS)命令逻辑完全不成立:-c参数的作用是告知g只做编译、不做链接,此时你把所有已经生成的.o文件(属于链接阶段的输入文件)传给g,g++就会抛出linker input file unused because linking not done警告。 - 可执行文件后缀缺失:你定义的
BIN变量没有加Windows平台要求的.exe后缀,最终生成的文件名不符合预期。
可用的正确Makefile
CXX = g++ CXXFLAGS = -g -Wall # 扫描src目录下所有cpp源文件 SRC := $(wildcard src/*.cpp) # 对应源文件生成的.o文件,存放在src目录下 OBJS := $(SRC:.cpp=.o) # 最终生成的可执行文件,全部存放在bin目录,带.exe后缀 BIN := $(SRC:src/%.cpp=bin/%.exe) # 首次执行时自动创建bin目录,避免路径不存在报错 $(shell mkdir -p bin) .PHONY: all clean all: $(BIN) # 编译cpp生成对应.o文件,匹配要求的编译日志输出格式 src/%.o: src/%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< # 链接单个.o文件,生成bin目录下对应的独立可执行文件 bin/%.exe: src/%.o $(CXX) -o $@ $^ # 可选清理命令,执行make clean即可删除所有编译产物 clean: rm -f $(OBJS) $(BIN)
效果说明
执行make命令后,终端输出的编译日志和预期完全一致:
g++ -g -Wall -c -o src/program1.o src/program1.cpp g++ -g -Wall -c -o src/program2.o src/program2.cpp g++ -g -Wall -c -o src/program3.o src/program3.cpp g++ -g -Wall -c -o src/program4.o src/program4.cpp
编译完成后,bin目录下会生成program1.exe、program2.exe、program3.exe、program4.exe四个独立可执行文件,每个文件仅由对应同名的cpp源码编译链接生成,不会混入其他源码的目标文件。
内容的提问来源于stack exchange,提问作者Alix Blaine
相关产品推荐
相关产品推荐

