查看某个程序使用了那些动态库,使用ldd命令查看
ldd /bin/ls
这么多so,是的。使用ldd显示的so,并不是所有so都是需要使用的,下面举个例子
main.cpp
#include#include #include using namespace std; int main () { cout << "test" << endl; return 0; }
使用缺省参数编译结果
g++ -o demo main.cpp ldd demo
如果我链接一些so,但是程序并不用到这些so,又是什么情况呢,下面我加入链接压缩库,数学库,线程库
g++ -o demo -lz -lm -lrt main.cpp ldd demo
虽然没有用到,但是一样有链接进来,那看看程序启动时候有没有去加载它们呢
strace ./demo
有加载,所以必定会影响进程启动速度,所以我们最后不要把无用的so编译进来,这里会有什么影响呢?
大家知不知道linux从程序(program或对象)变成进程(process或进程),要经过哪些步骤呢,这里如果详细的说,估计要另开一篇文章。简单的说分三步:
1、fork进程,在内核创建进程相关内核项,加载进程可执行文件;
2、查找依赖的so,一一加载映射虚拟地址
3、初始化程序变量。
可以看到,第二步中dll依赖越多,进程启动越慢,并且发布程序的时候,这些链接但没有使用的so,同样要一起跟着发布,否则进程启动时候,会失败,找不到对应的so。所以我们不能像上面那样,把一些毫无意义的so链接进来,浪费资源
先使用 ldd -u demo 查看不需要链接的so
ldd -u demo
使用 -Wl,–as-needed 编译选项
g++ -Wl,--as-needed -o demo -lz -lm -lrt main.cpp ldd demo
ldd -u demo Unused direct dependencies:
如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LDLIBRARYPATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其他系统启动后即可执行到的脚本添加如下语句:LDLIBRARYPATH =/work/lib:$(LDLIBRARYPATH)。并且LDLIBRARYPATH路径优先于系统默认路径之前查找(详细参考《使用LDLIBRARYPATH》)。
不过LDLIBRARYPATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LDLIBRARYPATH的缺陷和使用准则,可以参考《Why LDLIBRARYPATH is bad》 )。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LDLIBRARYPATH环境变量查找。



