静态库的编译 共享库的编译链接运行 及共享库的区别(2)

1、组成共享库的目标文件和一般的目标文件有所不同,在编译时要加-fPIC选项,

$ gcc -c -fPIC stack/stack.c stack/push.c stack/pop.c stack/is_empty.c
-f后面跟一些编译选项,PIC是其中一种,表示生成位置无关代码(Position Independent Code)

gcc -shared -o libstack.so stack.o push.o pop.o is_empty.o


2、把main.c和共享库编译链接在一起,然后运行:

$ gcc main.c -g -L. -lstack -Istack -o main
$ ./main 
./main: error while loading shared libraries: libstack.so: cannot open shared object file: No such file or directory

3、解决方法

最常用的方法。把libstack.so所在目录的绝对路径(比如/home/langu/linuxk/link/libshared)添加到/etc/ld.so.conf中(该文件中每个路径占一行),如:

include /etc/ld.so.conf.d/*.conf
/home/langu/linuxk/link/libshared

然后运行ldconfig


4、指定noname编译(逗号之间不能用空格)

按照共享库的命名惯例,每个共享库有三个文件名:real name、soname和linker name。真正的库文件(而不是符号链接)的名字是real name,包含完整的共享库版本号。

编译生成的库文件是libstack.so.1.0,是real name,但这个库文件中记录了它的soname是libstack.so.1

$ gcc -shared -Wl,-soname,libstack.so.1 -o libstack.so.1.0 stack.o push.o pop.o is_empty.o


libstack.so.1.0所在的目录加入/etc/ld.so.conf中,然后运行ldconfig命令,ldconfig会自动创建一个soname的符号链接:

$ sudo ldconfig

$ ln -s libstack.so.1.0 libstack.so
$ gcc main.c -L. -lstack -Istack -o main

langu@langu:~/linuxk/link/libshared$ ls -l libs*
lrwxrwxrwx 1 langu langu   15 May 21 11:18 libstack.so -> libstack.so.1.0
lrwxrwxrwx 1 root  root    15 May 21 11:20 libstack.so.1 -> libstack.so.1.1
-rwxrwxr-x 1 langu langu 7937 May 21 11:17 libstack.so.1.0
-rwxrwxr-x 1 langu langu 7937 May 21 11:19 libstack.so.1.1
lrwxrwxrwx 1 root  root    15 May 21 11:21 libstack.so.2 -> libstack.so.2.0
-rwxrwxr-x 1 langu langu 7937 May 21 11:20 libstack.so.2.0

soname是一个符号链接的名字,只包含共享库的主版本号,主版本号一致即可保证库函数的接口一致,因此应用程序的 .dynamic段只记录共享库的soname,只要soname一致,这个共享库就可以用。假如有libstack.so.1和 libstack.so.2是两个主版本号不同的libstack.so,有些应用程序依赖于libstack. so.1,有些应用程序依赖于 libstack.so.2,但对于依赖 libstack .so.1的应用程序来说,真正的库文件不管是 libstack.so.1.0libcap.so.1.1都可以用,所以使用共享库可以很方便地升级库文件而不需要重新编译应用程序,这是静态库所没有的优点。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值