ar -t 用于列出静态库中所有目标文件,是最轻量可靠的查看方式;若输出为空,说明库可能为空或参数错误(如漏写-r);配合 nm -c 可进一步检查符号,ar -x 则用于解包验证。

用 ar -t 列出静态库中所有目标文件
静态库本质是 ar 打包的归档文件,不是可执行或共享对象,不能用 objdump -d 或 readelf 看指令,但能直接列出它包含哪些 .o 文件。ar -t libxxx.a 是最轻量、最可靠的查看方式。
-
ar -t libmyhello.a输出类似hello.o、utils.o这样的文件名,确认源对象是否已打包进去 - 如果输出为空,说明库可能为空或损坏(常见于
ar命令参数写错,比如漏了-r) - 不推荐用
ls -l或file判断内容——它们只显示文件大小和类型,看不出内部结构
用 nm -C 查看每个 .o 里的符号(函数/变量)
光知道有哪些 .o 不够,你真正关心的是“这个库有没有导出 my_init 函数?”——这时得进到每个目标文件里查符号表。nm 是专干这事的工具,加 -C 能还原 C++ 修饰名(即使你用 C 写也建议加上,避免看到一堆 _Z... )。
- 查整个库的所有全局符号:
nm -C libmyhello.a | grep " T "(T表示定义在代码段的全局函数) - 只查某个
.o:nm -C hello.o,适合调试单个模块编译是否正确 - 如果某函数名没出现在输出里,要么没编译进去(
gcc -c漏了该源文件),要么被声明为static(不会导出)
为什么 objdump -t 对静态库效果有限
objdump -t libxxx.a 确实能打印符号表,但它会为每个 .o 单独输出一段,且默认不带可读函数名(C++ 未 demangle),信息杂乱难定位。更麻烦的是:它无法区分“符号是否被实际引用”——静态链接器只提取用到的部分,而 objdump 显示的是所有符号,容易误判。
- 例如
objdump -t libmyhello.a | grep printf可能命中几十行,但其中大部分来自printf.o的内部辅助函数,跟你代码无关 - 真正有效的方式是:先用
ar -t锁定具体.o,再用nm -C针对性检查 - 如果你看到
U(undefined)符号大量出现,说明这个.o依赖外部符号,还没被完全解析——它不适合作为独立静态库成员
别跳过 ar -x 解包验证
当 nm 和 ar -t 结果矛盾,或链接时报 “undefined reference” 却查不到缺失函数时,最直白的办法就是把库解包出来看原始 .o 文件是否存在、是否损坏。
-
ar -x libmyhello.a会在当前目录释放出所有.o文件 - 接着运行
file hello.o确认它是 ELF 格式目标文件(不是空文件或文本) - 再
nm -C hello.o,对比和你源码函数签名是否一致(比如参数数量、const 修饰等) - 常见坑:不同架构编译(如 x86_64 编译的
.o打包进 aarch64 项目)、gcc -m32和-m64混用,解包后file一眼就能暴露
ar -t 看骨架,再 nm -C 查血肉,最后 ar -x 拆开验真伪——三步下来,90% 的符号问题都能定位到具体 .o 文件甚至某一行源码。











