【Linux】动静态库

内容回顾

  • 静态库是指后缀为.a的库文件,windows下为.lib
  • 动态库是指后缀为.so的库文件,windows下为.dll

使用

当一个文件要使用静态库的时候,它需要将它想使用的静态库的部分内容拷贝进自己的文件,然后再执行自己的程序。

当一个文件要使用动态库的时候,当它执行到库函数时,会跳转到动态库中,找到该函数的.o文件,去链接标准库中库函数的.o文件,最后再跳转回来。

正是因为两种库的差距,所以一般使用动态库的文件占用空间会比静态库小。

静态库

如何制作静态库

如果我们想自己写一个静态库,该怎么做?

我们知道,对于任何一个库,都至少包含了一个头文件。这头文件的作用是提供库的使用方法(相当于使用说明书)。而真实的库文件,是二进制代码,库的作者可以选择不公开,只提供使用,不让库的使用者看到具体的代码。

准备工作

如果我们要创建一个静态库,首先需要一个头文件。

下一步是要写对应的方法。

此时,我们已经具备制作一个库的全部条件了(准备好配菜了),接下来就是进行具体的制作(进厨房加工)。

处理

想要将一个文件变成可执行程序,需要做的是:预处理,编译,汇编,链接。

而这里,我们首先需要将源文件打包成一个二进制文件,也就是.o文件。

我们执行红色框中的指令,最后可以得到黄色框中的.o文件。

注意白色框,可以看到,我们所做的一切都是在mylib目录下的。我们在这个目录下制作了一个库。

如何使用静态库

此时我创建了一个classmate的目录,目的是模拟别人使用库的情况。

此时可以看到这个classmate目录里什么都没有。

此时,我们把别人目录下的.o和.h文件都拿过来了。相当于把我需要的都拿过来了。

.h用于告诉我库的使用方法。

.o是库的具体实现方案。

这一步就是编写程序,并且使用别人的库

多个静态库文件一起打包

如果我今天写了很多个静态库文件,该如何打包?

  • 指令 ar -rc libname.a 待打包的库文件.o
  • 作用:将所有待打包的库文件制作成静态库

 1.创建源文件

上面这一系列操作表示我写了两个头文件和源文件,并且,将这两个文件都制作成.o文件了。

接下来,我将使用ar指令将这些.o文件打包制作成一个静态库。

2.将.o文件生成静态库

接下来将我们的静态库打包给别人用,可以使用makefile一步到位

这一步的意义是:

  1. make指令,一步将所有的.c源文件编译成.o文件,并且制作成静态库
  2. make ouput执行,一步创建三个目录,分别是总的目录myliba和myliba下的两个子目录include和lib。并将,h文件都放在include目录下,将.a文件都放在lib目录下。

效果:

3.将静态库压缩打包

  • tar指令:tar czf 打包文件.tgz 被打包的文件
  • 作用:用于打包压缩
  • czf表示:c--打包, z--压缩, f--指定打包后的文件名

使用打包好的静态库

这里的将myliba.tgz从其他地方拿过来和解压缩,就像是从网上下载库一样。

写好test.c文件,准备使用库

make的时候报错,说找不到头文件。

明明已经弄好库了,怎么可能找不到呢? --就在下面,myliba里面

方法1:直接将第三方库安装在系统的默认路径下

这种方法类似于我们安装软件,使用gcc的时候,它会自动去系统默认路径下搜索所需要的头文件和库文件,也就是C语言标准库所在的路径。

  • 头文件默认搜索路径:/usr/include;
  • 库文件默认搜索路径:/usr/lib64;

因此,我们只需要将头文件和库文件安装到系统默认的路径下就行了。

到usr/include目录下就可以看到我们的.h文件了

同时,在usr/lib64目录下也能看到我们的静态库了

接下来直接像使用以前的静态库一样使用我们的静态库就行了。

直接make之后报错说找不到Add。这是因为,gcc不知道要链接默认路径库里的哪个库(找不到使用接口的定义 -- 代表是库出问题了)

