为了避免项目布署麻烦,需要将执行文件尽量静态链接

1. boost库全部静态链接

2. c++库静态链接

1,2点的改变如下,强制链静态库的方法为参数下为-l:libXXXX.a; 对于boost log, 需要将宏-DBOOST_LOG_DYN_LINK去掉

LOCAL_STATICLIBS := boost_log boost_log_setup boost_system boost_filesystem boost_serialization  boost_thread boost_chrono
#LOCAL_LIBS := boost_system boost_serialization boost_log pthread boost_thread boost_chrono boost_log_setup ibverbs
LOCAL_LIBS :=  pthread ibverbs
LOCAL_LINKFLAGS := -static-libgcc -static-libstdc++ $(LIBDIRS:%=-L%) $(OUT_DIR:%=-L%) $(LOCAL_LIBS:%=-l%) $(LOCAL_STATICLIBS:%=-l:lib%.a)

3. 但是对于动态库编译报错,需要将boost 带上参数-fPIC重新编译,原因见下转载

sudo ./bjam cxxflags=-fPIC cflags=-fPIC -a -d+2
sudo ./bjam install

4. 用strip去掉一些符号信息

https://blog.csdn.net/stpeace/article/details/47090255

5. so由于静态链接会引用许多不该出现的导出符号,编译参数中带-fvisibility=hidden已经失效

使用--version-script参数

$ gcc -shared -o libtest.so a.C -fPIC -Wl,--version-script=exportmap

OPENCL_1.0
{global:_init;_fini;clGetPlatformIDs;clGetPlatformInfo;clGetDeviceIDs;local:*;
};

========================分割线==========================

转:https://blog.csdn.net/edwardlulinux/article/details/56812636

最近自己的项目中遇到一个问题:

编译一个动态库,动态库中使用了静态库的函数如下图所述

问题来了怎么编译最终得到一个带有静态链接的动态库libxxx.so?

生成静态库libxxx1

  gcc -o xxx1.o -c xxx1.c

         ar -r xxx1.o libxxx1.a

生成静态库libxxx2

 gcc -o xxx2.o -c xxx2.c

         ar -r xxx2.o libxxx2.a

生成静态库libxxx3

 gcc -o xxx3.o -c xxx3.c

         ar -r xxx3.o libxxx3.a

生成动态库libxxx.so

gcc -o libdynamic.so dynamic.o -shared -fPIC -L. -lxxx1 -lxxx2 -lxxx3

gcc报错:
       ibxxx.a xxx.o:relocation against '.rodata' can not be used when making a shared object;recomplie with -fPIC

于是网上看了一篇文章解决方案是把静态库编译的过程加上了-fPIC和-shared选项。然后进行编译和链接再生成动态库被程序所使用。最为关键的一些变化为:回到以上静态库生成指令中

        gcc -o xxx1.o -fPIC -shared -c xxx1.c

        gcc -o xxx2.o -fPIC -shared -c xxx2.c

        gcc -o xxx3.o -fPIC -shared -c xxx3.c

这样一来不禁要问:既然是静态库,加上了这两选项编译出来的结果到底是动态库还是静态库?那原本的问题岂不是变为动态库链接动态库了?

之后结合个人调试和总结看看有没有其他方法可以解决此类问题(动态库调用静态库中的函数)

1,静态库被其他程序调用,编译结果为把静态库的函数“拷贝”到目标程序中。

2,而动态库这没有相关的“拷贝”动作。只是做了一个链接,程序运行时会自动的到默认路径下搜索动态库,并且调用执行。

明确以上两个概念之后再来看看实际的情况

代码转自:

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

 
  1. #include

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

  3. void print_niuzai_said()

  4. {

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

  6. }

  7. #include

  8. #include "static.h"

  9. void print_papa_said()

  10. {

  11. print_niuzai_said();

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

  13. }

  14. #include

  15. #include "dynamic.h"

  16. int main(int argc, char** argv)

  17. {

  18. print_papa_said();

  19. return 0;

  20. }

  21. emptyempty

以上代码中很清楚的可以看到如下实时。生成一个动态库,这个动态库依中的函数实现依赖于一个静态库。满足要分析的应用场景。那么为什么按照博客中描述的方法操作gcc,但是结果和我预期的有出入呢?

问题在于两点:

