除了一些使用g ++之外,如何静态链接所有库?

时间:2011-05-28 09:06:17

标签: c++ g++ dynamic-linking static-linking

我要求我静态链接所有库,包括libstdc ++,libc,pthread等。有一个omniorb库我想动态链接。

目前我已动态链接所有库。 ldd显示以下内容

linux-vdso.so.1 =>  (0x00007fff251ff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f291cc47000)
libomniDynamic4.so.1 (0x00007f291c842000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f291c536000)
libm.so.6 => /lib64/libm.so.6 (0x00007f291c2e0000)
libgomp.so.1 => /usr/lib64/libgomp.so.1 (0x00007f291c0d7000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f291bebf000)
libc.so.6 => /lib64/libc.so.6 (0x00007f291bb66000)
/lib64/ld-linux-x86-64.so.2 (0x00007f291ce63000)
librt.so.1 => /lib64/librt.so.1 (0x00007f291b95d000)
libomniORB4.so.1 (0x00007f291b6aa000)
libomnithread.so.3 (0x00007f291cf35000

我需要ldd将libomniDynamic4.so.1显示为唯一的动态链接库。

我如何实现这一目标?

4 个答案:

答案 0 :(得分:10)

试图制作一个在所有发行版上运行的linux可执行文件呃?祝你好运......但我离题了......

您想查看g ++的-v标志输出。它显示了由g ++ / ld执行的内部链接命令。具体来说,您需要检查最终链接命令collect2及其所有参数。然后,您可以指定要链接的.a库的确切路径。您还必须跟踪所有内容的静态库。我的libstdc ++。a在/usr/lib/gcc/x86_64-linux-gnu/4.4/libstdc++.a

rant on:我对linux最大的抱怨是可执行文件的破碎状态。为什么我不能在一台机器上编译二进制文件并将其复制到另一台机器上并运行它!即使Ubuntu发行版中的一个版本也将产生二进制文件,由于libc / libstdc ++ ABI incompatibilites

而无法在另一个上运行

编辑#1 我只想添加The script on this page produces a .png of an executables .so dependencies.在尝试按照您的描述进行操作时,此非常非常有用。

请注意ldd <exename>将列出链中的所有依赖项,而不仅仅是可执行文件的直接依赖项。所以,即使你的可执行文件只依赖于omniorb.so,但是omniorb.so依赖于libphread.so,ldd的输出会列出那个。查找readelf的联机帮助页以仅查找二进制文件的直接依赖项。

要注意的另一个项目。如果omniorb.so依赖于libstdc ++。那么,你将别无选择,只能依赖于同一个lib。否则,ABI不兼容性将破坏您的代码和omniorb代码之间的RTTI。

答案 1 :(得分:6)

  

我需要ldd将libomniDynamic4.so.1显示为唯一的动态链接库。

不可能

首先,对于需要动态链接的任何(ldd)二进制文件,ld-linux-x86-64.so.2始终显示x86_64。如果您使用动态关联(与libomniDynamic4.so.1一起使用),则获得ld-linux-x86-64.so.2

其次,内核将linux-vdso.so.1“注入”到您的进程中。你不能摆脱它。

接下来,问题是为什么您希望最小化动态库的使用。最常见的原因通常是错误地认为“大多数静态”二进制文件更具可移植性,并且可以在更多系统上运行。在Linux上,这与真实相反。

如果实际上您正在尝试实现可移植的二进制文件,则存在多种方法。迄今为止最好的(根据我的经验)是使用apgcc

答案 2 :(得分:0)

构建一个可以在许多Linux发行版上运行的二进制文件非常困难,并且静态链接不是重点。

请注意,使用较早的glibc版本(即较旧的Linux发行版)构建的二进制文件也可以在较新的Linux发行版上运行。之所以可行,是因为glibc是向后兼容的。

获得预期结果的一种可能方法是:

  • 在旧的Linux操作系统上编译二进制文件

  • 使用命令ldd或lsof查找已编译二进制文件的所有必需库 (运行时)在二进制文件上,详细信息here

  • 在“ custom-lib ”文件夹中复制旧Linux操作系统所需的库

  • 总是使用二进制文件捆绑/发布此 custom-lib 文件夹

  • 创建一个bash脚本,将 custom-lib 文件夹放在LD_LIBRARY_PATH环境变量的文件夹列表顶部,然后调用您的二进制文件。

    < / li>

通过这种方式,通过使用bash脚本执行二进制文件,我能够在具有非常不同Linux版本的各种嵌入式设备上执行二进制文件。 但是总是有问题的情况失败了。

请注意,我始终使用cli应用程序/二进制文件对此进行了测试。

其他可能的方式。

似乎也有精巧的方法来编译与glibc-back兼容的二进制文件,例如this似乎在编译与较旧的ABI兼容的二进制文件。但是我还没有检查这条路线。

答案 3 :(得分:-4)

链接时,在指定要静态链接的库之前使用-static,并在要动态链接的库之前使用-dynamic。您最终应该看到如下命令行:

g++ <other options here> -dynamic -lomniDynamic4 -static -lpthread -lm -lgomp <etc>

当然,您需要。静态链接的库的版本(duh)。