共享库和静态库

处理共享库用的是一种更加高级的链接形式,它会使得可执行文件比较小。共享库使用“.so”后缀名,它代表共享对象(shared object)。
一个与共享库链接的可执行文件仅仅包含它用到的函数相关的一个表格,而不是外部函数所在的对象文件的整个机器码。在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该共享库中复制到内存中----这个过程被称作动态链接(dynamic linking)。

如果可能,在绝大部分系统上gcc编译程序时默认链接到共享库。使用选项“-lNAME”的情况下,静态库“libNAME”可以用于链接,但编译器首先会检查具有相同名字和“.so”为扩展名的共享库。

“libgdbm.so”共享库优先于“libgdbm.a”静态库被使用。
然而,当启动可执行文件时,载入器为了把共享库载入内存,必须先找到它。默认情况下,载入器仅在一些预定义的系统目录中查找共享库,比如“/usr/local/lib”和“/usr/lib”。如果库不在这些目录中,那它必须被添加到载入路径(load path)中去。8
设置载入路径的最简单方法是通过环境变量LD_LIBRARY_PATH。例如,下面的命令设置载入路径为“/opt/gdbm-1.8.3/lib”,以便载入器能够找到“libgdbm.so”:
$ LD_LIBRARY_PATH=/opt/gdbm-1.8.3/lib
$ export LD_LIBRARY_PATH
$ ./a.out
Storing key-value pair... done

注意,原则上包含有要用到的共享库的目录可以通过链接选项“-rpath”存储到可执行文件中去,但通常都不这样做。因为如果库被移走或该可执行文件被复制到另外的系统上,这会产生新的问题。

为了不要每次都输入,LD_LIBRARY_PATH环境变量可以一次性的被设置到shell的相应登录文件中,象GNU Bash shell的“.bash_profile”文件。
多个共享库目录可以用冒号分隔列表DIR1:DIR2:DIR3:...:DIRN的形式放入载入路径中。例如下面的命令设置载入路径,用到了“/opt/gdbm-1.8.3”和“/opt/gtk-1.4”中的“lib”目录:
$ LD_LIBRARY_PATH=/opt/gdbm-1.8.3/lib:/opt/gtk-1.4/lib
$ export LD_LIBRARY_PATH
如果载入路径包含已有项,可以用语法LD_LIBRARY_PATH=NEWDIRS: $LD_LIBRARY_PATH来扩展。例如,下面的命令象上面显示的那样把目录“/opt/gsl-1.5/lib”添加到载入路径中:
$ LD_LIBRARY_PATH=/opt/gsl-1.5/lib:$LD_LIBRARY_PATH
$ echo $LD_LIBRARY_PATH
/opt/gsl-1.5/lib:/opt/gdbm-1.8.3/lib:/opt/gtk-1.4/lib
系统管理员可以为所有用户设置LD_LIBRARY_PATH变量,只要把它添加到默认的登录脚本中,比如象“/etc/profile”。在GNU系统上,系统范围的路径也可以被定义在载入器配置文件“/etc/ld.so.conf”中。
相比较,使用“-static”选项可以迫使gcc静态链接,避免使用共享库:
$ gcc -Wall -static -I/opt/gdbm-1.8.3/include/
-L/opt/gdbm-1.8.3/lib/ dbmain.c –lgdbm

这就创建了一个与静态库“libgdbm.a”链接的可执行文件,它不需要设置环境变量LD_LIBRARY_PATH或把共享库存放在默认目录中就可以运行:
$ ./a.out
Storing key-value pair... done.
正像前面一样要注意的,通过在命令行上指定库的完整路径,直接与个别库文件链接也是可以的。例如,下面的命令将直接与静态库“libgdbm.a” 链接,
$ gcc -Wall -I/opt/gdbm-1.8.3/include
dbmain.c /opt/gdbm-1.8.3/lib/libgdbm.a
而下面的命令将与共享库文件“libgdbm.so”链接:
$ gcc -Wall -I/opt/gdbm-1.8.3/include
dbmain.c /opt/gdbm-1.8.3/lib/libgdbm.so
对于后者,要运行该可执行文件,还是需要设置该库的载入路径。

有关C语言标准,请看《An Introduce to GCC》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值