为何Make会自动执行cc编译命令?Makefile编译报错排查
问题描述
我正在学习使用Make工具,编写了如下简单的Makefile:
all: main other main: main.c other.o gcc main.c -o main echo "Compiled main.exe" other: other.o other.c: touch $@ echo "int main(){return 0;}" > $@ echo "Created other.c" other.o: other.c gcc other.c -o other.o echo "Compiled other.o" clean: rm -f main.exe other.o other.c
执行make all时,大部分步骤均正常执行,但最后自动触发了一条cc other.o -o other命令,引发了多重定义的链接错误,具体执行输出如下:
> make all touch other.c echo "int main(){return 0;}" > other.c echo "Created other.c" Created other.c gcc other.c -o other.o echo "Compiled other.o" Compiled other.o gcc main.c -o main echo "Compiled main.exe" Compiled main.exe cc other.o -o other <--- /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o: in function `mainCRTStartup': /c/S/B/src/msys2-runtime/winsup/cygwin/crt0.c:20: multiple definition of `mainCRTStartup'; /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../crt0.o:/c/S/B/src/msys2-runtime/winsup/cygwin/crt0.c:20: first defined here /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o: in function `mainCRTStartup': /c/S/B/src/msys2-runtime/winsup/cygwin/crt0.c:20: multiple definition of `WinMainCRTStartup'; /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../crt0.o:/c/S/B/src/msys2-runtime/winsup/cygwin/crt0.c:20: first defined here /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o:cygming-crtbeg:(.text+0x50): multiple definition of `__gcc_register_frame'; /usr/lib/gcc/x86_64-pc-msys/13.2.0/crtbegin.o:cygming-crtbeg:(.text+0x0): first defined here /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o:cygming-crtbeg:(.text+0x70): multiple definition of `__gcc_deregister_frame'; /usr/lib/gcc/x86_64-pc-msys/13.2.0/crtbegin.o:cygming-crtbeg:(.text+0x20): first defined here /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o:cygming-crtbeg:(.data+0x0): multiple definition of `__dso_handle'; /usr/lib/gcc/x86_64-pc-msys/13.2.0/crtbegin.o:cygming-crtbeg:(.data+0x0): first defined here collect2: error: ld returned 1 exit status make: *** [<builtin>: other] Error 1
请问这条cc命令为何会被Make自动执行?
原因分析与解决办法
原因
你定义的other: other.o规则没有指定具体的执行命令,Make会触发内置隐式规则来尝试生成目标other。
Make的内置规则中,存在从.o文件生成可执行文件的默认逻辑,对应的命令就是cc $^ -o $@——这就是那条自动执行的cc other.o -o other的来源。
而你的other.o是从包含main函数的other.c编译而来,链接时会和系统默认的启动代码(包含mainCRTStartup等符号)产生重复定义,因此触发链接错误。
解决办法
根据实际需求,有两种常见修复方式:
如果
other只是用于确保other.o被构建的中间目标(不需要生成可执行文件),可以将其标记为伪目标:.PHONY: other other: other.o这样Make就不会尝试为它寻找隐式规则生成文件,只会执行规则依赖检查。
如果
other确实需要生成可执行文件,需要显式写出链接命令,同时建议修改other.c的内容(比如移除main函数,改为普通函数)避免符号冲突:other: other.o gcc other.o -o other echo "Compiled other.exe"
内容的提问来源于stack exchange,提问作者verpas
相关产品推荐
相关产品推荐

