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

时间:2017-10-31 19:35:52

标签: c++ linker static-linking dynamic-linking libgcc

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

  1. 不依赖于任何操作系统提供的库,以便拥有完全可重现的代码库
  2. 在动态链接导致的其他系统上部署时避免出现问题
  3. 在链接库的不同版本时避免运行时冲突
  4. 能够交叉编译其他操作系统
  5. 然而,正如我最初害怕的那样,我必须非常快地走下兔子洞。我目前仍然坚持使用OpenCV,我相信还有更多。但是,我的主要问题是:

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

1 个答案:

答案 0 :(得分:3)

  

我的动机:

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

  2.   
  3. 在动态链接导致的其他系统上部署时避免出现问题

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

  6.   
  7. 能够交叉编译其他操作系统

  8.   

你的动机都错了

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

对于#2,你的动机是错误的。

在Linux上,如果安装在目标系统上的libc与构建程序的(静态)libc不同,则完全静态的二进制文件可能会以神秘的方式崩溃。也就是说,Linux上的全静态二进制文件(与普遍看法相比)显着 less 可移植,而不是动态链接的。一个人应该只是永远不会在Linux上静态链接libc.a。

仅这一点就会让你放弃这种方法(至少对于任何基于GLIBC的系统而言)。

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

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