原文链接:静态库和动态库 - 简书
前言:库是已写好的、供使用的可复用代码,每个程序都要依赖很多基础的底层库。从本质上,库是一种可执行代码的二进制形式。可以被操作系统载入内存执行。库分为两种:静态库(.a .lib)和 动态库 (.so .dll)。所谓的静态、动态指的是 链接的过程。
一、静态库和动态库的标准定义
1、静态库
①后缀名:Linux下.a
,Windows下.lib
1.1 简介
之所以称之为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o 与 引用的库一起链接到可执行文件中。对应的链接方式称为 静态链接。
如果多个进程需要引用到【静态库】,在内存中就会存在多份拷贝。
1.2【静态库】的特点:
①静态库对函数库的链接是在编译期完成的。执行期间代码装载速度快。
②使可执行文件变大,浪费空间和资源(占空间)。
③对程序的更新、部署与发布不方便,需要全量更新。如果某一个静态库更新了,所有使用它的应用④程序都需要重新编译、发布给用户。
2、动态库
①后缀名:Linux下.so
,Windows下.dll
1.1 简介
在程序编译时并不会链接到目标代码中,而是在运行时才被载入。不同的应用程序如果调用相同的库,那么在内存中只需要有一份该共享库的实例,避免了空间浪费问题。同时也解决了静态库对程序的更新的依赖,用户只需更新动态库即可。gcc在编译时默认使用动态库。
1.2 动态库分类(根据动态库的载入时间 load time )
1.动态链接库: 在启动 app 时立刻将动态库进行加载 (随程序启动而启动)
2.动态加载库: 当需要的时候再使用 dlopen 等通过代码或者命令的方式来加载 (在程序启动之后)
以上行为是由动态链接器 (Dynamic linker, 简称 dyld) 来完成
1.3【动态库】的特点:
①动态库把对一些库函数的链接载入推迟到程序运行时期(占时间)。
②可以实现进程之间的资源共享。(因此动态库也称为共享库)
③将一些程序升级变得简单,不需要重新编译,属于增量更新。
二、系统移植时的静态和动态编译
在系统移植过程中,一般情况下会使用静态编译来编译内核(kernel)和 U-Boot,而根文件系统则通常会使用动态编译。
当系统移植时,选择静态编译内核和 U-Boot 的原因主要是为了提高系统的可靠性和稳定性,而选择动态编译根文件系统的原因则是为了减小可执行文件的大小并方便系统的维护和更新。以下是更具体的解释:
-
内核和 U-Boot 的静态编译:
- 可靠性和稳定性: 将内核和 U-Boot 静态编译成独立的可执行文件,可以确保它们在系统引导过程中不依赖外部的共享库。这样可以避免因为共享库的变化或版本不匹配而导致的引导问题,提高系统的可靠性和稳定性。
- 简化引导过程: 静态编译的内核和 U-Boot 可以直接加载并运行,无需在引导过程中加载额外的共享库。这样可以简化引导过程,加快系统启动速度。
-
根文件系统的动态编译:
- 减小可执行文件的大小: 使用动态链接库可以将系统所需的库文件分开,避免将所有内容都静态链接到一个大型可执行文件中。这样可以减小根文件系统的大小,节省存储空间。
- 方便系统的维护和更新: 动态链接库可以在不影响系统其他部分的情况下进行更新。这样可以方便系统的维护和更新,要更新其中一个可执行文件,动态链接库允许你只更新需要修改的应用程序或库文件,而不影响其他部分。同时也有助于减小系统的更新包大小。
总的来说,选择静态编译内核和 U-Boot 是为了提高系统的可靠性和稳定性,而选择动态编译根文件系统则是为了减小可执行文件的大小并方便系统的维护和更新。这样做可以更好地满足系统移植的需求,提高系统的性能和可维护性。