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

   
   基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看 
  1. # ldd /bin/ls
  2. linux-vdso.so.1 => (0x00007fff597ff000)
  3. libselinux.so.1 => /lib64/libselinux.so.1 (0x00000036c2e00000)
  4. librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
  5. libcap.so.2 => /lib64/libcap.so.2 (0x00000036c4a00000)
  6. libacl.so.1 => /lib64/libacl.so.1 (0x00000036d0600000)
  7. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
  8. libdl.so.2 => /lib64/libdl.so.2 (0x00000036c1600000)
  9. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
  10. libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
  11. libattr.so.1 => /lib64/libattr.so.1 (0x00000036cf600000)

这么多so,是的。使用ldd显示的so,并不是所有so都是需要使用的,下面举个例子

main.cpp

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <string>
  4. using namespace std;
  5. int main ()
  6. {
  7. cout << "test" << endl;
  8. return 0;
  9. }

使用缺省参数编译结果

  1. # g++ -o demo main.cpp
  2. # ldd demo
  3. linux-vdso.so.1 => (0x00007fffcd1ff000)
  4. libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4d02f69000)
  5. libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
  6. libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
  7. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
  8. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)

如果我链接一些so,但是程序并不用到这些so,又是什么情况呢,下面我加入链接压缩库,数学库,线程库

  1. # g++ -o demo -lz -lm -lrt main.cpp
  2. # ldd demo
  3. linux-vdso.so.1 => (0x00007fff0f7fc000)
  4. libz.so.1 => /lib64/libz.so.1 (0x00000036c2600000)
  5. librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
  6. libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff6ab70d000)
  7. libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
  8. libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
  9. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
  10. libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
  11. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)

看看,虽然没有用到,但是一样有链接进来,那看看程序启动时候有没有去加载它们呢

  1. # strace ./demo
  2. execve("./demo", ["./demo"], [/* 30 vars */]) = 0
  3. ... = 0
  4. open("/lib64/libz.so.1", O_RDONLY) = 3
  5. ...
  6. close(3) = 0
  7. open("/lib64/librt.so.1", O_RDONLY) = 3
  8. ...
  9. close(3) = 0
  10. open("/usr/lib64/libstdc++.so.6", O_RDONLY) = 3
  11. ...
  12. close(3) = 0
  13. open("/lib64/libm.so.6", O_RDONLY) = 3
  14. ...
  15. close(3) = 0
  16. open("/lib64/libgcc_s.so.1", O_RDONLY) = 3
  17. ...
  18. close(3) = 0
  19. open("/lib64/libc.so.6", O_RDONLY) = 3
  20. ...
  21. close(3) = 0
  22. open("/lib64/libpthread.so.0", O_RDONLY) = 3
  23. ...
  24. close(3) = 0
  25. ...

看,有加载,所以必定会影响进程启动速度,所以我们最后不要把无用的so编译进来,这里会有什么影响呢?

   大家知不知道linux从程序(program或对象)变成进程(process或进程),要经过哪些步骤呢,这里如果详细的说,估计要另开一篇文章。简单的说分三步:
    1、fork进程,在内核创建进程相关内核项,加载进程可执行文件;
    2、查找依赖的so,一一加载映射虚拟地址
    3、初始化程序变量。
  可以看到,第二步中dll依赖越多,进程启动越慢,并且发布程序的时候,这些链接但没有使用的so,同样要一起跟着发布,否则进程启动时候,会失败,找不到对应的so。所以我们不能像上面那样,把一些毫无意义的so链接进来,浪费资源。但是开发人员写makefile 一般有没有那么细心,图省事方便,那么有什么好的办法呢。继续看下去,下面会给你解决方法。
  先使用 ldd -u demo 查看不需要链接的so,看下面,一面了然,无用的so全部暴露出来了吧
  1. # ldd -u demo
  2. Unused direct dependencies:
  3. /lib64/libz.so.1
  4. /lib64/librt.so.1
  5. /lib64/libm.so.6
  6. /lib64/libgcc_s.so.1

