当前位置:  编程技术>其它
本页文章导读:
    ▪linux下so动态库一些不为人知的秘密2       上一篇(linux下so动态库一些不为人知的秘密(上))介绍了linux下so一些依赖问题,本篇将介绍linux的so路径搜索问题。 我们知道linux链接so有两种途径:显示和隐式。所谓显示就是程序.........
    ▪linux下so动态库一些不为人知的秘密(上) (2012-08-14 22:48)      linux下so动态库一些不为人知的秘密(上) (2012-08-14 22:48) 标签: so linux ldd strace 依赖 分类: c/C++ linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名。二者都使用广泛。本.........
    ▪Linux下合并多个.a库函数 到动态库so      Linux下合并多个.a库函数 到动态库so 在LINUX下用静态库进行链接的时候经常会碰到如下情况:存在与静态库名一样的动态库。以MKL为例,在目录/MKLROOT/lib/em64t下,库libmkl_core.a和库libmkl_core.so同.........

[1]linux下so动态库一些不为人知的秘密2
    来源:    发布时间: 2013-11-15
 上一篇(linux下so动态库一些不为人知的秘密(上))介绍了linux下so一些依赖问题,本篇将介绍linux的so路径搜索问题。

我们知道linux链接so有两种途径:显示和隐式。所谓显示就是程序主动调用dlopen打开相关so;这里需要补充的是,如果使用显示链接,上篇文章讨论的那些问题都不存在。首先,dlopen的so使用ldd是查看不到的。其次,使用dlopen打开的so并不是在进程启动时候加载映射的,而是当进程运行到调用dlopen代码地方才加载该so,也就是说,如果每个进程显示链接a.so;但是如果发布该程序时候忘记附带发布该a.so,程序仍然能够正常启动,甚至如果运行逻辑没有触发运行到调用dlopen函数代码地方。该程序还能正常运行,即使没有a.so.

既然显示加载这么多优点,那么为什么实际生产中很少码农使用它呢, 主要原因还是起使用不是很方便,需要开发人员多写不少代码。所以不被大多数码农使用,还有一个重要原因应该是能提前发现错误,在部署的时候就能发现缺少哪些so,而不是等到实际上限运行的时候才发现缺东少西。

下面举个工作中最常碰到的问题,来引申出本篇内容吧。

写一个最简单的so, tmp.cpp

1. int test()

2. {

3. return 20;

4. }

编译=>链接=》运行, 下面main.cpp 内容请参见上一篇文章。

[stevenrao]$ g++ -fPIC -c tmp.cpp

[stevenrao]$ g++ -shared -o libtmp.so tmp.o

[stevenrao]$ mv libtmp.so /tmp/

[stevenrao]$ g++ -o demo -L/tmp -ltmp main.cpp

[stevenrao]$ ./demo

./demo: error while loading shared libraries: libtmp.so: cannot open shared object file: No such file or directory

[stevenrao]$ ldd demo

linux-vdso.so.1 => (0x00007fff7fdc1000)

libtmp.so => not found

这个错误是最常见的错误了。运行程序的时候找不到依赖的

    
[2]linux下so动态库一些不为人知的秘密(上) (2012-08-14 22:48)
    来源:    发布时间: 2013-11-15
linux下so动态库一些不为人知的秘密(上) (2012-08-14 22:48)
标签: so linux ldd strace 依赖 分类: c/C++


linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名。二者都使用广泛。本文主要讲动态库方面知识。

基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看
  • # ldd /bin/ls
  • linux-vdso.so.1 => (0x00007fff597ff000)
  • libselinux.so.1 => /lib64/libselinux.so.1 (0x00000036c2e00000)
  • librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
  • libcap.so.2 => /lib64/libcap.so.2 (0x00000036c4a00000)
  • libacl.so.1 => /lib64/libacl.so.1 (0x00000036d0600000)
  • libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
  • libdl.so.2 => /lib64/libdl.so.2 (0x00000036c1600000)
  • /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
  • libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
  • libattr.so.1 => /lib64/libattr.so.1 (0x00000036cf600000)
  • 这么多so,是的。使用ldd显示的so,并不是所有so都是需要使用的,下面举个例子
    main.cpp
  • #include <stdio.h>
  • #include <iostream>
  • #include <string>
  • using namespace std;

  • int main ()
  • {
  • cout << "test" << endl;
  • return 0;
  • }
  • 使用缺省参数编译结果
  • # g++ -o demo main.cpp
  • # ldd demo
  • linux-vdso.so.1 => (0x00007fffcd1ff000)
  • libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4d02f69000)
  • libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
  • libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
  • libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
  • /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
  • 如果我链接一些so,但是程序并不
        
    [3]Linux下合并多个.a库函数 到动态库so
        来源:    发布时间: 2013-11-15
    Linux下合并多个.a库函数 到动态库so

    在LINUX下用静态库进行链接的时候经常会碰到如下情况:存在与静态库名一样的动态库。以MKL为例,在目录/MKLROOT/lib/em64t下,库libmkl_core.a和库libmkl_core.so同名。这样的话我们如果在链接时加入链接的库名-lmkl_core,编译器只同动态库libmkl_core.so链接,而屏避掉静态库文件libmkl_core.a。所以静态库文件里的对象文件无法被链接。解决这一问题有两个办法:

    1. 直接将静态库的绝对路径加到编译过程中去:

    gcc -I$(INCLUDE) -L$(LIB) main.c /MKLROOT/lib/em64t/libmkl_core.a -o a.out

    这样的话编译器就会根据指定的文件进行编译链接,不过这种做法在静态库文件少的时候可用,如果文件一多,就会让整个指令冗长,可读性差。下面是一种比较可取的方法。

    2. 在目录/MKLROOT/lib/em64t下用vi编辑器打开一个与所有库文件都不重名的库,例如libmkl.a。然后在该文件中加入下面的一行:

    GROUP (libmkl_*.a libmkl_*.a libmkl_*.a ............... libmkl_*.a)

    (GROUP一定要大写)

    保存退出。之后在编译程序的时候只要将该文件加入链接项就OK了。命令如下:

    gcc -I$(INCLUDE) -L$(LIB) main.c -lmkl -o a.out

    上面的选项(-lmkl)就相当于让编译器gcc到文本文件libmkl.a指定的静态库文件中寻找.o文件进行链接,而不用人工地将每个静态库地址都输进行。查找.o对象文件的顺序从左到右,所以应该将最低层的静态库放到最右边,把需要调用右边库里的对象的库放到左边,否则会出现找不到对象文件,导致报函数没定义的错误。



    tqsheng 2013-01-04 16:54 发表评论

        
    最新技术文章:
     




    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3