目标文件格式分析工具: ar,nm,objdump,objcopy,readelf

http://www.ibm.com/developerworks/cn/aix/library/au-unixtools.html

http://www.ibm.com/developerworks/aix/library/au-unixtools.html?S_TACT=105AGX52&S_CMP=cn-a-aix

http://www.cnblogs.com/amethyst623/articles/1946499.html

# [库文档的开发与使用](http://www.cppblog.com/amazon/archive/2010/01/12/105471.html)
软件开发者可以使用某种语言的库函数,这些库函数通常放在/lib和/usr/lib目录中,而大多数的库函数放在/usr/lib中,比如标准C库函数文件/usr/lib/libc.a和标准C++库函数/usr/lib/libstdc++.a。

库对应的头文件有两种,包括公有头文件和私有头文件。公有头文件声明的资源对其他程序是有效的,而私有头文件声明的资源只能被对应的库代码使用。为了使库成为公有的,应将它安装在目录/usr/lib中,并将它的头文件放在/usr/include中,并在用户程序中使用#include <>的方式引入库头文件。将头文件的路径名放置在引号中,就可将私有头文件放入程序中,比如#include "hello.h",预处理程序会首先在当前目录查找hello.h头文件,如果写成#include "-/include/hello.h",预处理程序就会在目录~/include中搜索头文件hello.h。

库文档必须以.a扩展名结束,一旦为一组目标模块创建了一个库文件,通过制定库文档作为参数,这些模块就可以被C程序根据-l*链接使用。对于标准库,例如C中的libc.a,只需要在用户程序中添加相应的头文件比如stdio.h、stdlib.h、ctype.h等,而不需要明确地用-l编译程序选项去链接该库;但还有许多库不是标准库,例如数学库libm.a,除了需要添加相应头文件之外,还必须明确地用编译程序选项-lm链接该库,其中-l编译选项在lib和.a之间指定子串,不明确指定的话会在编译器产生错误。

注意:

1.标准C语言库libc.a在编译程序的链接阶段自动被链接。

2.一些常见的与库相关的编程错误:

没有为库加入头文件

没有明确链接一个库,而这个库不能被程序自动链接

使用了错误版本的库

链接了不兼容的库



------------------------------------------------------------------------------------------------------



**库的开发**



使用ar程序可以执行各种与库相关的任务,比如在库文件中创建、修改和提取模块等。与linux命令不同,ar命令的关键字不需要使用-连字符。

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)**ar 关键字 库文档名 文件列表

**![](//www.cppblog.com/Images/OutliningIndicators/None.gif)d 在库文档中删除一个文件

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)q 在现有库文档中添加一个文件,若库文档不存在,则创建之

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)r 新建一个库文档或覆盖一个现有库文档

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)t 显示一个库文档目录

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)s 强制生成库文档符号表

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)x 从一个库文档中提取一个或多个文件,并将它们保存在当前的工作目录中

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)v 生成一个详细的输出

假设已存在main.c、compute.c、input.c、main.h、compute.h、input.h这些文件,且compute.c使用了数学库libm.a,下面的例子用于库文档的创建和追加等。

**ar r libmath.a input.o compute.o**

该命令创建了文件input.o和compute.o的库文档文件libmath.a,如果该库文档已存在则会被覆盖。上述命令当libmath不存在时,可以使用**ar q libmath.a input.o compute.o**代替,该命令在libmath.a中追加新文件,当libmath.a不存在时自动创建;当想将当前目录中所有目标文件都放入库文件中,也可以使用**ar r libmath.a *.o**或者**ar r libmath.a `ls *.o`**这样的命令。

**gcc main.c libmath.a -o power -lm**

该命令将库文档中的input.o和compute.o链接到main.o上,使用-lm链接数学库libm.a,因为在compute.o中使用了pow函数。将libmath.a安装到/usr/lib后,就可以通过-lmath的方式使用了。

**rm compute.o input.o**

创建目标模块的库文档后,就可以删除原有模块。

**ar t libmath.a**

该命令用于显示库文档libmath.a的目录,同理可以使用ar vt libmath.a命令获得更详细的输出。

**ar d libmath.a input.o**

该命令用于从库文档libmath.a中删除一个或多个目标模块。

**ar x libmath.a compute.o**

该命令下哦那个库文档libmath.o中提取一个或多个目标模块,并放在当前目录中。



在makefile中也可以使用ar命令,这样创建了软件的可执行文件之后,也可以创建目标文档的库文档,具体方法如下:

CC=gcc

OPTIONS=-03

OBJECTS=main.o input.o compute.o

SOURCES=main.c input.c compute.c

HEADERS=main.h input.h compute.h

ARCHIVE=compute.o input.o

LIBRARY=libmath.a

AR_KEYS=qv

complete : power

@echo "Build complete"

power : $(OBJECTS)

$(CC) $(OPTIONS) -o $@ $^ -lm

@echo "The executable is in the 'power' file"

main.o : main.h input.h compute.h

compute.o : compute.h

input.o : input.h

buldle :

@echo "Archiving object modules..."

ar $(AR_KEYS) $(LIBRARY) $(ARCHIVE)

@echo "Archiving is complete."

power.tar : makefile $(HEADERS) $(SOURCES)

tar -cvf $@ $^

clean :

rm -f *.o



---------------------------------------------------------------------------------------------



**库的使用**



在安装库文档之前,需要给库文档生成和添加一个目录索引。库文档中的目标文件不是以任意顺序排列的,而是依赖于模块被插入到库文档中的顺序。带有目录的库文档在链接阶段是必要的,它允许库文档中的函数互相调用,而无论这些函数在库文档中的位置如何。

**ranlib 库文档列表**

该命令可以为库文档列表中的每个库文档生成和添加一个目录,该命令与如下命令相同:

**ar s 库文档

**

一旦添加了目录之后,就可以安装该库使其成为公有,主要采取两个步骤:

1.创建库的头文件并把它放在/usr/include目录中,头文件包含库中资源的声明。一个库文档可以对应多个头文件,例如libmath.a可以对应input.h和compute.h。

2.在/usr/lib目录中放置该库文档,例如/usr/lib/libmath.a。

3.在使用该库时,在程序中加入对应头文件,并用带有-lmath的编译命令即可。



可以用nm命令显示一个库、目标或可执行文件的符号表,表中包括名称、类型、大小和进入点等信息。它的输出告知该库的属性,输出的每一行是每一个标识符,例如文件中的某个函数名或者变量名。nm命令显示的信息用于调试库和可执行文件,对于库文档中的每个文件或成员,nm命令至少会将下面的信息发送到标准输出:每个符号的地址、符号的值以及其类型。根据选项,也可能输出库或目标的名称以及符号的大小等。
![](//www.cppblog.com/Images/OutliningIndicators/None.gif)**nm[选项][文件列表(库文件/目标文件/可执行文件)]**

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-D 只显示动态符号,当使用动态库时很有用

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-V nm命令版本号

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-g 只显示全局符号的相关信息

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-l 为每一个符号查找和显示文件名和行号

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-n 用地址给外部符号分类

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-u 只显示未定义的符号,即每个目标模块的外部符号

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-w 给出更多警告信息

![](//www.cppblog.com/Images/OutliningIndicators/None.gif)-f 格式 以不同格式输出,可以是bsd、sysv、posix等,默认是bsd

对nm命令,以后再进行详细学习,在此省略。

原文链接: https://www.cnblogs.com/xuxm2007/archive/2012/01/01/2309331.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/39603

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 下午4:15
下一篇 2023年2月8日 下午4:17

相关推荐