7

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

  1. 不依赖任何操作系统提供的库以获得完美可重现的代码库
  2. 避免在其他系统上部署时由动态链接引起的问题
  3. 链接不同版本的库时避免运行时冲突
  4. 能够为其他操作系统交叉编译

然而,正如我最初担心的那样,我不得不很快地进入兔子洞。我目前坚持使用 OpenCV,我相信还有更多。但是,我的主要问题是:

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

1 回答 1

5

我的动机:

  1. 不依赖任何操作系统提供的库以获得完美可重现的代码库

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

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

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

你的动机全错了

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

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

在 Linux 上,如果安装在目标系统上的 libc 与构建程序的(静态)libc 不同,则完全静态的二进制文件可能会以神秘的方式崩溃。也就是说,Linux 上的完全静态二进制文件(与流行的看法相反)比动态链接的二进制文件的可移植性要低得多。永远不要在 Linux 上静态链接libc.a。

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

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

对于#4,与#1 相同的解决方案就可以了。

于 2017-11-01T03:50:03.783 回答