Library — 函数库
No.1:
静态库:
这类库的名字一般是libxxx.a,xxx为库的名字。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。
No.2:
动态库:
这类库的名字一般是libxxx.M.N.so
,同样的xxx为库的名字,M是库的主版本号,N是库的副版本号。当然也可以不要版本号,但名字必须有。相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。linux系统有几个重要的目录存放相应的函数库,如/lib、/usr/lib。
No.3:
静态库与动态库的区别
- 当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。
- 然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。
- 由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
No.4:
动态库搜索路径的设置方式
- 在环境变量 LD_LIBRARY_PATH 中设置
- 在 /etc/ld.so.conf 文件中设置,并执行 /sbin/ldconfig 命令,详见下面的
ldconfig命令
。
No.5:
常见故障处理
- 在运行某个程序时,如果看到提示:“Incompatible library version.”
- 则表明需要将该库升级到程序所需要的版本。库是向下兼容的,也就是说,用老版本库编译的程序可以在新安装的版本库上运行,反之则不行。
Library的操作命令
No.1:
ldconfig命令
-
名称:
/sbin/ldconfig 配置动态连接器(ld)运行时邦定 -
描述:
- ldconfig为命令行中指定、/etc/ld.so.config文件(默认)中指定的目录、及一些可信任的目录(如/usr/lib, /lib)中的最新的动态库创建动态连接器
/lib/ld-linux.so.2
所需要的连接和绶存文件/etc/ld.so.cache(默认) - 即ldconfig将 /etc/ld.so.conf的数据读入高速缓存中,同时在 /etc/ld.so.cache文件中记录数据
- 这些绶存起来的数据会被动态连接器
ld.so
或ld-linux.so
所使用。ldconfig会检查它所遇到的动态库文件的名称与版本号,以决定那些动态库的连接要进行更新。 - 通常由特权用户运行
ldconfig
,可能需要对一些根拥有的目录和文件的写入权限。 - 相关文件
- /lib/ld.so.2或/lib/ld-linux.so.2:动态连接器
- /etc/ld.so.conf:library文件目录列表(一行一个),可自定义添加Library文件目录
- /etc/ld.so.cache:包含了在/etc/ld.so.conf中指定的目录中查找到所有连接库。
- ldconfig为命令行中指定、/etc/ld.so.config文件(默认)中指定的目录、及一些可信任的目录(如/usr/lib, /lib)中的最新的动态库创建动态连接器
-
参数
# ldconfig --help 用法: ldconfig [选项...] 设置运行时期动态连接 -c, --format=FORMAT 采用的格式:新、旧或兼容(默认) -C CACHE 将 CACHE 用作缓冲区文件 -f CONF 将 CONF 用作配置文件 -i, --ignore-aux-cache 忽略辅助缓存文件 -l 手工连接独立的库。 -n 只在命令行中给出了进程目录。未创建缓冲区。 -N 不要创建缓冲区 -p, --print-cache 打印缓冲区 -r ROOT 进入 ROOT 目录并将其作为根目录 -v, --verbose 生成详细消息 -X Don't update symbolic links -?, --help 给出此帮助列表 --usage 给出简要的用法信息 -V, --version 打印程序版本号 长选项的强制或可选参数对对应的短选项也是强制或可选的。
-
使用注意事项
- 往/lib和/usr/lib目录加入文件,是不用修改/etc/ld.so.conf的,但是要执行下ldconfig,不然会有这个library会找不到的情况
- 想从其他目录加载library时,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会有找不到Library的情况
- 想从其他目录加载library,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西),可以使用export一个全局变量
LD_LIBRARY_PATH
,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案。 - ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
- 最好是有任何关于library的变动,最好都ldconfig一下,可以避免一些意想不到的结果,反正也不费事。
-
实践演示
# cp /opt/nw/lib/libnw.so /lib/ # ldconfig -p|grep libnw.so # cat /etc/ld.so.cache |grep libnw.so # ldconfig # ldconfig -p|grep libnw.so libnw.so (libc6,x86-64) => /lib/libnw.so # cat /etc/ld.so.cache |grep libnw.so Binary file (standard input) matches
-
ldconfig提示“is not asymbolic link”的解决方法
- 在执行ldconfig的时候会出现以下错误:
ldconfig: /lib/libdb-4.7.so is not a symbolic link
- 这是因为正常情况下libdb-4.7.so是一个符号连接,而不是一个实体文件,因此只需要把它改成符号连接即可
mv libdb-4.7.so libdb-4.so.7
ln -s libdb-4.so.7 libdb-4.7.so
- 在执行ldconfig的时候会出现以下错误:
No.2:
ldd命令
-
名称
ldd - 显示可执行程序对共享库的依赖情况 -
语法
ldd [-vVdr] program ...
-
OPTIONS
$ ldd --help 用法:ldd [选项]… 文件… --help 印出这份说明然后离开 --version 印出版本信息然后离开 -d, --data-relocs 进程数据重寻址 -r, --function-relocs 进程数据和函数重寻址 -u, --unused 印出未使用的直接依赖关系 -v, --verbose 印出所有信息
-
program
程序,指定可执行程序
-
其他介绍
- 首先ldd不是一个可执行程序,而只是一个shell脚本
- ldd显示可执行模块的dependency的工作原理,其实质是通过ld-linux.so来实现的。
- 实际上可以直接执行ld-linux.so模块,如:/lib/ld-linux.so.2 --list program(这相当于ldd program)
-
实践
$ ldd /bin/ls linux-vdso.so.1 (0x00007ffea3155000) libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fef6c4d1000) libc.so.6 => /usr/local/lib/libc.so.6 (0x00007fef6c132000) libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fef6bebf000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fef6bcbb000) /lib64/ld-linux-x86-64.so.2 (0x00007fef6c91a000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fef6ba9e000)
《Linux运维之Library》文章由 执笔写快乐 发布在行动派博客,未经授权禁止转载。