ar

我们已经很熟悉linux中的tar命令了, 英文原文是tape archive,  磁带归档。 今天, 我们要说的是ar命令, 也就是archive, 也是归档。 其实, 对目标文件.o进行归档, 就形成了静态库.a文件。实际上, ar命令可以对一个或者多个目标文件.o进行归档, 形成一个静态库.a文件。 可见, 静态库还是很简单的,无非就是众多目标文件的集合。



ar基本用法
  ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
  下面是ar命令的格式:
  ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files..
  ar可让您集合许多文件,成为单一的备存文件。在备存文件中,所有成员文件皆保有原来的属性与权限。

参  数:
指令参数
-d  删除库文件中的成员文件。
-m  变更成员文件在库文件中的次序。
-p  显示库文件中的成员文件内容。
-q  将问家附加在库文件末端。
-r  将文件插入库文件中。
-t  显示库文件中所包含的文件。
-x  自库文件中取出成员文件。
选项参数
a<成员文件>  将文件插入库文件中指定的成员文件之后。
b<成员文件>  将文件插入库文件中指定的成员文件之前。
c  建立库文件。
f  为避免过长的文件名不兼容于其他系统的ar指令指令,因此可利用此参数,截掉要放入库文件中过长的成员文件名称。
i<成员文件>  将问家插入库文件中指定的成员文件之前。
o  保留库文件中文件的日期。
s  若库文件中包含了对象模式,可利用此参数建立备存文件的符号表。
S  不产生符号表。
u  只将日期较新文件插入库文件中。
v  程序执行时显示详细的信息。
V  显示版本信息



ar用来管理一种文档。这种文档中可以包含多个其他任意类别的文件。这些被包含的文件叫做这个文档的成员。ar用来向这种文档中添加、删除、解出成员。成员的原有属性(权限、属主、日期等)不会丢失。



实际上通常只有在开发中的目标连接库是这种格式的,所以尽管不是,我们基本可以认为ar是用来操作这种目标链接库(.a文件)的。



ar的常用用法见正文。



1、创建库文件
我 不知道怎么创建一个空的库文件。好在这个功能好像不是很需要。通常人们使用“ar cru liba.a a.o”这样的命令来创建一个库并把a.o添加进去。”c”关键字告诉ar需要创建一个新库文件,如果没有指定这个标志则ar会创建一个文件,同时会给出 一个提示信息,”u”用来告诉ar如果a.o比库中的同名成员要新,则用新的a.o替换原来的。但是我发现这个参数也是可有可无的,可能是不同版本的ar 行为不一样吧。实际上用”ar -r liba.a a.o”在freebsd5上面始终可以成功。



2、加入新成员
使用”ar -r liba.a b.o”即可以将b.o加入到liba.a中。默认的加入方式为append,即加在库的末尾。”r”关键字可以有三个修饰符”a”, “b”和”i”。



“a”表示after,即将新成员加在指定成员之后。例如”ar -ra a.c liba.a b.c”表示将b.c加入liba.a并放在已有成员a.c之后;
“b”表示before,即将新成员加在指定成员之前。例如”ar -rb a.c liba.a b.c”;
“i”表示insert,跟”b”作用相同。
3、列出库中已有成员
“ar -t liba.a”即可。如果加上”v”修饰符则会一并列出成员的日期等属性。



4、删除库中成员
“ar -d liba.a a.c”表示从库中删除a.c成员。如果库中没有这个成员ar也不会给出提示。如果需要列出被删除的成员或者成员不存在的信息,就加上”v”修饰符。



5、从库中解出成员
“ar -x liba.a b.c”



6、调整库中成员的顺序
使用”m”关键字。与”r”关键字一样,它也有3个修饰符”a”,”b”, “i”。如果要将b.c移动到a.c之前,则使用”ar -mb a.c liba.a b.c”



 1. ar  rcs ——   把目标文件转换为静态库



       2. ar -vt libtest.a  查看静态库中有哪些目标文件  (实际上就相当于: objdump -a libtest.a)



       3. ar -x libtest.a   将静态库中的目标文件取(解压)出来, 放在当前目录下。
       静态库就这么简单。 实际上, 我认为, 从广义上来讲: 目标文件.o等价于静态库.a, 它们是可逆的。



