【Linux】16. 动静态库

简介: 【Linux】16. 动静态库

1. 库概念的引出

在这里插入图片描述
在这里插入图片描述
但是如果只是单纯的将多个.o文件提供给使用者,那么如果.o文件过多链接就会变得非常复杂,于是我们考虑将所有的.o文件打包给使用者提供一个库文件即可。
库的本质就是.o文件的集合

2. 动静态库概念

在之前的学习过程中我们认识到动静态链接会生成对应的库类型
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

3. 静态库

3.1 静态库的生成

在这里插入图片描述
在这里插入图片描述

我们执行如下命令:

[hx@hx dynamic_static_lib]$ tar czf mylib.tgz mylib
[hx@hx dynamic_static_lib]$ ll
total 56
-rw-rw-r-- 1 hx hx 3296 Jun 22 13:03 libmymath.a
-rw-rw-r-- 1 hx hx  231 Jun 20 19:25 main.c
-rw-rw-r-- 1 hx hx  303 Jun 22 13:38 makefile
-rw-rw-r-- 1 hx hx  120 Jun 20 19:15 my_add.c
-rw-rw-r-- 1 hx hx   67 Jun 20 19:16 my_add.h
-rw-rw-r-- 1 hx hx 1544 Jun 22 13:03 my_add.o
drwxrwxr-x 4 hx hx 4096 Jun 22 13:39 mylib
-rw-rw-r-- 1 hx hx  940 Jun 22 14:46 mylib.tgz
-rwxrwxr-x 1 hx hx 8568 Jun 20 19:38 mymath
-rw-rw-r-- 1 hx hx  117 Jun 20 19:17 my_sub.c
-rw-rw-r-- 1 hx hx   64 Jun 20 19:17 my_sub.h
-rw-rw-r-- 1 hx hx 1544 Jun 22 13:03 my_sub.o

将库文件和头文件打包压缩,形成.tgz文件将其上传到yum资源当中或者发布到XXX网站上
使用者就可以通过访问网站/资源的方式来获取到

3.2 静态库的使用

3.2.1 指定当前路径下编译使用

