03Linux下静态库和动态库(共享库)的制作与使用

Linux下静态库和动态库(共享库)的制作与使用

Linux操作系统支持的函数库分为:
·
静态库,libxxx.a,在编译时就将库编译进可执行程序中。(lib:前缀(固定)、.a:后缀(固定))
优点:程序的运行环境中不需要外部的函数库。
缺点:可执行程序大

·
动态库,又称共享库,libxxx.so,在运行时将库加载到可执行程序中。
优点:可执行程序小。
缺点:程序的运行环境中必须提供相应的库。

·
库的好处:①代码保密、②方便部署和分发、③库是别人写好的现有的、成熟的、可以复用的代码,可以使用但要记得遵守许可协议、④不同的应用程序 如果调用相同的库,那么在内存里只需要有一份该动态库的实例

一、静态库的制作

为什么要做静态库:
国内的企业,掌握有核心技术,同时是又希望更多的程序员来使用其技术,因此采用"闭源"的方式开发使用
在企业开发中,一些核心技术或者常用框架,出于安全性和稳定性的考虑,也会提供静态库给程序员使用

情景如下:我们写了若干个.c代码,这些.c代码组合起来能够完成一个计算器的功能。
03Linux下静态库和动态库(共享库)的制作与使用_第1张图片
但如果我们想要编译这个main.c文件得到可执行文件的话,就必须加上加减乘除的每个源文件才行。不然会出现下面的情况:03Linux下静态库和动态库(共享库)的制作与使用_第2张图片
这个问题与链接器(ld)在编译链接过程中找不到函数的定义有关。
得加上加减乘除的源文件才可以编译:gcc main.c div.c add.c mult.c sub.c -o main

现在我们将加减乘除的四个源文件生成为一个静态库

在这里插入图片描述

  • 1、输入命令生成四个.o文件:gcc add.c sub.c mult.c div.c -c(若是head.h文件不在当前路径,可以使用命令gcc -c add.c sub.c mult.c div.c -I ./include/这样可以确保编译器能够正确找到相关的头文件。)
  • 生成结果如下所示:
    在这里插入图片描述
  • 2、对.o文件打包
  • 生成的静态库是的名称为libcalc.a,输入如下命令进行.o文件的打包,生成名为libcalc.a的静态库
  • ar rcs libcalc.a add.o div.o mult.o sub.o
    在这里插入图片描述
    ar rcs libcalc.a add.o div.o mult.o sub.o
    -c: create的意思
    -r: replace的意思,表示当插入的模块file.o已经存在libfile.a中,则覆盖。
    -s:在库文件中创建一个索引表索引表可以提高链接速度。

至此,就完成了静态库的制作。

二、静态库的使用

静态库的编译:
我们先使用tree命令查看libcalc.a静态库的位置
03Linux下静态库和动态库(共享库)的制作与使用_第3张图片
使用命令:gcc main.c -o main -L. -lcalc 就可以生成main执行文件了
-L指定静态函数库的位置供查找,注意L后面还有’.',表示静态函数库在本目录下查找。
-l则指定了静态函数库名,由于静态函数库的命名方式是lib
***.a,其中的lib和.a忽略。

打印结果如下:
03Linux下静态库和动态库(共享库)的制作与使用_第4张图片

03Linux下静态库和动态库(共享库)的制作与使用_第5张图片

之后删除libaddsub.a后main依然可以运行,因为静态库的内容已经整合进去了。

最后如果你从别处得到一个静态库文件libxxx.a,想知道其中包含哪些模块。
可以使用命令ar -t libxxx.a就可以查看静态库中包含了哪些模块
03Linux下静态库和动态库(共享库)的制作与使用_第6张图片

三、动态库的制作

动态加载库
动态库最大的优点,是将链接推迟到运行时,由于运行时才链接动态库,这就给链接的目标留下了选
择的空间。结合以上工程需求,可以让程序在运行的时候,为其指定要链接的动态库,以达到可以按
需链接动态库的目的,这种做法称为动态库的动态加载。

依旧使用静态库的例子:
当前文件分布如下:
03Linux下静态库和动态库(共享库)的制作与使用_第7张图片

  • 1、输入命令生成四个.o文件:gcc -c add.c sub.c mult.c div.c -I ./include/
  • -I :重新指定要搜索的文件目录。
    03Linux下静态库和动态库(共享库)的制作与使用_第8张图片
    2、执行下面的指令gcc -shared -fPIC *.o -o libCalc.so生成动态链接库
    -fPIC:产生位置与代码无关
    -shared:生成共享库

    *.o:本路径下的所有.o文件
    03Linux下静态库和动态库(共享库)的制作与使用_第9张图片

四、动态库的使用

1、得到了一个可用的动态库之后,将其与相应的头文件放到一个目录中(就相当于发布了),
然后根据得到的头文件编写测试代码,对动态库中的函数进行调用。
把生成的动态库和相应的头文件放到temp文件夹中进行测试。

03Linux下静态库和动态库(共享库)的制作与使用_第10张图片

2、执行下面的指令gcc main.c -o main -L. -l Calc生成执行文件main
03Linux下静态库和动态库(共享库)的制作与使用_第11张图片
到这一步就证明你已经成功90%了,但是现在我们运行执行文件main的时候会发现报错提示:

在这里插入图片描述
该错误提示表明在执行可执行文件main时,系统无法找到名为libCalc.so的共享对象文件

解决方法:

①、 libCalc.so放到/usr/lib 或/lib中去。因为在动态函数库使用时,会查找/usr/lib 和 /lib目录下的动态函数库,而此时我们生成的库不在里边。
执行命令sudo cp libCalc.so /lib将我们的动态库添加到lib目录中去
03Linux下静态库和动态库(共享库)的制作与使用_第12张图片
现在我们在执行./main 就可以实现使用动态库了03Linux下静态库和动态库(共享库)的制作与使用_第13张图片

②、第二种方法 假设我们的libfile.so在/home/linux/file 环境变量方法
export LD_LIBRARY_PATH=/home/linux/file:$LD_LIBRARY_PATH

PATH:用于设置可执行程序的查找路径
LD_LIBRARY_PATH:用于设置动态库的查找路径

03Linux下静态库和动态库(共享库)的制作与使用_第14张图片

或者直接在temp目录下面使用命令export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH也可以实现

③、在/etc/ld.so.conf文件里加入我们生成的库的目录
避免直接将动态库拷贝到系统的/lib目录下,而是将动态库所在的路径添加到系统的库配置文件中。可以在/etc/ld.so.conf.d目录下创建一个新的配置文件(例如mylib.conf),并将动态库的路径添加到该文件中,然后运行sudo ldconfig命令更新动态库缓存。

在这里插入图片描述
在这里插入图片描述
通过临时管理员权限进入添加我们动态库的路径:
在这里插入图片描述
在这里插入图片描述
保存退出,在动态库的目录下执行命令sudo ldconfig就可以使用动态库了
03Linux下静态库和动态库(共享库)的制作与使用_第15张图片

最后在比较一下通过链接静态库和动态库出来的执行文件

静态库的执行文件:在这里插入图片描述

动态库的执行文件:
在这里插入图片描述

可以看到,通过动态库生成的执行文件没有静态库生成的执行文件的内存占用大。

你可能感兴趣的:(Linux文件IO,linux,服务器)