linux - g++在处理.a文件和.o文件时的区别?
巴扎黑
巴扎黑 2017-04-17 15:33:41
0
1
449

简单的说,就是

g++ A.o B.o C.o -o a.out

ar rv libpack.a A.o B.o g++ C.o libpack.a -o a.out

或者

ar rv libpack.a A.o B.o g++ C.o -o a.out -lpack

有什么区别,对最终的行为有什么影响?
我只知道.a就是多个.o打个包,然后加个索引之类,但是在输送给g++的时候,有什么影响?

下面是背景,有点长:

使用google test框架写单元测试。
使用的方案是将具体的test 和 所有的test的单一入口main分开。
也就是:

  • main.cpp:

#include "gtest/gtest.h" int main(int argc, char* argv[]){ testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
  • testxxx.cpp,有好多个

#include "testedClass.h" #include "gtest/gtest.h" TEST(xxx, yyy){ ... } ...

按照正常流程,将每个cpp编译为对象文件*.o,然后全部link起来就可以得到一个可执行文件,运行之后,执行各种test,然后pass,没什么问题。

main.cpp显然是通过gtest.h得知其他各种test的存在,然后调用。也就是TEST语句等于是在gtest中注册了一个回调。

============ 异常出现 ===============
现在换了一种方法
将各种testxxx.o打包成libtest.a
然后

g++ main.o libtest.a -o test

当然还有许多链接库,先省略吧。

结果就是,程序链接成功,但是运行之后,gtest直接认为没有注册的test,直接pass返回。也就是和没写test一样。

为了验证是不是打包的时候丢失了信息,特地还将.a重新解开,然后链接。这样操作就没有任何问题了,挨个test,然后pass。

================================
所以说,到底是哪里出问题了,还是google test本身实现的缺陷。
各位大侠给小弟解个惑吧!!

巴扎黑
巴扎黑

모든 응답 (1)
洪涛

问题已经解决了。
链接器在处理.a文件的时候,会自动忽略那些没有被引用的项,以保证链接结果中没有太多无用的代码
而在处理.o文件的时候,则是你给它什么就链接什么

gtest的使用并没有使用显式的引用,因此会被链接器忽略。gtest具体是如何找到测试用例的就不清楚了,需要看源代码吧。

对这个问题的解决方案有两种:

  • 一开始就不要生成.a

  • .a解开,用一堆.o代替

  • 在链接TEST的.a时,用这个选项-Wl,--whole-archive libtest.a,它可以强制引入libtest.a中的所有符号

    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿
    회사 소개 부인 성명 Sitemap
    PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!