1. 找不到依赖的动态库问题 解决方法:
[stevenrao]$ ldd demo
linux-vdso.so.1 => (0x00007fff7fdc1000)
libtmp.so => not found
这个错误是最常见的错误了。运行程序的时候找不到依赖的so。
1) 一般人使用方法是修改LD_LIBRARY_PATH这个环境变量
export LD_LIBRARY_PATH=/tmp
[stevenrao]$ ./demo
test
这样就OK了, 不过这样export 只对当前shell有效,当另开一个shell时候,又要重新设置。
2) 可以把export LD_LIBRARY_PATH=/tmp 语句写到 ~/.bashrc中,这样就对当前用户有效了,
写到/etc/bashrc中就对所有用户有效了。
3) 前面链接时候使用 -L/tmp/ -ltmp 是一种设置相对路径方法,
4) 还有一种绝对路径链接方法。
[stevenrao]$ g++ -o demo /tmp/libtmp.so main.cpp
[stevenrao]$ ./demo
test
[stevenrao]$ ldd demo
linux-vdso.so.1 => (0x00007fff083ff000)
/tmp/libtmp.so (0x00007f53ed30f000)
绝对路径虽然申请设置环境变量步骤,但是缺陷也是致命的,这个so必须放在绝对路径下,不能放到其他地方,这样给部署带来很大麻烦。所以应该禁止使用绝对路径链接so。
搜索路径分两种,一种是链接时候的搜索路径,一种是运行时期的搜索路径。
像前面提到的 -L/tmp/ 是属于链接时期的搜索路径,即给ld程序提供的编译链接时候寻找动态库路径;
而 LD_LIBRARY_PATH则既属于链接期搜索路径,又属于运行时期的搜索路径。
....................
5) 另外还可以通过配置/etc/ld.so.conf,在其中加入一行
/tmp/
这个配置项也是只对运行期有效,并且是全局用户都生效,需要root权限修改,修改完后需要使用命令ldconfig 将 /etc/ld.so.conf 加载到ld.so.cache中,不需要重启系统就可以立即生效。
除了前面介绍的那些搜索路径外,还有缺省搜索路径/usr/lib/ /lib/ 目录,可以通过-z nodefaultlib编译选项禁止搜索缺省路径。
2. 去除无用的动态库依赖:
先使用 ldd -u demo 查看不需要链接的so
# ldd -u demo
Unused direct dependencies:
/lib64/libz.so.1
/lib64/librt.so.1
/lib64/libm.so.6
/lib64/libgcc_s.so.1
使用 -Wl,--as-needed 编译选项
# g++ -Wl,--as-needed -o demo -lz -lm -lrt main.cpp
# ldd demo
linux-vdso.so.1 => (0x00007fffebfff000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff665c05000)
libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
/lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
# ldd -u demo
Unused direct dependencies: