`
java-mans
  • 浏览: 11422058 次
文章分类
社区版块
存档分类
最新评论

Linux静态库

 
阅读更多
一、引言
通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式。另外,我们也可以把对一些库函数的链接载入推迟到程序运行,这种库称之为动态库,关于动态库的详细内容请参考《linux动态库(转)
二、编译静态库
编译静态库很简单。
比如:gcc robin.c-c-L.-lRobinDynamic-o robin.o
注意这里一定要加-c选项,不然如果的代码中没有Main函数的话,就编译不过。
这里-L.-lRobinDynamic表示在当前目录下搜寻RobinDynamic库,并载入它。该库可以是静态,也可以是动态的。编译静态库或编译动态库时,对库的搜寻和载入都一样,因此关于此 部分的知识请参照《linux动态库
注意:如果要使用多个库的话,可以如下形式:gcc test.c-L.-lRobin-lRobinDynamic-o test.exe
三、打包静态库
编译完成,我需要用ar命令对生成的目标文件进行打包,以便使用。
ar命令选项如下:
d-----从指定的静态库文件中删除文件
m-----把文件移动到指定的静态库文件中
p-----把静态库文件中指定的文件输出到标准输出
q-----快速地把文件追加到静态库文件中
r-----把文件插入到静态库文件中
t -----显示静态库文件中文件的列表
x-----从静态库文件中提取文件
还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:
a-----把新的目标文件(*.o)添加到静态库文件中现有文件membername之后,如果没有membername项就表示所有现有文件之后
b-----把新的目标文件(*.o)添加到静态库文件中现有文件membername之前,如果没有membername项就表示所有现有文件之前
c-----创建一个新的.a文件
v-----使用详细模式,该模式下,将显示你添加的所有文件。
ar命令的命令行格式如下:
ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...
参数archive定义库的名称,files是你向库文件要添加的目标文件的清单, 用空格分隔每个文件.
比如目标文件添加到一个静态库文件的命令如下:
ar r libapue.a error.o errorlog.o lockreg.o
如果此次该静态文件库还不存在的话,它会先创建它再添加目标文件。
如果我们想新建一个静态库(如果有,先删除)的话,可以用如下的命令:
ar crv libRobin.a robin.o libRobinDynamic.so
这样就了创建了librobin.a静态库文件, 你可以用 t 选项显示包含在库中的文件
创建库文件之后,可以创建这个静态库文件的索引来帮助提高和库连接的其他程序的编译速度.
使用ranlib程序创建库的索引,索引存放在库文件内部.
ranlib libapue.a
用nm命令可以进行显示目标文件或.so文件的符号,系统必须依靠这些符号找到其对应的代码地址,然后执行这些代码。
nm命令用于显示.a存档文件的时候,它将显示.a中所有目标文件或.so文件的符号
显示目标文件的符号,可用如下命令:
nm robin.o | more
0000000000000000 T sayHello
U sayHelloWorld
显示.so文件的符号,可用如下命令
nm libRobinDynamic.so
0000000000200e50 a _DYNAMIC
0000000000200fe8 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
0000000000200e30 d __CTOR_END__
0000000000200e28 d __CTOR_LIST__
0000000000200e40 d __DTOR_END__
0000000000200e38 d __DTOR_LIST__
0000000000000670 r __FRAME_END__
0000000000200e48 d __JCR_END__
0000000000200e48 d __JCR_LIST__
0000000000201018 A __bss_start
w __cxa_finalize@@GLIBC_2.2.5
00000000000005c0 t __do_global_ctors_aux
0000000000000500 t __do_global_dtors_aux
0000000000201010 d __dso_handle
w __gmon_start__
0000000000201018 A _edata
0000000000201028 A _end
00000000000005f8 T _fini
0000000000000498 T _init
00000000000004e0 t call_gmon_start
0000000000201018 b completed.7424
0000000000201020 b dtor_idx.7426
0000000000000580 t frame_dummy
U puts@@GLIBC_2.2.5
00000000000005ac T sayHelloWorld
如果用nm命令对.a存档文件进行操作的时候,它将显示.a中所有目标文件或.so文件的符号。
命令如下:
nm libapue.a | more
三、使用静态库
使用静态库,只有在编译时才需要,运行时就不要需要了。
使用静态库,在进行编译时,可以和使用动态库一样进行使用因此关于此部分的知识请参照《linux动态库
另外,如果要使用多个库的话,可以如下形式gcc test.c-L.-lRobin-lRobinDynamic-o test.exe
另外也可以以如下形式使用静态库:
gcc test.cpp –otest.exelibexample.a
使用静态库进行编译时需要注意如下事项:
1)编译时,静态库如果不放在-l项中,那么一定要放在最后。
如:(在-o后面)
gcc test.cpp –o test.exelibexample.a
2)使用静态库时一定要连接所有用到的静态库,有多个静态库时,应该按照从新到旧(越底层越后面)的顺序进行排列
如要使用libwinkeemq-cpp.a,由于libwinkeemq-cpp.a用到了libactivemq-cpp.a,
而libactivemq-cpp.a又用到了libpthread.a, libuuid.a等等库。
其命令应如下
gcc test.cpp –o test.exelibwinkeemq-cpp.a lib libactivemq-cpp.a libpthrea.a libuuid.a…
3)静态库和动态库结合使用。
这时动态库应该放到静态库前面,动态库按照从旧到新(越底层越前面)的顺序排列。
比如:gcc test.cpp–L/usr/local/lib–lactivemq-cpp –lrobin–o test.exelibwinkeemq-cpp.a
这里activemq-cpp就比robin更底层,即robin库会使用activemq-cpp库
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics