红联Linux门户
Linux帮助

Linux下创建自己的共享库

发布时间:2016-03-08 09:58:40来源:linux网站作者:Gavin__Zhou

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于windows和linux的本质不同,因此二者库的二进制是不兼容的。

Linux操作系统支持的函数库分为静态库和动态库,动态库又称共享库。Linux系统有几个重要的目录存放相应的函数库,如/lib, /usr/lib。


静态函数库、动态函数库

A. 这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进可执行文件了。当然这也会称为它的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译,而且体积也较大。

B.这类库的名字一般是libxxx.so,动态库又称共享库;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。而且如果多个应用程序都要使用同一函数库,动态库就非常适合,可以减少应用程序的体积。

注意:不管是静态函数库还是动态函数库,都是由*.o目标文件生成。


函数库的创建


静态函数库的创建

ar rcs  libname.a   a.o  b.o

ar:静态函数库创建的命令
-c :create的意思
-r :replace的意思,表示当前插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误信息,并不替换其他同名的模块。默认的情况下,新的成员增加在库的结尾处。
s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。甚至对于没有任何变化的库也作该动作。对一个库做ar s等同于对该库做ranlib


动态函数库的创建

gcc -shared -Wl,-soname,youLibSoname,-o youRealName a.o b.o

**linux共享库名称分为三段:realname,soname,linkname
realname:共享库的全名,比如:libmycal.so.1.10
soname:只是包含共享库的版本号,比如:libmycal.so.1
linkname:一般只包含共享库的名字,比如:libmycal.so**

产生.o文件的命令是:

gcc -c -fPIC a.c

-fPIC:产生位置无关的代码
-c:只编译不链接


创建共享库实例

我们先创建一个src和lib文件夹,src下存放源代码,,lib下存放共享库
我么在src下写个add.c和sub.c,代码很简单,就是对两个数实现加法和减法运算,代码略过。
(1)编译产生.o文件

gcc -c -fPIC add.c
gcc -c -fPIC sub.c

(2)创建共享库

gcc -shared -Wl,-soname,libmycal.so.1,-o libmycal.so.1.10 add.o sub.o


现在我们看看结果:

Linux下创建自己的共享库

将生成的共享库copy到上级的lib下,并生成linkname:

cp libmycal.so.1.10 ../lib  #copy
ln -s libmycal.so.1.10 libmycal.so   #创建link,linkname

(3)回到父目录,创建main.c作为测试程序

Linux下创建自己的共享库

(4)编译生成可执行程序

gcc main.c lib/libmycal.so -o app

此时已经编译成功,生成app

我们运行下,出错了,结果是:

Linux下创建自己的共享库

找不到共享库的路径,我们需要修改配置文件
(5)修改/etc/ld.so.conf文件

sudo vi /etc/ld.so.conf

我们把共享库的路径写上:

Linux下创建自己的共享库

更新配置文件:

sudo ldconfig -v

此时重新编译并运行app,可以看到结果正确:

Linux下创建自己的共享库

此时使用ldd查看依赖,发现全部满足:

Linux下创建自己的共享库

第一个共享库存实例成功。


本文永久更新地址:http://www.linuxdiyf.com/linux/18704.html