美文网首页C/C++ || 编译、链接、执行 || docker
【转载】 动态库(.so)链接静态库(.a)的情况总结

【转载】 动态库(.so)链接静态库(.a)的情况总结

作者: dopami | 来源:发表于2018-04-11 20:49 被阅读12次

https://blog.csdn.net/lichen18848950451/article/details/59489343

来自:http://www.cnblogs.com/nobugtodebug/archive/2012/11/07/e6cd72c67b3dd843f40d7ce919f7336a.html

动态库(.so)链接静态库(.a)的情况总结 

一般来说在链接时想要使用静态库有三种方法:

1、link时加上 -static 选项;当加上 -static选项后,gcc会把所有用到的库都做静态连接。

2、link时直接指定想要静态连接的.a文件的绝对路径。优点是除非.a文件不存在,否则肯定有效;缺点也是很明显,拿到其他机器上编译时,.a文件也必须在相同的路径下存放。

3、在要静态连接的库前指定-Bstatic ,在要动态连接的库前指定-Bdynamic选项。连接器在看到-Bstatic时会优于去找静态库,如果找不到再去找动态库。 -Bdynamic也是同样的情况。(可是我实验的结果是这两个选项根本不起作用,我的环境是centos 6.2 gcc4.7.2, 仔细看了gcc 文档,这两个选项是针对VxWorks平台的,所以不起作用。)

当我们要编译一个so提供给外部使用,这个so本身依赖一些第三方库。但是我们却希望so的使用者不用关心该so对其他库的依赖。很自然的是会想到在编译so的时候把依赖到的第三方库静态链接进来。

我在这样做的时候碰到了问题:指定-static选项时,link失败,错误提示说要用到的object文件应该用-fPIC选项重新编译才行(也就是说,只有用-fPIC选项编译的object文件能被link到.so里);当直接给出.a的绝对路径的时候link成功,但是.so里却并没有直正包含所用到的符合连接。针对碰到的问题,我做了一些实验。实验如下:

static.c

#include

const char* sz_static = "i'm a static str.";

void print_niuzai_said()

{

printf("in static lib, niu zai said, i'm happy!\n");

}

dynamic.c

#include

#include "static.h"

void print_papa_said()

{

print_niuzai_said();

printf("in dynamic lib, papa said, niu zai is wonderful!\n");

}

main.c

#include

#include "dynamic.h"

int main(int argc, char** argv)

{

print_papa_said();

return 0;

}

分别用两组命令编译出了两个.a 文件

1、gcc -o static.o -c static.c

      ar -r libstatic.a static.o

2、gcc -o static_shared.o -shared -fPIC -c static.c

      ar -r libstatic_shared.a static_shared.o

然后用此命令  "gcc -o dynamic.o -c dynamic.c"  编译出dynamic.o文件

接下来就是本文的主题了,链接生成libdynamic.so.此时有这么几种情况:

1、使用 "gcc -o libdynamic.so -shared -fPIC -L. -lstatic dynamic.o ",连接成功,但.so里实际上没有static.o里的内容。

2、使用"gcc -o libdynamic.so dynamic.o -shared -fPIC -L. -lstatic",连接失败

3、使用 "gcc -o libdynamic.so -shared -fPIC -L. -lstatic_shared dynamic.o",连接成功,但.so里实际上没有static.o里还是没有的内容。

4、使用 "gcc -o libdynamic.so dynamic.o -shared -fPIC -L. -lstatic_shared",连接成功,.a的内容被连接到了.so里面。

另外,链接静态生成可执行程序时,静态库是不是用 "-shared -fPIC" 选项编译产生的没有影响。都能正常生成可执行程序。

综合以上情况,总结如下:

1、动态连接库中用到的object文件必须是用 "-shared -fPIC"选项编译产生的,否则连接时要么报错,要么被忽略。

2、静态库中的object文件最好也用"-shared -fPIC"选项编译,这样静态库就可以同时被连接到.so 或者可执行性文件中。

3、动态库只能连接用"-shared -fPIC"选项编译出来的静态库(和第1点是同一件事)

4、连接选项的顺序对连接器的行为有重要影响!

静态库使用-shared -fPIC连接命令连接执行结果动态库结果最终结果

否gcc -o libdynamic.so -shared -fPIC -L. -lstatic dynamic.o成功静态库内容没有被连接失败

否gcc -o libdynamic.so dynamic.o -shared -fPIC -L. -lstatic失败 失败

是gcc -o libdynamic.so -shared -fPIC -L. -lstatic_shared dynamic.o成功静态库内容没有被连接失败

是gcc -o libdynamic.so dynamic.o -shared -fPIC -L. -lstatic_shared成功静态库内容被连接成功

相关文章

  • 【转载】 动态库(.so)链接静态库(.a)的情况总结

    https://blog.csdn.net/lichen18848950451/article/details/5...

  • Linux链接库

    动态链接库(共享链接库) 杂项 生成.o文件 生成.so 使用动态库 静态链接库 杂项 生成.a 查看.a 使用静态库

  • linux下静态库和动态库创建和使用

    linux静态库 .a ===== win 静态库 .lib linux动态库 .so ==== win动态库 ....

  • 2.动态库和静态库

    1.库分类:库一般分为两种:静态库(.a 、.lib)动态库(.so 、.dll )所谓静态、动态是指链接过程。2...

  • 常用的gcc选项

    调试相关 警告相关 改变隐藏的链接行为 链接静态库 or 链接动态库 so相关选项 exe相关选项

  • 动态链接库和静态链接库

    动态库和静态库 在Win下,动态库以.dll结尾,静态库以.lib结尾。 在Linux下,动态库文件以.so结尾,...

  • linux下静态库 动态库和 gcc gdb Makefile

    一、静态库和动态库 定义 根据链接时期的不同,库有静态库和动态库之分。 静态库是在链接阶段被链接的,所以生成的可执...

  • 静态库和动态库

    静态库:.a 和 .framework动态库:.tbd(.dylib) 和 .framework静态库:链接时会...

  • iOS静态库及动态库

    2018-06-19 浅析静态库链接原理编译原理以及什么是静态库和动态库 转之: iOS 静态库和动态库(库详解)...

  • MT MD 讲解

    (114条消息) 静态库、动态库、静态链接、动态链接、系统运行库混合、MD MT默认库冲突问题wxlfreewin...

网友评论

    本文标题:【转载】 动态库(.so)链接静态库(.a)的情况总结

    本文链接:https://www.haomeiwen.com/subject/nqazhftx.html