第一点:使用 -fPIC -shared 两个选项编译了静态库,这个库还是静态属性吗?假设一个静态库已经被其他软件和工程广泛使用了,现在修改了这个静态库属性后是不是会影响其他的软件?

第二点:为什么不能编译出我们预期效果的动态库?

看看博客中的操作:

gcc -o static.o -c static.c

ar -r libstatic.a static.o
        gcc -o dynamic.o -c dynamic.c

做个静态库libstatic.a,然后只编译dynamic.c不链接。

接着使用

gcc -o libdynamic.so -shared -fPIC -L. -lstatic dynamic.o

生成一个名为libdynamic.so动态库。

一切准备就绪,要用测试软件测试了

gcc main.c -L. -ldynamic -o main
        ./libdynamic.so: undefined reference to `print_niuzai_said' collect2: ld returned 1 exit status

链接错误

我们分析一下原因:

使用命令 nm 查看可执行程序的符号和函数等

nm libdynamic.so

00001f18 a _DYNAMIC
        00001ff4 a _GLOBAL_OFFSET_TABLE_w _Jv_RegisterClasses
        00001f08 d __CTOR_END__
        00001f04 d __CTOR_LIST__
        00001f10 d __DTOR_END__
        00001f0c d __DTOR_LIST__
        00000558 r __FRAME_END__
        00001f14 d __JCR_END__
        00001f14 d __JCR_LIST__
        0000200c A __bss_start w __cxa_finalize@@GLIBC_2.1.3
        000004d0 t __do_global_ctors_aux
        000003f0 t __do_global_dtors_aux
        00002008 d __dso_handle w __gmon_start__
        000004a7 t __i686.get_pc_thunk.bx
        0000200c A _edata
        00002014 A _end
        00000508 T _fini
        00000388 T _init
        0000200c b completed.7021
        00002010 b dtor_idx.7023
        00000470 t frame_dummy
            U print_niuzai_said
        000004ac T print_papa_said
            U puts@@GLIBC_2.0

这个U 后面的函数正是静态库中想要使用的函数,前面这个U 表示:该符号在当前文件中是未定义的,即该符号的定义在别的文件中。

看来这个动态库名字是对的,但是内容还不全。怎么办?修改gcc命令如下:

gcc -o libdynamic1.so -shared -fPIC dynamic.o -L. -lstatic

这条命令是告诉gcc先要把dynamic.o这个编译后未链接的文件中没有定义的符号链接先处理掉,也就是把U开始的函数先链接。随后再把这个未连接的文件作为动态库来处理,最后生成一个动态库。

有了动态库libdynamic1.so,再使用nm看看输出结果:

00001f18 a _DYNAMIC
       00001ff4 a _GLOBAL_OFFSET_TABLE_w _Jv_RegisterClasses
       00001f08 d __CTOR_END__
       00001f04 d __CTOR_LIST__
       00001f10 d __DTOR_END__
       00001f0c d __DTOR_LIST__
       000005e4 r __FRAME_END__
       00001f14 d __JCR_END__
       00001f14 d __JCR_LIST__
       00002010 A __bss_start w __cxa_finalize@@GLIBC_2.1.3
       00000520 t __do_global_ctors_aux
       00000430 t __do_global_dtors_aux
       00002008 d __dso_handle w __gmon_start__
       000004e7 t __i686.get_pc_thunk.bx
       00002010 A _edata
       00002018 A _end
       00000558 T _fini
       000003c8 T _init
       00002010 b completed.7021
       00002014 b dtor_idx.7023
       000004b0 t frame_dummy
       00000508 T print_niuzai_said
       000004ec T print_papa_said
           U puts@@GLIBC_2.0
       0000200c D sz_static

这下这个函数变为 属性变为T了,T的含义是:该符号位于代码区text section。

使用命令:gcc main.c -L. -ldynamic1 -o main

执行main后一切都有了,静态库中的函数信息最后是动态库中的信息。

总结:

gcc使用的时候带有参数,这些参数的先后顺序直接导致了编译的结果。特别是在做库文件的过程中,有时候看似编译没有报错,但是运行时候就会有问题。这些问题多数出现在链接阶段。

文中有不足之处请大家指点,谢谢

动态库链接boost静态库相关推荐

  1. x64 编译 静态链接_C++静态库与动态库

    这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一本书<程序员的自 ...

  2. Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明

    本文描述的是windows系统下,通过qtcreator在pro文件中添加动态库与静态库的方法: 1.添加动态库(直接添加动态库文件.dll,非子项目) 通过qtcreator创建动态库的方法就不在此 ...

  3. 【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )

    文章目录 I . 导入 z 库 ( FFMPEG 动态库 与 静态库区别 ) II . FFMPEG 库引入顺序 III . Android Studio 中 FFMPEG 静态库引入完整 CMake ...

  4. Visual studio那些破事。。。(生成静态库、生成动态库、引用静态库、引用动态库)

    共4个小步骤,每个小步骤你都可以新建个VS解决方案,自己跟着步骤跑一下,windows怎么[生成静态库.生成动态库.引用静态库.引用动态库]你就基本明白了@! 文章目录 1.导出静态库.lib(add ...

  5. go语言调用c 的头文件 so,Golang生成共享库(shared library)以及Golang生成C可调用的动态库.so和静态库.a...

    Golang类似于C的静态语言,效率也接近于C,如果Golang也可以导出可供C调用的库,那可以和很多高级语言say goodbye了,goodbye似乎又有点武断,但至少说,Golang可以做很多事 ...

  6. Visual Studio引入外部库 ---- 弄懂静态库lib和动态库dll

    这两天由于想要研究一下socket的相关内容,但是没想到引入外部库还有这么多门道. 根据维基百科定义:一个现代编译器的主要工作流程如下:源代码(source code)→ 预处理器(preproces ...

  7. Linux下动态库(.so)和静态库(.a)

     linux下有两种库:动态库和静态库(共享库) 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大. 动态库(共享库)的代码在可执行程序运行时才 ...

  8. Linux下动态库(.so)和静态库(.a) 的区别

    linux下有两种库:动态库和静态库(共享库) 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大. 动态库(共享库)的代码在可执行程序运行时才载入内 ...

  9. Ubuntu中动态库.so和静态库.a介绍

    Ubuntu中.so和.a后缀的文件介绍 ( 今天在编译某个开源代码的时候遇到glog库的链接问题,由于对.so和.a动态库和静态库不够明白,于是学习了一波) 转自:http://www.cnblog ...

最新文章

  1. 关于C和C++的一点观点
  2. MVC下HtmlHelper自带BeginForm表单提交与异步Ajax请求
  3. yii2 RESTful api的详细使用
  4. JDK5--Annotation学习:基础(二)
  5. 关于DubboMain启动的真相
  6. arduino定时器函数如何使用_excel如何使用函数公式来查找图片
  7. 您的WebApp真的需要jQuery吗?
  8. ABBYY FineReader 12PDF选项卡之图像及文字设置
  9. sdk linux 离线安装方法,Android SDK离线安装方法详解(加速安装)
  10. C++新特性探究(八):初始化列表(Initialization List)再探究
  11. C语言常用8种排序方法耗时测试
  12. 科学道德与学风-2021雨课堂答案-第1章
  13. c语言malloc(c语言malloc头文件)
  14. 超简单漂浮广告代码、网页漂浮广告代码、jQuery漂浮广告、div漂浮层
  15. 中尺度海洋涡流对热带气旋强度影响的调查
  16. 高仿富途牛牛-组件化-界面美化
  17. 机器学习 --- 概率图 - 表示 - 动态模型
  18. 日子大不了就是有粥喝粥,有菜吃菜
  19. 微信网址遮罩引导法升级版,微信自动跳转默认浏览器打开HTML
  20. Tableau各版本更新情况

热门文章

  1. conhosts 占用CPU
  2. 当你收到面试通知后,通过如下的准备可以大大提升面试成功率
  3. ITE平台开发 chapter4 - https通信
  4. php建站: 2019年最好用的6个php环境搭建工具推荐
  5. 【空间规划符号库】国土空间规划_制图规范+制图样式
  6. 国际:程序员V.S.编程语言:你上“贼船”了吗?
  7. 03-盒子模型与元素显示类型
  8. 89c52流水灯汇编语言,89c52单片机流水灯汇编程序
  9. 计算机flash ram是什么意思,ROM、RAM、CPU、CACHE、FLASH的区别
  10. 量子计算机 最先进国家,中国获得量子霸权,玻色取样取得重大成功,成为当今量子技术最先进的国家。...