本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于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
现在我们看看结果:
将生成的共享库copy到上级的lib下,并生成linkname:
cp libmycal.so.1.10 ../lib #copy
ln -s libmycal.so.1.10 libmycal.so #创建link,linkname
(3)回到父目录,创建main.c作为测试程序
(4)编译生成可执行程序
gcc main.c lib/libmycal.so -o app
此时已经编译成功,生成app
我们运行下,出错了,结果是:
找不到共享库的路径,我们需要修改配置文件
(5)修改/etc/ld.so.conf文件
sudo vi /etc/ld.so.conf
我们把共享库的路径写上:
更新配置文件:
sudo ldconfig -v
此时重新编译并运行app,可以看到结果正确:
此时使用ldd查看依赖,发现全部满足:
第一个共享库存实例成功。