冲突的提升版本

时间:2016-04-01 00:09:14

标签: c++ gcc boost dependencies shared-libraries

由于我正在使用的旧版第三方代码,我已使用较旧的GCC ABI(https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)编译了boost::systemboost::serialization

我将它们构建为/usr/local/lib,它已被设置为链接器的有效路径(我也使用其他库),并将它们重命名为:

$ ls /usr/local/lib/libboost_*

/usr/local/lib/libboost_serialization_old_abi.so
/usr/local/lib/libboost_serialization_old_abi.so.1.60.0
/usr/local/lib/libboost_system_old_abi.so
/usr/local/lib/libboost_system_old_abi.so.1.60.0
/usr/local/lib/libboost_wserialization_old_abi.so
/usr/local/lib/libboost_wserialization_old_abi.so.1.60.0

默认情况下,主流提升库照常在/usr/lib下。当我使用自定义标志-lboost_system_old_abi-lboost_serialization_old_abi将任何代码链接到这些特定库时,会产生的二进制文件将链接到默认的boost库

$ ldd darwin_socket

linux-vdso.so.1 (0x00007ffd137ea000)
/usr/local/webots/resources/projects/robots/darwin-op/libraries/darwin/libdarwin.so (0x00007fcb9edaa000)
libipsocket.so.1 => /usr/local/lib/libipsocket.so.1 (0x00007fcb9eb7b000)
libboost_system.so.1.60.0 => /usr/lib/libboost_system.so.1.60.0 (0x00007fcb9e977000)
libboost_serialization.so.1.60.0 => /usr/lib/libboost_serialization.so.1.60.0 (0x00007fcb9e739000)
libController.so => not found
libCppController.so => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fcb9e3b7000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007fcb9e0b2000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fcb9de9c000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fcb9dafb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcb9efc1000)
librt.so.1 => /usr/lib/librt.so.1 (0x00007fcb9d8f3000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fcb9d6d6000)

这很奇怪,因为如果使用原始的-lboost_system-lboost_serialization标志,由于新的/旧的ABI不兼容性,gcc甚至无法链接到默认的提升。

那究竟发生了什么?

1 个答案:

答案 0 :(得分:1)

问题是只重命名自定义构建的库是不够的。库名称作为 soname 嵌入到库中(您可以使用readelf -d命令查看它),并在您的应用程序与库一起使用时使用。基本上,自定义库中的sonames作为依赖项放入应用程序二进制文件中,因为它们与官方Boost库名称相同,所以在运行时加载了错误的二进制文件。

您必须确保在构建过程中正确命名了自定义构建的Boost库。您可以尝试通过向b2命令行添加--buildid=old_abi选项来执行此操作。