编写Makefile遇问题:仅执行测试文件,未生成目标可执行文件
问题分析与解决
核心问题
build/tab.o无编译命令:原规则仅声明了依赖,但没有告诉make如何生成这个目标文件,导致依赖满足后也无法产出build/tab.o,自然无法继续构建bin/82。tabtest伪目标无实体文件:该规则没有生成名为tabtest的文件,make会认为它永远需要更新,每次执行都会优先跑测试,但测试完成后因为build/tab.o无法生成,后续流程中断。- 缺少目录初始化:
build、bin目录如果不存在,编译时会因无法写入文件失败。
修正后的Makefile
CC = gcc CFLAGS = -W -Wall -std=c89 -pedantic -O3 # 声明伪目标,避免与实际文件冲突 .PHONY: all tabtest clean all: bin/82 # 确保目录存在,避免编译时出错 bin/82 build/tab.o: | build bin # 生成主程序:链接main.c和tab.o bin/82: src/82/main.c build/tab.o $(CC) $(CFLAGS) $^ -o $@ # 生成tab.o:依赖tab.c和测试通过 build/tab.o: src/82/tab.c tabtest $(CC) $(CFLAGS) -c $< -o $@ # 执行tab模块测试:测试失败则终止构建 tabtest: src/82/tab.c src/82/tab_test.c $(CC) $(CFLAGS) $^ -o bin/test/tab && bin/test/tab # 清理生成文件 clean: rm -f build/*.o bin/82 bin/test/tab # 创建所需目录的通用规则 build bin: mkdir -p $@
关键修改说明
- 伪目标声明:用
.PHONY标记all、tabtest、clean,确保make不会把它们当成实际文件处理。 - 目录依赖:用
| build bin(订单式依赖)确保编译前先创建目录,且目录存在后不会重复创建。 - 补全编译命令:给
build/tab.o和bin/82添加实际的编译/链接命令,明确告诉make如何生成目标。 - 测试失败终止:通过
&&连接编译和测试命令,确保测试不通过时直接终止后续构建。
执行说明
- 直接运行
make:会先执行测试,测试通过后生成build/tab.o,最终构建bin/82。 - 运行
make clean:清理所有生成的目标文件和可执行程序。 - 若只想跑测试:执行
make tabtest即可。
内容的提问来源于stack exchange,提问作者Ter Maxima
相关产品推荐
相关产品推荐

