可执行文件的静态链接和动态链接
静态链接会将需要的库函数在编译时一并包含, 所以体积会比较大.
使用ldd命令查看可执行文件链接的库
$ ldd /sbin/ldconfig not a dynamic executable $ ldd /bin/ln linux-vdso.so.1 => (0x00007fff4dbcd000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbcb3b39000) /lib64/ld-linux-x86-64.so.2 (0x0000558d79c26000)
如果是静态链接的, 会显示"not a dynamic executable", 如果是动态链接的, 会显示链接的对象, 有3种类型
linux-vdso.so.1
这是虚拟动态共享对象Linux Virtual Dynamic Shared Object
libc.so.6
这是一个链接, 指向/lib64/libc.so.6 或 /lib/i386-linux-gnu/libc.so.6. 这将便于系统升级后, 可执行文件不需要更改直接使用
/lib64/ld-linux-x86-64.so.2
库文件的绝对路径
虚拟动态共享对象 Linux Virtual Dynamic Shared Objects
在早期的x86处理器中, 用户程序与监护服务通过软件中断进行通信. 在处理器速度提升后, 这就成为一个瓶颈, 从Pentium® II处理器开始, 引入了一个Fast System Call方式用于加速系统调用, 使用SYSENTER and SYSEXIT指令取代了中断. 你看到的linux-vdso.so.1是一个虚拟库, 又称虚拟动态共享对象, 会存在于每个程序的地址空间, 在一些发行版中叫linux-gate.so.1, 这个虚拟库提供了用户程序访问系统方法的最快途径, 可能是中断, 对于新处理器, 也可能是Fast System Call
动态加载
从上面可以看到, /lib/ld-linux.so.2 和/lib64/ld-linux-x86-64.so.2 看起来是动态链接库, 但其实都是可执行文件, 它们主要是负责动态加载: 从可执行文件读取头部信息(Executable and Linking Format (ELF) 格式). 从这个信息, 可以知道需要哪些链接库, 哪些需要加载, 然后动态地将可执行文件以及加载的链接库中的地址指针链向正确的地址.
使用ld-linux同样可以查看ldd信息, 注意: 每次ld-linux, 以及每次ldd查看到的地址都可能会变化
/lib64/ld-linux-x86-64.so.2 --list /bin/ln linux-vdso.so.1 => (0x00007ffc8eb34000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4756f36000) /lib64/ld-linux-x86-64.so.2 (0x0000556f8d784000)
动态链接库配置
动态加载是如何知道在哪里查找链接库呢? 主要是通过 /etc/ld.so.conf 和 /etc/ld.so.cache. 通过 /etc/ld.so.conf 可以看到实际加载的链接库. ldconfig命令用于处理ld.so.conf及其关联的所有配置, 从可信任的路径(/lib, /usr/lib)以及命令行中指定的路径中包含的库文件. ldconfig会在/etc/ld.so.cache中记录必要的链接和缓存, 如果修改了ld.so.conf, 需要执行ldconfig来重建/etc/ld.so.cache
一般不带参数执行ldconfig命令会重建ld.so.cache. 可以带上-p参数用于重建时显示ld.so.cache的内容
加载指定的库文件
如果运行的应用需要一个旧版本的动态链接库或者一个更新的动态链接库, 你就会需要指定库文件路径以覆盖默认的查找路径. 在一些使用特定版本库文件的产品中也存在这种情况. 你可以使用LD_LIBRARY_PATH来指定一系列的路径(用冒号分隔), 这些路径会优先于ld.so.cache中设定的路径, 例如
export LD_LIBRARY_PATH=/usr/lib/oldstuff:/opt/IBM/AgentController/lib
编译安装Libevent-2.1.8的安装完成提示
Libraries have been installed in: /opt/lib/libevent/lib If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the '-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the 'LD_RUN_PATH' environment variable during linking - use the '-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to '/etc/ld.so.conf' See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages.
CFLAGS="-Idir1 -Idir2 -Idir3" LDFLAGS="-Ldira -Ldirb -Ldirb"