在这里插入图片描述
那为啥不需要告诉编译器头文件需要链接哪个头文件,而是只是告诉编译器头文件路径即可,因为我们在代码编译时(#include "my_add.h")
已经告诉编译器了我们所要包含的头文件是啥了
在这里插入图片描述
==所以如果要链接第三方库,就一定要指明库的名称==
那为啥编写C语言/C++时,我们不需要指明库名称呢? -- 因为gcc(编译C语言) g++(编译C++) 编译器本身就知道链接库的名称
在这里插入图片描述

3.2.2 添加到系统路径下使用(安装)

在这里插入图片描述
这种方式其本质也叫做库的安装
软件的安装其实也是一个道理,将软件添加到对应的系统路径下
在学习的过程中不太推荐,因为目前编写的大多是测试/小程序没有经过严格的测试和发布这些流程,所以不推荐将自己写的库直接安装到系统当中

4. 动态库

4.1 动态库的生成

在这里插入图片描述

4.2 动态库的使用

在这里插入图片描述
==那么如何告诉OS自定义库的位置呢?==

  1. 拷贝.so文件到系统共享库路径下, 一般指/usr/lib (安装 --> 现阶段不太推荐将自己写的安装到系统共享库中 )
  2. 添加到环境变量LD_LIBRARY_PATH当中(一次性)
    系统在搜索库文件路径时,除了在系统默认的库路径下查找之外还会在环境变量LD_LIBRARY_PATH当中查找
    在这里插入图片描述
    但是当我们将机器退出后,再运行又无法找到,原因是因为自定义的环境变量只在本次登录有效
  3. 配置/etc/ld.so.conf.d/,ldconfig更新
    在这里插入图片描述
  4. 给运行程序建立软链接
    在这里插入图片描述

    5. 使用外部库

    使用外部库
    系统中其实有很多库,它们通常由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况
    的函数(ncurses库)
    #include <math.h>
    #include <stdio.h>
    int main(void)
    {
         
         
    double x = pow(2.0, 3.0);
    printf("The cubed is %f\n", x);
    return 0;
    }
    gcc -Wall calc.c -o calc -lm
    
    -lm表示要链接libm.so或者libm.a库文件

6. 动态库的加载

静态库是不会加载到内存当中的,在链接时静态库就是将其方法拷贝到对应的调用处,当后续程序在运行的过程当中就不再依赖静态库。
但是如果静态库当中的方法被不同的文件调用,会在内存中出现重复的代码(浪费空间)
链接时发生的拷贝会拷贝到虚拟地址空间的代码区当中,(程序在未编译形成之前,编译器也会按照虚拟地址空间的方式划分区域,对应的拷贝就是存放到代码区),所以未来这部分代码必须通过相对确定的地址位置来进行访问
在这里插入图片描述

动态库命令的理解:

  1. 为啥形成.o文件要带-fPIC选项 是因为会生成位置无关码,可以理解为形成的函数地址不是绝对编址,只是相对编址的方案
  2. -shell 打包形成动态库格式 ,方便操作系统以库方式加载

当内存中存在100个可执行程序,都使用的是同一个库的话,那么只需要将这一个库加载到内存当中即可(节约内存空间)

相关文章
|
5天前
|
存储 编译器 Linux
动态链接的魔法:Linux下动态链接库机制探讨
本文将深入探讨Linux系统中的动态链接库机制,这其中包括但不限于全局符号介入、延迟绑定以及地址无关代码等内容。
|
4月前
|
安全 Linux vr&ar
Linux的动态库和静态库
Linux的动态库和静态库
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
110 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
4月前
|
Linux API
在Linux中,程序产生了库日志虽然删除了,但磁盘空间未更新是什么原因?
在Linux中,程序产生了库日志虽然删除了,但磁盘空间未更新是什么原因?
|
5月前
|
Oracle 关系型数据库 Linux
讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
通过这一连串的步骤,可以专业且有效地在Linux下为Qt编译Oracle驱动库 `libqsqloci.so`,使得Qt应用能够通过OCI与Oracle数据库进行交互。这些步骤适用于具备一定Linux和Qt经验的开发者,并且能够为需要使用Qt开发数据库应用的专业人士提供指导。
169 1
讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
|
4月前
|
Linux 网络安全 API
【Azure 应用服务】App Service For Linux 环境中,如何从App Service中获取GitHub私有库(Private Repos)的Deploy Key(RSA key)呢?
【Azure 应用服务】App Service For Linux 环境中,如何从App Service中获取GitHub私有库(Private Repos)的Deploy Key(RSA key)呢?
|
4月前
|
小程序 Linux 开发者
Linux之缓冲区与C库IO函数简单模拟
通过上述编程实例,可以对Linux系统中缓冲区和C库IO函数如何提高文件读写效率有了一个基本的了解。开发者需要根据应用程序的具体需求来选择合适的IO策略。
37 0
|
6月前
|
存储 Linux C语言
Linux|如何安装和运行多个 glibc 库
Linux|如何安装和运行多个 glibc 库
1253 5
|
6月前
|
Linux 编译器 C语言
Linux中的pkg-config:简化库依赖管理的利器
**pkg-config**是Linux下管理库依赖的工具,它通过读取库的`.pc`文件提供编译和链接参数。使用`pkg-config --cflags --libs &lt;library&gt;`获取编译和链接选项,例如`gcc -o test test.c $(pkg-config --cflags --libs glib-2.0)`。能进行版本检查、参数提取、依赖管理和路径搜索。列出所有包用`pkg-config --list-all`。最佳实践包括确保库正确安装、检查版本、配置`PKG_CONFIG_PATH`及使用构建工具。
|
6月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
51 1