什么是库文件?
库就是一组预先编译好的方法的集合。在linux系统中,库文件一般被存储在/lib和/usr/lib中,库的头文件一般会被存储在/usr/include下。
库文件可以分为静态库和共享库两种。
静态库的命名规则为libxxx.a,共享库的命名规则为libxxx.so。
静态库和共享库生成的第一步都是先将需要生成库的“.c”文件编译成为“.o”文件;
之后的步骤命令各有各的不同:
静态库的命令为:ar crv libfoo.a add.o max.o(这里假设静态库的名称为foo,需要编译的两个文件名分别为add和max,稍后我会给出实例)
该命令具体解释如下:
ar 就是将.o文件生成静态库的命令
c 是创建库
r 是将方法添加到库中
v 是显示过程
后面跟的就是库的名称和需要的.o文件名称。
共享库的命令为:gcc -shared -fPIC -o libfoo.so add.o max.o
该命令具体解释如下:
该命令需要使用gcc命令
-shared 该选项指定生成动态连接库,不用该标志外部程序无法连接,相当于一个可执行文件。
-fPIC 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,达不到‘共享’的目的。
接下来通过实例来展示这两种库怎样使用。
接下来我们把这两个.c文件编译成.o文件
函数的调用需要使用头文件实现函数的声明
先将二者形成静态库
接下来编写main函数实现二者的调用
编译并运行main函数
我们发现这时编译没有通过,因为这时候主函数在编译链接时找不到add和max的位置,这时候我们需要使用 命令
gcc -o main main.c -L. -lfoo
来编译,-L后接库函数的位置,-l后接库函数的名称
我们可以看到生成了可执行文件main,执行结果如下
现在我们把库函数删除,再执行main程序
可以看到程序仍然运行成功。
下面我们使用共享库
接下来编译链接生成main可执行程序
可以看到仍然需要在编译命令后加上-L和-l
接下来执行
执行失败
我们将库函数移动到/usr/lib下,将头文件移动到/usr/include下,需要注意我们需要切换管理员权限来进行这个操作,在ununtu系统下使用sudo su切换管理员,在红帽子和cent os下使用su切换
运行成功!
这时候我们把库函数删除再次运行main程序
这时候可以看到运行时失败,这是因为静态库和共享库的主要区别在于:
使用静态库链接时将用到的方法包含到了最终生成的可执行程序中,而共享库不包含,只做标记,在运行程序时才会动态加载。所以把静态库删除后不影响程序运行,而删除共享库则会。这个不同也引发出一些其他的不同,比如使用静态库生成的可执行程序是比使用共享库生成的可执行程序所占内存空间更大;当更新库文件时,使用静态库的程序需要重新编译链接,使用共享库的程序则不需要。
c语言的标准库使用的都是共享库,如下图所示