【入门教程】Linux下静态库和共享库的制作方法
在Linux环境下编写程序时,经常会调用glibc库中的API。这些库是如何实现的的呢?很多初学者对此一直很困惑,接下来就与大家一起动手练习一下静态库和共享库的制作方法。 作者:沧海猎人 出处:http://blog.csdn.net/embedded_hunter 转载请注明出处 嵌入式技术交流QQ群:179012822 首先,我们编写代码来实现“输入半径求
在Linux环境下编写程序时,经常会调用glibc库中的API。这些库是如何实现的的呢?很多初学者对此一直很困惑,接下来就与大家一起动手练习一下静态库和共享库的制作方法。
作者:沧海猎人 出处:http://blog.csdn.net/embedded_hunter 转载请注明出处 嵌入式技术交流QQ群:179012822
首先,我们编写代码来实现“输入半径求出圆的面积和周长”这个任务。看一下我另几篇文章的内容:
- Linux环境下C语言编程实践_01 http://blog.csdn.net/embedded_hunter/article/details/6838338 在这篇文章里,在主函数直接就实现了。非常简单。
- Linux环境下C语言编程实践_02 http://blog.csdn.net/embedded_hunter/article/details/6838352 在这篇文章里,通过函数的方式实现了任务要求,主函数以及普通函数写在了同一个c源文件中。
- Linux环境下C语言编程实践_03 http://blog.csdn.net/embedded_hunter/article/details/6838372 在这篇文章里,还是通过函数的方式实现的任务要求,但是主函数以及普通函数分别放在了不同的c源文件中。
接下来我们希望将求圆的面积函数以及求圆的周长函数制作成库,主函数来直接调用我们自定义的库。
下面我们分别介绍制作静态库和共享库的方法。在介绍制作方法之前,先了解一下静态库与共享库的概念以及区别。
首先,无论是静态库还是共享库都是二进制代码。在linux中这些库与可执行文件类似,都是ELF格式文件。(关于ELF格式文件,这里不做详细介绍,请读者自行查阅其他资料,如果有机会,我会单独写一篇关于ELF格式文件的文章)
一个源程序转化为可执行文件,要经历编译、链接阶段。编译是将源文件转换为目标代码,链接是将目标代码与其他目标文件或库进行“组合”,生成可执行程序。
静态库与共享库的主要区别就在于链接过程,静态库在链接时会将代码静态插入可执行文件中,因此可执行文件比较大,并且可执行文件在运行时不依赖静态库;而共享库则不会将代码插入可执行文件中,因此可执行文件运行时会依赖共享库。
一、静态库的制作方法
“Linux环境下C语言编程实践_03 ”一文中有2个源文件和1个头文件:MyPrograme.c,Mylib.h,Mylib.c。需要将Mylib.c制作为静态库。
1、生成目标代码,后面制作静态库时需要用到这个目标代码。
#gcc -c Mylib.c
将会生成Mylib.o目标文件。
2、 制作静态库
#ar -cr libmylib.a Mylib.o
libmylib.a为静态库的文件名称,必须以lib开头。lib***.a 中的***为库名称。静态库必须按照 lib[name].a 的规则命名
使用ar命令,可以生成静态库。
3、程序链接时使用静态库
#gcc -o main main.c -L. -lmylib
main.c文件编译链接时链接mylib静态库。链接时库名称用-l指定,如-lmylib;静态库位置使用-L指定,如-L.,.代表当前路径,此选项不能省略。
注意:编译器默认会寻找共享库的,如果此目录下还有一个同名共享库,则编译器默认使用共享库进行链接。如果希望使用静态库,可以通过-static选项来指定。
4、运行程序
#./main 即可运行
此时即使删除libmylib.a,程序也能够运行。如果是共享库则不能删除库。
二、共享库的制作方法
1、制作共享库
#gcc -shared -fpic -o libmylib.so Mylib.c
libmylib.so 为静态库的文件名称,必须以lib开头。lib***.so中的***为库名称。
-shared 生成共享库
-fpic 产生位置无关代码,请思考什么是与位置无关。
2、使用共享库
#gcc -o main1 main.c -L. -lmylib
3、运行程序
此时无法直接运行程序,因为程序使用了共享库,需要指定共享库的位置。默认搜索共享库的路径为/usr/lib和 /lib目录。
有多方法可以解决这个问题:
(1)将共享库拷贝到/usr/lib或/lib目录中
(2)设置环境变量 LD_LIBRARY_PATH
(3)修改配置文件/etc/ld.so.conf
(4)编译时指定共享库路径。使用选项 -rpath
在这里我们使用第二种方法:
#export LD_LIBRARY_PATH=/home/linux/:$LD_LIBRARY_PATH
#./main1
4、查看可执行文件依赖哪些库。
#ldd main1
更多推荐
所有评论(0)