库文件及相关命令

库是移组预先编译好的函数的集合,这些函数都是按照可重用的原则编写的。他们通常由移组相互关联的函数组成以执行某项常见的任务,比如屏幕处理函数库和数据库访问库。

Reference:

  • 《Linux程序设计》

标准系统库文件存储在/lib和/usr/lib目录中,库文件的名字总是以lib开头,随后部分知名这是什么库,最后给出库文件的类型:

  • .a代表传统的静态函数库
  • .so代表共享函数库

创建库文件,使用ar程序创建一个归档文件并将目标文件添加进去。

[root@localhost test]# ar crv libfoo.a bill.o fred.o
a - bill.o
a - fred.o

要查看那些函数被包含在目标文件、函数库或可执行文件里,可以使用nm命令。

[root@localhost test]# nm libfoo.a 

bill.o:
0000000000000000 T bill
                 U printf

fred.o:
0000000000000000 T fred
                 U printf
[root@localhost test]# nm program
0000000000400595 T bill
000000000060103c B __bss_start
000000000060103c b completed.6355
0000000000601038 D __data_start
0000000000601038 W data_start
00000000004004c0 t deregister_tm_clones
0000000000400530 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000400648 R __dso_handle
0000000000600e28 d _DYNAMIC
000000000060103c D _edata
0000000000601040 B _end
                 U exit@@GLIBC_2.2.5
0000000000400634 T _fini
0000000000400550 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
00000000004007c0 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000400674 r __GNU_EH_FRAME_HDR
0000000000400418 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
0000000000400640 R _IO_stdin_used
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
0000000000400630 T __libc_csu_fini
00000000004005c0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
000000000040057d T main
                 U printf@@GLIBC_2.2.5
00000000004004f0 t register_tm_clones
0000000000400490 T _start
0000000000601040 D __TMC_END__
[root@localhost test]# nm program.o
                 U bill
                 U exit
0000000000000000 T main

静态库的一个缺点是,当同时运行许多应用程序并且都是用来自同一个函数库的函数时,内存中就会有同一个函数的多份副本,而且在程序文件自身中也有多分同样的副本。这将消耗大量宝贵的内存和磁盘空间。
共享库的保存位置与静态库是一样的,但是共享库有不同的文件名后缀。在一个典型的Linux系统中,标准数学库的共享版本是/usr/lib/libm.so。
当一个程序使用共享库时,他的连接方式是这样的:程序本身不在包含函数代码,而是引用运行时可访问的共享代码。当编译好的程序被装载到内存中执行时,函数引用被解析并产生对共享库的调用,如果有必要,共享库才被加载到内存中。
通过这种方法,系统可以只保留共享库的一份副本共许多应用程序同时使用,并且从磁盘上也仅保存一份。另一个好处是共享库的更新可以独立于依赖他的应用程序。如文件/lib/libm.so就是对实际库文件修订版本的符号链接。(/lib/libm.so.N,其中N代表主版本号)。
可以通过运行工具ldd来查看一个程序需要的共享库。

[root@localhost test]# ldd program
    linux-vdso.so.1 =>  (0x00007fff077b0000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f6371135000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f6371503000)

共享库在许多方面类似于Windows中使用的动态链接库。.so库对应于.DLL文件,都是在程序运行时加载,而.a库类似于.LIB文件,都包含在可执行程序中。

标签: none

添加新评论

ali-01.gifali-58.gifali-09.gifali-23.gifali-04.gifali-46.gifali-57.gifali-22.gifali-38.gifali-13.gifali-10.gifali-34.gifali-06.gifali-37.gifali-42.gifali-35.gifali-12.gifali-30.gifali-16.gifali-54.gifali-55.gifali-59.gif

加载中……