编译OpenGL C代码的Makefile误将自身规则当作文件编译求助
问题根因
- 你定义的
castle_link、castle_compile属于伪目标:规则执行后不会生成和目标名完全一致的文件,但你没有使用.PHONY标记这类目标。 - Make存在内置隐式推导规则:当生成可执行目标
castle时,Make发现其依赖castle_link没有对应实体文件,会自动触发隐式链接逻辑,尝试把castle.o和它判定为待链接文件的castle_link合并生成castle,就出现了你观察到的第三行多余编译命令。 - 手动单独执行
castle_compile、castle_link规则时,是直接调用目标对应的命令,不会触发castle目标的隐式规则推导,因此不会出现异常。
另外你当前的写法存在冗余错误:编译阶段(带-c参数)不需要传入-l开头的链接库参数,这类参数仅在链接阶段生效,放在COMPILEFLAGS中属于无效冗余配置。
解决方案
方法1:标记伪目标(适配你现有写法)
在Makefile开头或末尾添加如下声明,明确告知Make哪些目标不需要匹配实体文件:
.PHONY: run_castle castle_link castle_compile clean
修改后再执行make castle就不会触发多余的隐式链接规则。
方法2:简化Makefile(更规范的写法)
你不需要额外拆分castle_compile、castle_link两层中间目标,直接利用Make的隐式规则可以写出更简洁的版本:
CC = gcc COMPILEFLAGS = -Wall -c LINKFLAGS = -lglut -lGL -lGLU -lm # 最终可执行目标 castle: castle.o ${CC} -o $@ $^ ${LINKFLAGS} # 运行目标,依赖castle确保每次运行前都更新到最新版本 run_castle: castle ./castle $(ARGS) clean: rm -f *.o castle # 标记伪目标 .PHONY: run_castle clean
如果需要自定义编译参数可以额外添加castle.o的编译规则,否则Make会自动用COMPILEFLAGS将castle.c编译为castle.o,无需手动写规则。
内容的提问来源于stack exchange,提问作者Miguel N.
相关产品推荐
相关产品推荐

