在工作中遇到一次,项目更新一个sdk的后,发现另一个没有改动的sdk提供的功能无法生效了。仔细排查后,发现是因为升级后的sdk包含了与另一个已有sdk同名的库(大概率内部一些接口也是一致的),猜测这里出了问题。遂对链接器的一些实现产生了好奇,做了一个简单的实验,这里记录一下。
对链接器的一些疑问
- 从经验看,
CMakeLists文件只是简单的使用target_link_libraries之类的接口添加一个project需要链接的库,却没有任何地方指明了更进一步的链接细节,比如某个class A需要到具体的a.lib里面去寻找定义。那么势必导致两个结果:lib的名字不影响具体的链接。如果一个project同时链接了a.lib和b.lib,那么交换ab的名字,不应该影响链接结果(这里以交换文件名距离,是因为需要保证改名后的lib仍然是可以被定位到的。直接把a.lib改成a1.lib可能会找不到)- 符号是通过遍历库来查找的。因为并没有任何一个统一的表,注明了各个待链接的库包含了哪些符号,那么链接想想查找某个符号的时候,唯一可行的办法只有通过遍历各个库,查看是否有声明的符号。
- 在上一条的背景下,如果多个库里含有相同的符号,那具体链接器会怎么做,其实是不一定的了(取决于链接器的实现)。下面这个实验就验证了这一点。
代码
目录结构
src
├── CMakeLists.txt
├── main.cpp
├── mylib1
| ├── CMakeLists.txt
| ├── test.cpp
├── mylib2
| ├── CMakeList

本文记录了一次因SDK更新引发的库冲突问题,引发了对链接器工作原理的探讨。通过实验发现,链接器按指定顺序遍历库文件查找符号,选择最先遇到的实现,而不是所有相同符号的合并。这解释了库交换顺序导致的不同链接结果,并证实了链接器未记录库中符号的细节。
最低0.47元/天 解锁文章
4149

被折叠的 条评论
为什么被折叠?



