Linux下的库相关工具:nm、ar、ldd、ldconfig、readelf等

1. locate :查找文件位置

2. nm : 显示二进制目标文件的符号表

语法

nm (选项) (二进制目标文件)

二进制文件通常是库文件、可执行文件、objective文件(gcc -c xxx.c产生的目标文件)

选项

  • -A:每个符号前显示文件名
  • -C:禁用C++的name mangle,显示的是代码中函数的名字
  • -D:显示动态符号
  • -l:显示每个符号的行号
  • -u:显示file外定义的符号或没有定义的符号
  • -g:仅显示外部符号

3. ar : Linux系统的一个备份打包命令,用于创建存档文件(archive),或从存档文件中提取、添加、删除成员文件。

ar命令最常见的用法是将目标文件(.o)打包为静态链接库(.a)。在嵌入式开发中经常用到。

创建静态库

ar -rcsv libxxx.a  a.o b.o c.o d.o

- r: 替换存档文件中的同名文件或添加新文件
- c:创建存档文件
- s:将成员文件索引写入存档,或更新现有索引,即使没有对存档进行其他修改(创建较大库时能加快时间)
- v:显示操作过程的详细信息
- d:从存档中删除模块
- q:快速追加。增加新模块到归档文件的结尾处,并不检查是否需要替换。
- t:显示存档文件所包含内容的列表

显示归档文件内容

ar -tv libxxx.a

删除归档文件的成员文件

ar -d libxxx.a a.o c.o

4. ldd : 打印程序或库文件所依赖的共享库列表

ldd是分析程序运行时需要依赖的动态库的重要工具

语法

ldd (选项) file

选项

--version:打印指令版本号;
-v:详细信息模式,打印所有相关信息;
-u:打印未使用的直接依赖;
-d:执行重定位和报告任何丢失的对象;
-r:执行数据对象和函数的重定位,并且报告任何丢失的对象和函数;
--help:显示帮助信息。

使用方法

一般而言,我么用ldd命令就是观察程序运行依赖哪些库,直接ldd file即可:

5. ldconfig: 动态链接库管理命令

ldconfig工具主要用途是:在默认搜寻目录/lib和/usr/lib以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib.so),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。

缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表,为了让动态链接库为系统所共享,需运行动态链接库的管理命令ldconfig,此执行程序存放在/sbin目录下。

ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令

总结:ldconfig是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。

语法

ldconfig (选项)

选项

-v:详细信息模式,打印所有相关信息;
-p:打印出当前缓存文件所保存的所有共享库的名字
-C CACHE:此选项指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,此文件存放已排好序的可共享的动态链接库的列表。
-f CONF:此选项指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf

使用方法

(1) 一般而言,我们用法就是在/etc/ld.so.conf中添加新库的路径,然后执行ldconfig,这样程序运行的时候就能找到依赖的库。

(2) 比如安装了一个mysql/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,这时就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后ldconfig一下,新的library才能在程序运行时被找到!

注意事项

  1. /lib/usr/lib里面加东西,不用修改/etc/ld.so.conf,但是完了之后要调一下ldconfig,不然这个library会找不到。
  2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到。
  3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
  4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
  5. 不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。
  6. 再有,诸如libdb-4.3.so文件头中是会含有库名相关的信息的(即含“libdb-4.3.so”,可用strings命令察看),因此仅通过修改文件名以冒充某已被识别的库(如libdb-4.8.so)是行不通的。为此可在编译库的Makefile中直接修改配置信息,指定特别的库名。

6. readelf: 显示elf格式文件的信息

一般用于查看ELF格式的文件信息,常见的文件如在Linux上的可执行文件、动态库、静态库等。

语法

readelf (选项) 文件   除了`-v``-H`之外,其它的选项必须有一个被指定

选项

  • -a : 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I
  • -h : 显示elf文件开始的文件头信息
  • -l :显示程序头(段头)信息(如果有的话)。
  • -s : 显示符号表段中的项(如果有的话)。
  • -e : 显示全部头信息,等价于: -h -l -S
  • -r : 显示可重定位段的信息
  • -d : 显示动态段的信息
  • -V :显示版本段的信息
  • -A : 显示CPU构架信息
  • -D : 使用动态段中的符号表显示符号,而不是使用符号段。
  • -v : 显示readelf的版本信息。

关于elf文件

ELF 把文件分成了一个个分段,每一个段都有自己的作用,具体每个段的作用这里我就不详细说明了,感兴趣的同学可以去看《程序员的自我修养——链接、装载和库》这本书。

另外,ELF 文件有两种索引,Program header table 中记录了「运行时」所需的段,而 Section header table 记录了二进制文件中各个「段的首地址」。

那 ELF 文件怎么生成的呢?

我们编写的代码,首先通过「编译器」编译成汇编代码,接着通过「汇编器」变成目标代码,也就是目标文件,最后通过「链接器」把多个目标文件以及调用的各种函数库链接起来,形成一个可执行文件,也就是 ELF 文件。

那 ELF 文件是怎么被执行的呢?

执行 ELF 文件的时候,会通过「装载器」把 ELF 文件装载到内存里,CPU 读取内存中的指令和数据,于是程序就被执行起来了。

参考文献

  1. linux ar命令 --静态库(.a)的制作
  2. ar命令的常见用法
  3. /etc/ld.so.conf详解
  4. Linux 内核和 Windows 内核有什么区别?
posted @   时间的风景  阅读(1779)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示