动态链接库的深入理解。
Linux下面共享库默认路径是/usr/lib. /usr/local/lib. /lib。
一般的ELF格式的可执行文件可以通过readelf --d xxx。来获得共享库和程序运行时的库的路径和信息。
1、把我写好的动态库放到系统目录里。缺点:1a、系统目录被搞的很混乱。1b、在别人电脑上部署会很麻烦。
2、指定LD_LIBRARY_PATH环境变量。缺点:不能直接启动应用程序而需要外部shell启动。
3 、今天,我了解到,gcc在链接的时候有个rpath选项。它可以把动态库的路径直接写到elf文件中去。这样可以将rpath写成相对路径。方便部署。
程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。Linux的可执行程序在执行的时候默认是先搜索/lib和/usr /lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH 供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其 他系统启动后即可执行到的脚本添加如下语句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路径优先于系统默认路径之前查找(详细参考《使用 LD_LIBRARY_PATH》)。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调 试。(LD_LIBRARY_PATH的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》 )。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路 径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
运行时的库可以通过rpath或者-R来指定,编译连接时可用-L/lib/... 和la来指定。
现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。比如我们做嵌入式 移植时#arm-Linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉编译好的zlib库),将target编译好后我们只要把zlib库拷贝到开发板的系统默认路径下即可。或者通过- rpath(或-R )。