• gcc全静态链接


    昨天看一篇关于libco的博文,里面提到了一个由于全静态链接导致的bug。全静态链接?以前没有接触过这个概念,特意到网上搜了下,原来是一个程序将其依赖的所有动态库都替换成对应静态库,即使是libc.so,libm.so,libstdc++.so这种系统级别的动态库。全静态链接出来的可执行程序,不依赖任何动态库,拷贝到任何一台机器,只需要操作系统,这个程序就可以run起来。

    这种全静态链接的方式,肯定有好有坏。
    • 第一,缺点:浪费了磁盘空间。全静态链接出来的可执行程序要比动态链接的大。但目前磁盘普遍够大,这个缺点基本可以忽略。
    • 第二,缺点:浪费了内存空间。我们知道相同的动态库在内存中只存在一份,被多个程序共享。而静态库,是需要全部加载到内存的。所以多多少少要浪费一些内存空间。目前来看,内存仍然是服务器中宝贵的资源,能省一些肯定划算。
    • 第三,优点:屏蔽了动态库的版本差异。由于静态链接把所有依赖的函数,全部打包进可执行程序,不依赖于特定机器的动态库函数版本。所有分布式部署的程序,其行为一致。

    那全静态链接如何优雅的实现呢?gcc为我们提供了(-static)、(-Wl,-Bstatic)、(-Wl,-Bdynamic),这么几个选项。

    第一种用法:使用-static选项,将全部动态库都用静态库替换。
    这里有个基于boost库的程序,我们使用普通动态链接的方式编译出来,看看可执行程序的依赖关系。
    由上图可见,可执行程序依赖于libboost_thread.so.1.72.0、libpthread.so.0、libstdc++.so.6、libc.so.6等等动态库。我们再用-static编译这个程序,再看看可执行程序的依赖关系。
    由上图可见,加入-static选项以后,链接器将动态库全部换成了静态库。

    第二种用法:使用-Wl,-Bstatic,-Wl,-Bdynamic选项,将部分动态库设置为静态链接。
    gcc使用-Wl将参数传递给连接器。链接器使用-Bdynamic强制连接动态库,-Bstatic强制连接静态库。所以部分静态,部分动态连接这么写:
    gcc -Wl,-Bstatic -l<static-lib> -Wl,-Bdynamic -l<dynamic-lib>
    
    我们还是使用上面的boost.cpp作为例子,本次编译我们将libboost_thread.so.1.72.0用作静态编译,其他系统动态库,任然以动态库的方式进行连接。
    由上图可见,libboost_thread.so.1.72.0已经是静态链接,而其他系统库,任然是动态链接。

    参考1:https://www.zhihu.com/question/22940048/answer/222625910
    参考2:https://www.jianshu.com/p/3f1ec6748655
  • 相关阅读:
    编译内核时出现drivers/mfd/mxchdmicore.c:36:24: fatal error: mach/clock.h: No such file or directory
    IE中iframe标签显示在DIV之上的问题解决方案
    Linux驱动学习1.hello world;
    Maven安装与配置(转)
    Jmeter阶梯式压测
    Jmeter的分布式测试
    adb connect命令连接多个Android设备
    Linux当中文件的显示命令
    软件测试流程
    测试时间不够,该怎么办?
  • 原文地址:https://www.cnblogs.com/motadou/p/4471088.html
Copyright © 2020-2023  润新知