假设我有一个C ++二进制文件,它是用一个gcc说的4.4.x版本编译的,它在客户端的Linux机器上使用。
如果我想升级我的编译器以使用更新的编译器,比如4.9.3(因为我想使用C ++ 11):
在客户端框上需要升级哪些东西才能运行这个新的二进制文件? (例如.so图书馆) 怎么会发现这个呢?
答案 0 :(得分:1)
我猜你提到GCC 3.4你的客户端系统正在运行RedHat / CentOS / Scientific Linux 4,这个版本太老了,甚至Red Hat ended support for it three years ago。如果您运行的是任何较新的版本,那么您将能够利用Developer Toolsets,其中包含GCC的修改版本,它将标准库的新部分静态链接到您的二进制文件中,以便它可以在旧系统上运行没有更新的glibc / libstdc ++运行时。
答案 1 :(得分:1)
有两种机制可以测试共享库的兼容性:
SONAME
:链接器用于引用库的库的规范名称。您可以使用ldd
命令查询每个ELF对象(可执行文件或库)所需的库列表,并且需要为每个引用的库递归执行此操作以获取所需库的完整列表。
符号版本信息。这是一个额外的约束,允许通过引入每个符号使用的版本要求向现有库添加功能 - 仅使用已存在多年的符号的程序将需要比使用新功能的库的最低版本更低的版本。
为了让程序运行,需要满足这两个目标。
Linux发行版的典型方法是保持 SONAME 到包名称的映射(因为 SONAME 中不同的多个版本可以同时安装),以及一个表引入了包版本的版本符号。适合您的发行版的软件包开发工具应该能够创建符合您的程序要求的依赖项规范列表;如果由于符号未知而未能这样做,则很可能在该版本的发行版中不支持此版本。
答案 2 :(得分:1)
在客户端框上需要升级哪些东西才能运行这个新的二进制文件?
您需要在应用中发送两个共享库:libgcc_s
和libstdc++
。有关详细信息,请参阅https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html。
如果使用$ORIGIN
进行链接,则可以将这些库与可执行文件一起发布到同一目录中。有关详细信息,请参阅https://stackoverflow.com/a/4742034/412080。
怎么会发现这个?
在可执行文件上运行ldd
和readelf -d
以查看他们需要哪些库。
答案 3 :(得分:0)
另一种方法是静态链接除libstdc++
之外的所有库(特别是libc
)(如果您使用的话,还可以libm
和libdl
);然后生成的ELF可执行文件仅依赖于libc
;但是,使用足够古老的内核或libc(在目标机器上)甚至可能无法工作......
有关详细信息,请阅读Drepper的论文:How To Write Shared Libraries