单阶段编译成功但分两阶段编译链接失败的问题咨询
单阶段g++编译Antlr4项目成功,分编译链接阶段失败的原因
问题描述
编译简单Antlr4项目时,单条g++命令可成功完成编译,但分编译、链接两阶段操作时,出现大量未定义引用错误,无法正确链接antlr库。
单阶段编译(成功)
g++ -std=c++11 -Wall -Wextra *.cpp -L. -l antlr4-runtime -I/usr/local/include/antlr4-runtime -I. -o exec
两阶段编译(失败)
Makefile内容:
main: $(OBJS) g++ -L. -l antlr4-runtime $^ -o exec %.o: %.cpp g++ -std=c++11 -Wall -Wextra -I/usr/local/include/antlr4-runtime -I. -c $<
原因分析
问题核心在于链接时库的顺序:g++链接器是按从左到右的顺序处理符号依赖的。
- 单阶段编译命令中,源文件
*.cpp排在库-l antlr4-runtime之前,链接器处理源文件生成的目标文件时,遇到未定义的Antlr4符号,会后续在antlr库中查找对应定义,因此能正常完成链接。 - 两阶段的链接命令中,
-l antlr4-runtime放在目标文件列表$^之前,链接器先处理antlr库时,还未遇到需要引用的符号,会直接跳过库内的符号记录;后续处理目标文件时,遇到未定义符号,就无法找到已经跳过的库中对应的定义,从而抛出未定义引用错误。
解决方法
调整链接命令的顺序,将目标文件放在库的前面即可:
main: $(OBJS) g++ $^ -L. -l antlr4-runtime -o exec %.o: %.cpp g++ -std=c++11 -Wall -Wextra -I/usr/local/include/antlr4-runtime -I. -c $<
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

