首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在为Linux创建可发行的二进制文件时,静态链接libstdc++和/或libgcc是一个很好的实践吗?

在为Linux创建可发行的二进制文件时,静态链接libstdc++和/或libgcc是一个很好的实践吗?
EN

Software Engineering用户
提问于 2019-01-08 09:54:08
回答 2查看 7.4K关注 0票数 7

上下文:我有一个使用JNI的开源项目。虽然可以自己构建JAR,但我预计大多数用户都会使用标准Java工具(如Maven、Gradle或SBT )下载JAR,其中包含预编译的二进制映像。这在Windows上没有问题,但在Linux上就变得复杂了。

我想知道在创建这些包时需要静态链接多少,这样它就可以与大多数Linux发行版兼容。例如,我知道Alpine没有附带libstdc++,这意味着它在一个小的码头容器中会失败。

也有可能出现旧版本。例如,快速查看一下nm就会发现它正在链接_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21__vsnprintf_chk@@GLIBC_2.3.4。如果主机的版本大于3.4.21和2.3.4,该怎么办?

然而,我看过的大多数文献都告诉我不链接到libgcc。那还是真的吗?如果我切换到clang (它有自己的标准库),它也是一样的吗?

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2019-01-09 06:30:48

静态链接glibc是一个不-不.我的理解是,这通常是为发行版定制的,所以您不希望将其分发给运行不同linux发行版/发行版的机器。有插入的替代它,您可以静态链接,如MUSL。我从来没有试过,所以这方面的其他问题由读者来决定。静态连接其他一切都应该是好的。

我非常成功地使用的一种方法是在旧Linux版本上构建二进制文件(包括在可能的地方执行静态链接)。这些二进制文件将是向前兼容的。因此,您应该能够得到一些保证,您的二进制代码将运行在过去十年的大多数发行版上(尽管正如您所指出的那样,阿尔卑斯是不同的-它使用的是MUSL -所以您可能需要建立在阿尔卑斯的基础上,以确保兼容性)。从技术上讲,您可以使用现代版本来针对较早的glibc版本进行兼容性,但我发现仅仅使用旧版本更简单。

票数 8
EN

Software Engineering用户

发布于 2019-01-08 13:55:51

一般来说,要成为一个好的系统公民,您将希望尽可能多地依赖于系统库,并避免静态链接任何库。您的代码应该只具有源代码级的依赖性,而不是依赖于特定的ABI。由于您的项目是一个开放源码项目,如果您只是让进行打包的人重新编译您的应用程序与目标系统上的任何可用的系统库,您应该是好的。这会产生一个对系统来说尽可能小的精益应用程序,并且提高了整个系统安全性,因为当用户静态链接到同一个具有安全漏洞的库时,他们将不必单独修补20个不同的程序。

如果您的项目是封闭的源代码软件,这将是更棘手的,因为您将不得不重新编译每个系统自己,因为软件包可能无法重新编译您的应用程序。

此外,您还可以尝试提供一个与所有依赖项静态链接的通用应用程序,这是为了允许使用尚未打包应用程序的发行版的用户运行应用程序,而不必重新编译自己。在提供静态链接程序时,您有两种选择:尝试静态链接所有东西,除了您所支持的目标系统中可用的少数库(这是一个噩梦),或者您可以将应用程序打包为快照或平板。我认为后者是提供通用应用程序的最简单方法。

在为Linux创建可发行的二进制文件时,静态链接libstdc++和/或libgcc是一个很好的实践吗?

您必须查看您计划支持的目标系统。如果您计划支持可能没有预装libstdc++的最小发行版,则应该静态地链接它们。否则,你不需要这样做,它们只会使你的应用程序膨胀,这些基本的系统库被设计成具有非常稳定的ABI,甚至跨越不同的发行版;除非有一些预防措施,如果它们在系统上可用,您几乎可以确保您的应用程序在系统安装的任何版本下都能正常运行。

如果计划静态链接应用程序,请考虑使用设计为静态链接的libc,例如musl。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/385127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档