创建静态库。a文件。用C/C++开发程序时经常用到,但我很少单独在命令行中使用ar命令,一般写在makefile中,有时也会在shell脚 本中用到。



常用参数
  格式:ar rcs libxxx.a xx1.o xx2.o
  参数r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。【1】
  参数c:创建一个库。不管库是否存在,都将创建。
  参数s:创建目标文件索引,这在创建较大的库时能加快时间。(补充:如果不需要创建索引,可改成大写S参数;如果。a文件缺少索引,可以使用ranlib命令添加)
  格式:ar t libxxx.a
  显示库文件中有哪些目标文件,只显示名称。
  格式:ar tv libxxx.a
  显示库文件中有哪些目标文件,显示文件名、时间、大小等详细信息。
  格式:nm -s libxxx.a
  显示库文件中的索引表。
  格式:ranlib libxxx.a
  为库文件创建索引表。
  使用示例
  示例一 在shell脚本中使用
  Bash代码
  OS=uname -r
  ar rcs libhycu.a.$OS *.o



  示例二 在makefile中使用
  Makefile代码
  $(BIN1): $(BIN1_OBJS)
  ar rcs $@ $^



  示例三 创建并使用静态库
  第一步:编辑源文件,test.h test.c main.c。其中main.c文件中包含main函数,作为程序入口;test.c中包含main函数中需要用到的函数。
  vi test.h test.c main.c
  第二步:将test.c编译成目标文件。
  gcc -c test.c
  如果test.c无误,就会得到test.o这个目标文件。
  第三步:由。o文件创建静态库。
  ar rcs libtest.a test.o
  第四步:在程序中使用静态库。
  gcc -o main main.c -L. -ltest
  因为是静态编译,生成的执行文件可以独立于。a文件运行。
  第五步:执行。
  ./main



  示例四 创建并使用动态库
  第一步:编辑源文件,test.h test.c main.c。其中main.c文件中包含main函数,作为程序入口;test.c中包含main函数中需要用到的函数。
  vi test.h test.c main.c
  第二步:将test.c编译成目标文件。
  gcc -c test.c
  前面两步与创建静态库一致。
  第三步:由。o文件创建动态库文件。
  gcc -shared -fPIC -o libtest.so test.o
  第四步:在程序中使用动态库。
  gcc -o main main.c -L. -ltest
  当静态库和动态库同名时,gcc命令将优先使用动态库。
  第五步:执行。
  LD_LIBRARY_PATH=. ./main



     动态库除了在默认的的路径/lib 和 /usr/lib 下还可以通过"在配置文件/etc/ld.so.conf中指定动态库搜索路径",“环境变量的方式”和“在编译目标代码时指定该程序的动态库搜索路径(通过gcc 的参数"-Wl,-rpath,"指定)”三种,他们的优先级也不一样;

下面介绍第二种:


例如:



export LD_LIBRARY_PATH=.



但本文为了举例方便,使用另一种设置环境变量的方法,既在命令前加环境变量设置,该环境变量只对该命令有效,当该命令执行完成后,该环境变量就无效了。如下述命令:



LD_LIBRARY_PATH=. ./main



  示例五 查看静态库中的文件
  [root@node56 lib]# ar -t libhycu.a
  base64.c.o
  binbuf.c.o
  cache.c.o
  chunk.c.o
  codec_a.c.o
  …
  xort.c.o
  [root@node56 lib]#
  [root@node56 lib]# ar -tv libhycu.a
  rw-r–r– 0/0 7220 Jul 29 19:18 2011 base64.c.o
  rw-r–r– 0/0 2752 Jul 29 19:18 2011 binbuf.c.o
  rw-r–r– 0/0 19768 Jul 29 19:18 2011 cache.c.o
  …
  rw-r–r– 0/0 4580 Jul 29 19:18 2011 xort.c.o
  [root@node56 lib]#
  [root@node56 lib]# nm -s libhycu.a | less
  Archive index:
  Base64Enc in base64.c.o
  GetBase64Value in base64.c.o
  Base64Dec in base64.c.o
  encode64 in base64.c.o
  decode64 in base64.c.o
  check64 in base64.c.o
  test64 in base64.c.o
  …
  chunk_alloc in chunk.c.o


Category linux