我们需要告诉编译器使用的库的名字是什么就行了。

指令:gcc -o test test.c -lmylib

mylib是libmylib.a掐头去尾的结果,也是库真实的名字。

涉及一个问题:为什么我们使用stdio这样的库的时候,gcc时就不需要加上-l呢?

---- 因为那不是第三方库,是官方提供的库,系统能够默认认识,所以不需要特别指明。

方法2:告诉编译器就头文件路径,库路径,库名

但是,我们所写的第三方库并没有经过验证,如果直接放到系统的默认路径下,很可能导致污染系统的其他库和头文件。所以,我们可以采用第二种方式:

                                                                        自己指定

也可以将上述指令写入makefile,这样就不用每次都这么繁琐了。

动态库

如何制作动态库

拥有前面的基础,这里就直接使用makefile文件一键生成

这是目前所拥有的源文件和头文件,直接生成.o文件制作成动态库

使用指令之后得到如下结果:

接下来,打包动态库,将动态库压缩,就可以拿给别人用了。

如何使用动态库

此时我作为使用者,将别人的mylibso.tgz下载到我的目录下了。我该如何使用呢?

使用方法有四种。下面分别讲解

1.安装到默认路径(永久)

像静态库一样,直接将文件解压缩,安装到系统gcc执行的默认路径

头文件:usr/include

库文件:usr/lib64

2.将库文件路径放在环境变量里(暂时)

这一步是将我们的文件和库文件进行链接。

可以看到,我们链接的步骤是正确的,并没有报错。

生成的文件是这样的:

接下来我们直接运行文件:

出现报错:显示找不到动态库

这里需要说明,为什么静态库进行到上一步可以直接运行,而动态库却不行?显示找不到动态库?

因为如果使用静态库,是将内容直接拷贝到文件中

如果使用动态库,是将内容链接到文件中

所以我们之前所做的 gcc -o test test.c -I ……是在告诉gcc编译器,我们需要链接哪个文件,但是,编译完成之后就和gcc没有关系了。真正运行程序的时候就是要操作系统去动态库中找我们用到的内容。

但是,我们并没有告诉操作系统,我们的动态库在哪里,所以找不到。

告诉操作系统动态库在哪里:

        在执行程序的时候,操作系统会从环境变量LD_LIBRARY_PATH中读取动态库的路径。

所以,我们只需要将动态库的路径放入到LD_LIBRAY_PATH中就行了。

3.将库文件路径放在配置文件中(永久)

/etc/ld.so.conf.d/路径下有很多的配置文件

创建一个文件,文件名随意,但是后缀必须是conf。

最后将动态库的路径放到这个.conf文件中

sudo ldconfig -- 更新配置文件

4.软链接到系统默认搜索路径中

系统中装库的路径是usr/lib64

所以我们只需要将我们的动态库软链接到usr/lib64中,就可以直接使用了。

用ldd也可以看到test配置了动态链接

相关推荐

  1. Linux静态

    2024-03-26 01:44:05       18 阅读
  2. Linux静态

    2024-03-26 01:44:05       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-26 01:44:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-26 01:44:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-26 01:44:05       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-26 01:44:05       20 阅读

热门阅读

  1. 递归——N皇后

    2024-03-26 01:44:05       18 阅读
  2. Python中图片的切块与合并

    2024-03-26 01:44:05       16 阅读
  3. 深度学习中一些常见的问题

    2024-03-26 01:44:05       18 阅读
  4. 【C++】学习记录--condition_variable 的使用

    2024-03-26 01:44:05       18 阅读
  5. Docker部署springboot项目

    2024-03-26 01:44:05       18 阅读
  6. sql jdbc测试

    2024-03-26 01:44:05       16 阅读
  7. Android adb命令发送广播介绍

    2024-03-26 01:44:05       16 阅读
  8. C++初阶:浅识内存管理

    2024-03-26 01:44:05       17 阅读
  9. leetcode2549--统计桌面上的不同数字

    2024-03-26 01:44:05       19 阅读