构建动态库所用的目标文件都必须是位置无关的,因此编译动态库的源文件的时候都会加-fPIC. 如果构建这个动态库需要通过链接外部的静态库,而外部的静态库不是用-fPIC编译的,那么就会链接失败。为了调试这类问题,需要知道怎么判断一个静态库,更具体的是静态库内的目标文件,是不是用-fPIC构建的。
在Bing问了一下,找到一个stackoverflow[1]链接,里面说可以用 readelf --relocs 查看,它的方法是找 PLT, GOT, JUMP_SLOT 这些字符串。然而不用 -fPIC 构建的静态库也会有 R_X86_64_PLT32 这样的重定位,似乎这方法不太行。另外可以用 nm 找 _GLOBAL_OFFSET_TABLE_, 似乎也有同样的问题。
之后我点进这个问题的一个相关问题[2],然后想明白是怎么回事了。这个方法也是用 readelf --relocs, 但是它找某些不符合位置无关这个性质的重定位,即 R_X86_64_32 等。
找到了 R_X86_64_32 或者 R_X86_64_32S 就表明不是用 -fPIC 构建了。同时我也明白链接时报的错误信息是什么意思了,其实就是说遇到了不满足位置无关的重定位。
(后来我查到了为什么我构建某个动态库链接失败,原因是构建一个外部静态库的时候虽然加了-fPIC,但后来又被覆盖了。)
[1] https://stackoverflow.com/questions/1340...n-built-wi
[2] https://unix.stackexchange.com/questions...ndent-code
在Bing问了一下,找到一个stackoverflow[1]链接,里面说可以用 readelf --relocs 查看,它的方法是找 PLT, GOT, JUMP_SLOT 这些字符串。然而不用 -fPIC 构建的静态库也会有 R_X86_64_PLT32 这样的重定位,似乎这方法不太行。另外可以用 nm 找 _GLOBAL_OFFSET_TABLE_, 似乎也有同样的问题。
之后我点进这个问题的一个相关问题[2],然后想明白是怎么回事了。这个方法也是用 readelf --relocs, 但是它找某些不符合位置无关这个性质的重定位,即 R_X86_64_32 等。
代码:
readelf --relocs /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.a |\
awk '$3~/^R_/ && $5!~/^\.debug/{print $3}' |sort -u
找到了 R_X86_64_32 或者 R_X86_64_32S 就表明不是用 -fPIC 构建了。同时我也明白链接时报的错误信息是什么意思了,其实就是说遇到了不满足位置无关的重定位。
(后来我查到了为什么我构建某个动态库链接失败,原因是构建一个外部静态库的时候虽然加了-fPIC,但后来又被覆盖了。)
[1] https://stackoverflow.com/questions/1340...n-built-wi
[2] https://unix.stackexchange.com/questions...ndent-code