Ubuntu下用Make构建gtest项目出现main多重定义错误如何解决
问题修复方案
错误原因
你遇到的两类报错核心原因如下:
- main多重定义错误:你自己编写的
Main_TestAll.cpp中已经实现了main函数,而libgtest_main.a静态库本身就自带了一个gtest默认实现的main入口,两者同时链接就会冲突。 - undefined reference系列错误:GCC的静态库链接存在顺序依赖规则,被依赖的库必须放在调用它的目标文件之后,你之前把
-lgtest这类库参数写到了编译命令最前面,链接器处理时先加载库,但还不知道后续目标文件需要哪些符号,就不会导出库内的符号,导致后续目标文件找不到gtest的相关实现。
修复方案
二选一即可,推荐选择方案1,灵活性更高:
方案1:保留自定义的Main_TestAll.cpp
- 移除链接参数中的
-lgtest_main - 拆分编译参数和链接参数,编译生成
.o的阶段不需要加库链接参数 - 链接时把所有库参数放在命令的最后位置
方案2:使用gtest自带的main入口
- 删掉自定义的
Main_TestAll.cpp,同时移除Makefile中对该文件的引用 - 保留
-lgtest_main参数,其余链接顺序调整规则和方案1一致
修复后的Makefile示例(方案1)
CXX = g++ # 编译阶段参数:仅加调试信息、线程支持、警告 CXXFLAGS = -g -Wall -pthread INCS = -I./ -I../../src -I/usr/local/include # 链接阶段参数:库路径、依赖库 LDFLAGS = -L/usr/local/lib LDLIBS = -lgtest -lpthread OBJS = ../../src/Addition.o Addition_Test.o ../../src/Multiply.o Multiply_Test.o testAll: $(OBJS) # 链接顺序:源文件/目标文件在前,库参数在后 $(CXX) $(CXXFLAGS) $(INCS) -o testAll Main_TestAll.cpp $(OBJS) $(LDFLAGS) $(LDLIBS) .cpp.o: # 编译阶段仅做语法检查、生成目标文件,不需要链接参数 $(CXX) $(CXXFLAGS) -c $< -o $@ $(INCS) clean: rm -f testAll *.o ../../src/*.o testAll.xml
验证步骤
- 先执行
make clean清理之前生成的所有旧目标文件 - 执行
make重新编译即可正常生成可执行文件 - 执行
./testAll即可运行测试用例
内容的提问来源于stack exchange,提问作者Angus Comber
相关产品推荐
相关产品推荐

