linux gcc编译器误用-MM导致出现linker input file unused because linking not done

背景

昨晚深夜,音视频群有网友发消息给我,反馈我写的Makefile模板工程有一个bug,输入make之后,提示:linker input file unused because linking not done,并且没有生成a.out文件。
毕竟是自己一直维护的代码,出现bug就修正。

解决

错误详细信息如下:

g++: warning: ../build/main/main.o: linker input file unused because linking not done
g++: warning: ../build/bar/libbar.a: linker input file unused because linking not done
g++: warning: ../build/foo/libfoo.a: linker input file unused because linking not done

初步看不出问题,打开编译命令行打印信息,结果如下:

g++ -Wall -Wfatal-errors -MM -g  -I../include/ ../build/main/main.o -o ../bin/a.out ../build/bar/libbar.a ../build/foo/libfoo.a
g++: warning: ../build/main/main.o: linker input file unused because linking not done
g++: warning: ../build/bar/libbar.a: linker input file unused because linking not done
g++: warning: ../build/foo/libfoo.a: linker input file unused because linking not done

好像也没问题(注意!实际已经出现问题了,只是未发现),看一下.o文件格式:

file ../build/main/main.o
../build/main/main.o: ASCII text

竟然是ASCII文本,有点异常,查看其内容:

cat ../build/main/main.o
main.o: main.cpp ../include/foo.h ../include/bar.h ../include/crc.h \
 hello.h

从内容上,与生成的依赖文件是一样的。继续分析,发现在config.mk文件的CFLAGS = -Wall -Wfatal-errors -MM有问题。先看生成依赖文件的脚本关键的语句:

_depend: $(obj).depend

        $(CC)  $(CFLAGS) -E -MQ $(_obj)$$g $$f >> $@ ; 

为了生成依赖文件(.d文件),需要使用-MM,因此才有CFLAGS定义。但是CFLAGS同样也用于编译源码文件,但编译源码是不能使用-MM的,混用之后,得到的.o文件实际上就是依赖文件,具体见上内容。
知道问题后,修改就简单了,在CFLAGS去掉-MM,在生成依赖文件的脚本的CFLAGS前添加-MM即可。

小结

这次Bug是没有对编译选项做全面检查导致了。修正的版本已提交github。地址:https://github.com/latelee/Makefile_templet,具体在:https://github.com/latelee/Makefile_templet/tree/master/mult_dir_project。

李迟 2018.8.31 晚

你可能感兴趣的:(GNU/Linux)