一个unix发行版上的静态链接是否有效但不是另一个?

时间:2009-02-26 01:59:55

标签: g++ unix

如果我静态链接ubuntu中的可执行文件,那么该可执行文件是否有可能无法在另一个发行版中工作,例如mint os?还是fedora?我知道处理器类型会受到影响,但除此之外还有什么我必须要警惕的吗?对不起,如果这是一个愚蠢的问题。谢谢你的帮助

8 个答案:

答案 0 :(得分:5)

有一些极端情况,但在大多数情况下,你应该与静态链接保持良好状态。浮现在脑海中的是libnss。这个特定的库基本上不可能静态链接,因为它的工作方式(权限,身份验证,安全任务)。只要glibc版本相似,你应该对这个问题没问题。

如果你的程序需要使用内核的微妙功能,比如卷管理器,那么你很可能会让你的程序在发行版之间静态链接,因为内核接口可能会略有改变。

大多数典型的应用程序,即讨论可移植性的有意义的应用程序,如网络服务,gui应用程序,语言工具(如编译器/解释程序),不会出现任何问题。

答案 1 :(得分:3)

如果您静态链接一台计算机上的程序,然后将其移动到系统基本上以相同方式运行的另一台计算机,那么它应该可以正常工作。这是静态链接的重点;该程序没有其他文件 - 它完全是自包含的,所以只要它可以运行,它就会像在它的“主机”系统上一样运行。

这与动态链接形成对比,在动态链接中,程序在运行时包含其他文件(库)的元素。如果将动态链接的程序移动到其所依赖的库不同(或不存在)的另一个系统,则它将无效。

答案 2 :(得分:2)

在大多数情况下,您的可执行文件都可以正常运行。只要您的可执行文件不依赖于任何异常存在以使其正常运行,就不会有问题。 (并且,如果它确实取决于存在的异常情况,那么即使您动态链接,也会遇到相同的问题。)

静态链接通常比动态链接更安全,以实现不同UNIX环境之间的兼容性,只要使用相同的CPU即可。

要使静态链接的二进制文件失败,再次假设使用相同的处理器体系结构,您必须使用a.out二进制格式执行诸如系统上的链接之类的操作,并尝试在运行ELF的系统上执行它,其中如果动态链接版本失败就会失败。

那么为什么人们经常静态链接?有两个原因:

  • 它使可执行文件更大,有时更大,
  • 如果修复了库中的错误,则必须重新链接程序才能访问错误修复程序。如果库中修复了一个严重的安全漏洞,则必须重新链接并重新分发您的exe。

答案 3 :(得分:0)

恰恰相反。无论你有什么机会让二进制文件在发行版甚至操作系统之间工作,静态链接都可以最大化这些机会。静态链接使库中的可执行文件自包含。如果它试图读取另一个系统上没有的文件,它仍然可能出错。

为了获得更好的便携性,请尝试与dietlibc或其他libc联系。 An article at Linux Journal提到了一些候选人。一个更小,更简单的libc不太可能依赖于文件系统中与发行版和发行版不同的东西。

答案 4 :(得分:0)

我会因上述原因避免静态链接某些内容,除非您绝对必须

话虽这么说,它应该适用于同一架构的任何其他类似内核(即如果你在运行linux 2.4.x的机器上静态链接,加载器VDSO将在linux 2.6上不同,VDSO是虚拟动态的共享对象,内核向包含加载程序代码的每个进程公开的共享对象。)

其他陷阱包括/ etc中的内容不在您认为的位置,日志位于不同的位置,系统实用程序不存在或不同(ubuntu使用update-rc.d,RHEL使用chkconfig)等。

有时你别无选择。我正在编写一个程序,与LVM2的基于字符串的cmdlib接口交谈,支持使用execv()..低,不过,我需要支持的30%的发行版没有包含该库,也没有办法获得它。因此,在生成二进制包时,我不得不链接静态对象。

如果您正在使用glibc,您可以确信像getpwnam()和朋友这样的东西仍然可以工作..只需确保观察任何硬编码路径(更好的是,让它们在运行时可配置)

答案 5 :(得分:0)

只要您能保证它只会在类似硬件上的类似版本的操作系统上执行,如果静态链接,您的程序将正常工作。所以,如果你构建一个2.6 Linux和静态链接,你可以在(几乎)所有2.6 Linux发行版上运行。

请注意,您无法静态链接GLIBC的某些部分,因此如果您正在使用它们,则无论如何都必须动态链接。从内存中,名字服务东西(nss)部分在我调查它时需要动态链接。

您无法静态链接(例如)Linux的程序,然后期望它在BSD或Windows上运行。 BSD和Unix不像Linux那样呈现或处理它们的系统调用。我说一个轻微的谎言,因为BSD有一个可以启用的Linux仿真层,但开箱即用它不会起作用。

答案 6 :(得分:0)

不,它不会起作用。用于分发独立性的静态链接是旧的unix时代的概念,不推荐使用。事实上,无论如何,你都无法使用尽可能多的库作为静态库。

遵循Linux Standard Base方式,这是您获得尽可能多的交叉分发可移植性的唯一机会。

如果您为FreeBSD和Solaris编程,LSB也可以正常工作。

答案 7 :(得分:0)

这里有两个兼容性问题:库版本和库存。

您没有说明您正在使用的库。

如果没有'-l'选项,那么唯一的'库'就是glibc本身,它作为内核的接口。 Glibc版本向上兼容。如果您在glibc 2.x系统上链接,则可以在glibc 2.y上运行,对于y> X。开发商对此做出了坚定的承诺。

如果你有-l选项,静态链接总是安全的。如果是动态链接,则必须确保(1)目标系统上存在库,并且(2)具有兼容版本。您的里程可能会改变目标发行版是否具备您所需的内容。