完全静态构建具有所有依赖项(libgcc等)的应用程序

Fully statically build application with all dependencies (libgcc, etc.)?

本文关键字:libgcc 应用程序 依赖 静态 构建      更新时间:2023-10-16

我目前正在尝试将所有应用程序的依赖项编译为静态库。我的动机:

  1. 不要依赖任何操作系统提供的库来获得完全可复制的代码库
  2. 避免在其他系统上部署时由动态链接引起的问题
  3. 链接到不同版本的库时避免运行时冲突
  4. 能够针对其他操作系统进行交叉编译

然而,正如我最初担心的那样,我必须很快进入兔子洞。我目前被OpenCV卡住了,我相信还会有更多。然而,我的主要问题是:

  1. 是否可以构建一个完全静态构建的应用程序(例如libc、ligcc等)
  2. 是否可以静态链接所有库,但动态链接主要组件(libgcc等)
  3. 如果没有,是否可以针对静态构建的库(例如OpenCV)进行链接,但通过动态链接(zlib、libc等)来满足它们的依赖关系
  4. 我在互联网上做了研究,但找不到一本全面的指南来详细介绍链接的内部内容(静态与动态)。你知道一本好书/教程吗?一本关于gcc的书能让我更进一步吗
  5. 这是一个非常愚蠢的想法吗

我的动机:

  1. 不要依赖任何操作系统提供的库来获得完全可复制的代码库

  2. 避免在其他系统上部署时由动态链接引起的问题

  3. 当链接到不同版本的库时,避免运行时冲突

  4. 能够为其他操作系统进行交叉编译

你的动机都是错误的。

对于#1,您不需要完全静态的二进制文件。您只需要使用GNU链接器提供的--sysroot功能链接到一组版本控制的库

对于#2,你的动机被误导了。

在Linux上,如果目标系统上安装的libc与程序构建所基于的(静态)libc不同,则完全静态的二进制文件可能会以神秘的方式崩溃。也就是说,Linux上的完全静态二进制文件(与流行的观点相反)的可移植性明显低于动态链接的二进制文件。应该简单地永远不要在Linux上静态链接libc.a。

仅此一点就应该使您放弃这种方法(至少对于任何基于GLIBC的系统)。

对于#3,不要链接到不同版本的库(在程序构建时),也不会导致冲突。

对于#4,与#1相同的解决方案同样有效。