使用 -Wl,--as-needed 编译选项

  1. # g++ -Wl,--as-needed -o demo -lz -lm -lrt main.cpp
  2. # ldd demo
  3. linux-vdso.so.1 => (0x00007fffebfff000)
  4. libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff665c05000)
  5. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
  6. libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
  7. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
  8. libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
  9. # ldd -u demo
  10. Unused direct dependencies:

呵呵,办法很简单省事吧,本文主要讲so依赖的一些问题,下一篇将介绍so的路径方面一些不为人知的小秘密

linux下so动态库一些不为人知的秘密(上)的更多相关文章

  1. linux下so动态库一些不为人知的秘密(中二)

    继续上一篇< linux下so动态库一些不为人知的秘密(中) >介绍so搜索路径,还有一个类似于-path,叫LD_RUN_PATH环境变量, 它也是把路径编译进可执行文件内,不同的是它只 ...

  2. linux下so动态库一些不为人知的秘密(中)

    上一篇(linux下so动态库一些不为人知的秘密(上))介绍了linux下so一些依赖问题,本篇将介绍linux的so路径搜索问题. 我们知道linux链接so有两种途径:显示和隐式.所谓显示就是程序 ...

  3. linux下so动态库一些不为人知的秘密

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.    基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些 ...

  4. linux下so动态库一些不为人知的秘密(转)

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库, ...

  5. linux下so动态库一些不为人知的秘密 系列

    http://blog.chinaunix.net/uid-27105712-id-3313293.html http://www.cnblogs.com/gulvzhe/archive/2012/0 ...

  6. linux下c++动态库的生成及使用

    文章来源于:http://hi.baidu.com/ablenavy/item/b498901c6826bbf587ad4e33 我的程序是一个类,在网上找了半天,都是c的例子,c++的类封装成静态库 ...

  7. Linux下创建动态库与使用

    参考文章:dll和so文件区别与构成:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html 动态库路径配置- /etc/ld.so. ...

  8. linux下生成动态库和链接动态库

    1.生成动态库 src/test.h #ifndef _TEST_H_HH #define _TEST_H_HH void print(); #endif src/test.cpp #include ...

  9. Linux下设置动态库的方法

    库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的. 一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使 ...

随机推荐

  1. 关于link, visited, hover, active

    LoVe/HAte 如果只是希望点击的时候显示背景色,那么只需要设置 :active,无需设置:hover #navbar:active, #backbtn:active { background-c ...

  2. 基于Keil C的覆盖分析,总结出编程中可能出现的几种不可预知的BUG

    基于Keil C的覆盖分析,总结出编程中可能出现的几种不可预知的BUG,供各位网友参考 1.编译时出现递归警告,我看到很多网友都采用再入属性解决,对于再入函数,Keil C不对它进行覆盖分析,采用模拟 ...

  3. QT字体的设置

    摘要: QT4.7.0在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器中的字号与开发板中的字号一致.作者通过实验进行了一一验证. 介 ...

  4. Java Socket 简单梳理

    Sockets let you send raw streams of bytes back and forth between two computers, giving you fairly lo ...

  5. hdu 4620 Fruit Ninja Extreme

    Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  6. 文档生成工具doxygen+图像生成工具GraphViz

    文档生成工具doxygen+图像生成工具GraphViz 虽然jdk自带的javadoc也很好用,不过使用doxygen+GraphViz 的组合可以生成许多强大的图(类图.协作图.文件包含/被包含图 ...

  7. libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET

    libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...

  8. 使用Canvas实现动画效果 | DKlogs -- 设计 | 生活

    使用Canvas实现动画效果 | DKlogs -- 设计 | 生活 使用Canvas实现动画效果

  9. LR性能测试应用

    上半个月,由于工作和上课两边跑,几乎没有属于自己的时间去做自己想做的事,在没有加班的一天晚上,我突然冲动地跑到图书馆借了一本书<LR性能测试应用>——姜艳. 我总喜欢看那些陈旧的书,因为在 ...

  10. Android 判断文件的类型

    import java.util.HashMap; import java.util.Iterator; /** * 判断文件的类型 */ public class MediaFileUtil { p ...