[英]How do I find what libraries need to be installed on a client linux machine if I compile a binary with a newer version of gcc?
Say I have a C++ binary that was compiled with a version of gcc say 4.4.x, which is used on a client linux box. 假设我有一个C ++二进制文件,它是用一个gcc说4.4.x版本编译的,它用在客户端linux盒子上。
If I want to upgrade my compiler to use a newer one, say 4.9.3 (because I want to use C++11): 如果我想升级我的编译器以使用更新的编译器,比如4.9.3(因为我想使用C ++ 11):
What kind of things would need to be upgraded on the client box to run this new binary? 在客户端框上需要升级什么样的东西来运行这个新的二进制文件? (eg .so libraries) And how would one find this out? (例如.so图书馆)怎么会发现这个?
I'm guessing from the fact that you mention GCC 3.4 that your client system is running RedHat/CentOS/Scientific Linux 4 which is so old that even Red Hat ended support for it three years ago . 我猜你提到GCC 3.4你的客户端系统运行的是RedHat / CentOS / Scientific Linux 4,这个版本太旧了,甚至Red Hat三年前也终止了对它的支持 。 If you were running any newer version then you would have been able to take advantage of the Developer Toolsets which include a modified version of GCC that statically links newer parts of the standard library into your binary so that it can run on legacy systems without newer glibc/libstdc++ runtimes. 如果您运行的是任何较新的版本,那么您将能够利用包含GCC修改版本的开发人员工具集 ,该版本将标准库的新部分静态链接到您的二进制文件中,以便它可以在没有更新glibc的旧系统上运行/ libstdc ++运行时。
There are two mechanisms to test compatibility of shared libraries: 有两种机制可以测试共享库的兼容性:
The SONAME
: a canonical name for the library that is used by the linker to reference the library. SONAME
:链接器用于引用库的库的规范名称。 You can query the list of required libraries for every ELF object (executable or library) with the ldd
command, and you need to do this recursively for each referenced library to get a full list of libraries needed. 您可以使用ldd
命令查询每个ELF对象(可执行文件或库)所需的库列表,并且需要为每个引用的库递归执行此操作以获取所需库的完整列表。
The symbol version information. 符号版本信息。 This is an additional constraint that allows adding functionality to existing libraries by introducing version requirements per symbol used -- a program only using symbols that have existed for ages will require a lower minimum version of the library than one that uses new functionality. 这是一个额外的约束,允许通过引入每个符号使用的版本要求向现有库添加功能 - 仅使用已存在多年的符号的程序将需要比使用新功能的库的最低版本更低的库。
Both of these need to be fulfilled in order for the program to run. 为了使程序运行,需要满足这两个要求。
The typical approach of Linux distributions is to keep a mapping of SONAME to package name (as multiple versions differing in SONAME can be installed concurrently), and a table of versioned symbols to the package revision these were introduced. Linux发行版的典型方法是保持SONAME到包名称的映射(因为可以同时安装SONAME中不同的多个版本),并且引入了包修订版本的版本化符号表。 The appropriate package development tools for your distribution should be able to create a list of dependency specifications that matches your program's requirements; 适合您的发行版的软件包开发工具应该能够创建符合您的程序要求的依赖项规范列表; if they fail to do so because symbols are unknown, it is likely that this version cannot be supported on that release of the distribution. 如果由于符号未知而未能这样做,则很可能在该版本的发行版中不支持此版本。
What kind of things would need to be upgraded on the client box to run this new binary? 在客户端框上需要升级什么样的东西来运行这个新的二进制文件?
You will need to ship two shared libraries with your application: libgcc_s
and libstdc++
. 您需要在应用程序中提供两个共享库: libgcc_s
和libstdc++
。 See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more details. 有关详细信息,请参阅https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html 。
You can ship these libraries in the same directory with your executables if you link using $ORIGIN
. 如果使用$ORIGIN
链接,则可以将这些库与可执行文件一起发布到同一目录中。 See https://stackoverflow.com/a/4742034/412080 for more details. 有关详细信息,请参阅https://stackoverflow.com/a/4742034/412080 。
And how would one find this out? 怎么会发现这个?
Run ldd
and readelf -d
on your executables to see what libraries they need. 在可执行文件上运行ldd
和readelf -d
以查看它们需要哪些库。
An alternative could be to link statically all libraries (notably libstdc++
) other than the libc
(and libm
and libdl
if you use them); 另一种方法是静态链接除libc
之外的所有库(特别是libstdc++
)(如果你使用它们,还可以链接libm
和libdl
); then the produced ELF executable depends only of the libc
; 然后生成的ELF可执行文件仅依赖于libc
; however, with ancient enough kernels or libc (on the target machine) even that might fail to work... 然而,有足够古老的内核或libc(在目标机器上)甚至可能无法工作......
For details, read Drepper's paper: How To Write Shared Libraries 有关详细信息,请阅读Drepper的论文: 如何编写共享库
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.