1. 静态库和动态库的基本概念
静 态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分;使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生成 的可执行文件较大。动态库,是在可执行程序启动时加载到执行程序中,可以被多个可执行程序共享使用。使用动态库编译生成的程序相对较小,但运行时需要库文 件支持,如果机器里没有这些库文件就不能运行。
2. 如何使用动态库
如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。 linux 的可执行程序在执行的时候默认是先搜索 /lib 和 /usr/lib 这两个目录,然后按照 /etc/ld.so.conf 里面的配置搜索绝对路径。同时, Linux 也提供了环境变量 LD_LIBRARY_PATH 供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如: 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 环境变量查找。
3 .库的链接时路径和运行时路径
现代连接器在处理动态库时将链接时路径( 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 )、 LD_LIBRARY_PATH 指定查找路径。
小问题:
1 .编译时的 -L 选项是否影响 程序执行时库的路径 ?
举一个实例:
当前文件夹结构如下:
test.c tools/
tool 下有 tool.c tool.h my_err.h 以及由此生成的 libtool.so
tool 下编译生成库文件
gcc -Wall -g -shared -o tool.so tool.c
在当前文件夹引用:
gcc -Wall -g –o test.c -Ltools -ltool
编译不报错,但是运行加载的时候就出现 cannot open shared object file 。
如果将该库文件拷贝到 /usr/lib 下就没有错误,正常运行。
说明 -L 只是指定了程序编译连接时库 的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库。
转载自:http://blogold.chinaunix.net/u2/60011/showart_1007920.html