C/C++程序编译与链接(五) 定位库文件
创始人
2025-06-01 03:00:54

文章目录

    • 在构建过程中定位库
      • 静态库的命名规则
      • 动态库的命名规则
      • 运行时动态库的定位规则
        • `LD_LIBRARY_PATH`
        • ld.so.cache

定位库文件包括两个方面:

  • 在程序构建时,需要知道所依赖库的位置及头文件。
  • 在程序运行时,需要知道所依赖库的位置,只针对动态库。

只有动态库在程序运行时加载,静态库是构建时就已经链接到程序中。

在构建过程中定位库

静态库的命名规则

lib + library name +.a

library name才是静态库实际的名字,比如libtest.a,库名为test

动态库的命名规则

lib + library name + .so + library version information

动态库相比静态库多了库的版本信息,指定了版本信息后,库名一样版本不同也是不同的库,因为包含的符号不同。经常遇见依赖多个不同版本的动态,版本号是区分这些库的重要方式。
库的实际名字也是library name
在构建时不管是依赖的静态库还是动态库,指定所依赖的库的路径都是一致的,通过通过-L-l选项来指定构建过程中库文件的路径。
gcc main.o -L../lib -ltestlib -o test
-L是指定库的目录,-l是指定库名就是库的实际名字,-ltestlib对应的库为libtestlib.so或libtestlib.a

  • -L告诉编译器用于定位库的目录。
  • -l 对于动态库,指定的库名还会写入最终生成的执行文件,在程序运行时,加载器会查找指定的库,但是定位库的规则就不是按-L的规则了。

-l后面也可以跟路径+库名的方式,比如:
gcc main.o -l/home/test/lib/libtestlib.so -o test
但是这种方式,-l后面的内容会全部写入执行文件,在程序运行时,加载器会按照固定的位置/home/test/lib/libtestlib.so加载动态库。如果编译机与运行机不一样,那么就会因为找不到库而运行失败。

运行时动态库的定位规则

按照优先级的如下规则:

  1. LD_LIBRARY_PATH
  2. ld.so.cache
  3. 默认库路径(/lib/和/usr/lib等)

动态库的定位,还有更高优先级的rpathrunpath,这两个值会被写入动态库或执行程序ELF文件。但是这个两个配置的决策过程比较复杂,并且还面临着gcc版本不同处理方式不同的问题。所以这里没有列出它们。通常我们使用LD_LIBRARY_PATHldconfig就足以。

LD_LIBRARY_PATH

设置环境变量LD_LIBRARY_PATH是我们在开发过程中经常使用的方式,但这并不是标准方式,通常临时验证下程序的正确性,可以配置该环境变量,如下:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库目录

ld.so.cache

ld.so.cache是加载器(ld.sold-linux.so)的定位库目录的缓存文件。可以通过ldconfig工具更新它。
一种标准的代码部署过程是基于ldconfig工具,它通常是包安装过程中的最后一步,通常需要将指向包含库目录的路径作为出输入参数传递,将其写入ld.so.cache文件,保证加载器能定位到所依赖的库。

ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib).

ldconfig会搜索指定的目录,/etc/ld.so.conf,系统库默认目录/lib/usr/lib。将其中库的路径信息写入/etc/ld.so.cach,它被链接器(ld.sold-linux.so)用于查找依赖库。

ldconfig还有一个重要的功能是更新动态库的版本,这个会在后面的文件详细介绍。

所以当我们需要定位我们自己的所依赖的库时,可以将目录直接写入/etc/ld.so.conf中,但是/etc/ld.so.conf通常是如下内容:

cat /etc/ld.so.conf
include ld.so.conf.d/*.conf

**include ld.so.conf.d/*.conf**表示包含了**/etc/ld.so.conf.d/**目录下所有文件,所以我们通常是在该目录下建立一个包含所依赖库目录的conf文件。

#ls -lrt /etc/ld.so.conf.d/
-rw-r--r-- 1 root root 19 8月   9 2019 dyninst-x86_64.conf
-rw-r--r-- 1 root root 17 4月   3 2020 mariadb-x86_64.conf
-rw-r--r-- 1 root root 26 6月   1 2020 bind-export-x86_64.conf
-r--r--r-- 1 root root 63 8月  26 2020 kernel-3.10.0-1127.19.1.el7.x86_64.conf
#ldconfig

再通过ldconfig让其更新目录到/etc/ld.so.cach文件中,可以通过ldconfig -p查看cach中缓存的动态库及其路径信息,确认是否已经写入(ldconfig -p | grep 依赖的动态库)。

相关内容

热门资讯

在这部纪录片里,一起去海南环岛... 2025年,海南自贸港全岛封关运作步入倒计时,这座被海风与阳光浸润的海岛,正以开放包容的姿态,向世界...
东南亚出游热潮持续升温,宁波直... 潮新闻客户端 通讯员 张家其 陈燕 天气转冷,南下东南亚的出游热潮持续升温,宁波栎社国际机场飞往万象...
“三水环抱”生态城吸引游客打卡 “三水环抱”生态城吸引游客打卡 12月15日,在武汉市长江新区谌家矶片区麓洲生态城,游客乐享冬日...
“700万是里程碑,更是新起点... (来源:中国旅游报) 转自:中国旅游报 □ 本报记者 李 凤 11月22日9时,九寨沟景区迎来年度...
年轻人饮酒洞察报告 增长与热度 Z世代饮酒参与率两年间从66%升至73%,已成酒类消费最大增量来源。社交媒体同步升温:2...