linux gcc 把静态链接库.a链接到动态链接库.so里

时间:2022-01-03 15:50:39

        最近公司的项目中突然出现了这样一个需求,我简化再概括后如下:有两大模块,其中一个模块a最终编译出一个可执行文件exec_a,另一个模块b编译出一个动态链接库lib_b.so被模块a的程序exec_a所链接。现在模块b中分出一个小模块c,需要独立成一个项目,它最终生成一个东西,提供给模块b,最后链接成动态库lib_b.so。因为c将会编译出多个.o目标文件,如果提供这些.o给b去链接是没问题的,但是这样来说很不人性化。把b和c两个库同时提供给a去链接,也能解决,但是偏偏a不希望知道和见到c。

        于是,我的做法如下,把c编译出一个静态库lib_c.a,提供lib_c.a给b去链接,所以就有了一个动态链接库链接静态库的问题了。这个平时用得不多,记录一下,在链接动态库b时,链接命令如下(默认大家都懂gcc和Makefile啊):

    $(CC) -shared -o lib_b.so $^ -Wl,--whole-archive -L. -lc -Wl,--no-whole-archive

        从上面这句编译命令看来就是多了
    -Wl,--whole-archive
       和
    -Wl,--no-whole-archive
        -Wl 都知道是把参数传递给链接器,而--whole-archive就是可以把在这个参数之后的静态库中的函数和变量输出到动态库中,而--no-whole-archive则是关掉这个功能。

        否则如果只是单纯地链接一个.a到.so中的话,这个动态库是不会有任何静态库中的内容的,最后链接到可执行文件时,也会出现找不到静态库中的内容。

        还有值得注意的就是,我习惯了每次编译后的release版本都strip一下,如果直接对刚刚编译出来的静态库strip操作的话,这个静态库就啥都没有了,因为它的东西没被任何东西所使用,所以全部被去掉了。之前因为这个问题折腾了半天还以为仍然是没有把这个静态库导到动态库去。

        本文到此结束!