目录
为什么要有库?
库的存在是为了提高软件开发的效率、促进代码复用以及简化维护工作。通过使用库可以有效地屏蔽不同系统之间的差异。
静态库
什么是静态库?
静态库(Static Library)是一种在编译时就将库的代码和数据链接到可执行文件中的库。与动态库不同,静态库的内容是在构建最终程序的过程中直接嵌入到应用程序里的。这意味着每个使用该静态库的应用程序都会包含一份完整的库代码副本。在Linux/Unix系统中,静态库一般以
.a
为扩展名(来自“archive”的缩写)
特点
- 编译时链接:当编译器生成最终的可执行文件时,它会将静态库中所需的函数和数据复制到可执行文件中。
- 独立性:一旦应用程序被编译并链接了静态库,那么这个应用程序就可以独立运行,不需要外部库文件的支持。
- 大小:由于每个使用相同静态库的应用程序都包含了库的一份完整拷贝,这可能导致生成的可执行文件体积较大。
- 更新不便:如果静态库中的某个函数需要更新或修复,那么所有依赖于该库的应用程序都需要重新编译和链接以获得最新的版本。
- 性能:因为所有的代码都在一个可执行文件内,所以在某些情况下,静态链接可能提供更好的性能,因为它避免了运行时查找和加载共享库的开销。
优点
- 简单部署:不需要担心目标系统上是否安装了正确的库版本。
- 一致性:保证了应用使用的库版本不会因外部因素而改变。
- 可靠性:对于关键任务的应用来说,静态链接可以减少对系统环境的依赖,从而提高稳定性。
缺点
- 存储空间:多个应用程序如果使用相同的静态库,则会占用更多的磁盘空间,因为每个程序都有自己的库副本。
- 维护成本:每次库更新都需要重新编译所有依赖它的应用程序。
- 内存使用:在多进程环境中,如果多个进程都使用相同的静态库,那么这些库的代码会在内存中重复出现,消耗更多内存资源。
动态库
什么是动态库?
动态库(Dynamic Library),也被称为共享库(Shared Library),是一种可以在程序运行时加载的代码和数据集合。与静态库不同,动态库在编译时并不直接链接到可执行文件中,而是在程序运行时由操作系统根据需要加载到内存中,并且可以被多个程序同时使用。这种方式减少了磁盘空间的占用,同时也使得库的更新更加方便,因为不需要重新编译所有依赖该库的应用程序。在Linux和类Unix系统中,动态库通常以
.so
(Shared Object)为扩展名。
优点
- 节省内存:多个应用程序可以共享同一份库文件的单一实例。
- 易于升级:如果库文件被修复或升级了,那么所有依赖它的应用程序都可以立即受益,而无需重新编译。
- 灵活性:可以在程序运行时决定加载哪些库,甚至可以选择性地加载库中的特定功能。
缺点
- 兼容性问题:如果库进行了不向后兼容的更改,可能会导致依赖它的旧版本程序无法正常工作。
- 性能影响:由于库是在运行时加载的,因此可能会有一些额外的性能开销。
- 部署复杂性:需要确保目标系统上存在正确的库版本,并且位于正确的路径下。
编译器会选择哪个库?
- 如果同时提供动态库和静态库,gcc 默认使用的是动态库,如果非要用静态库,必须使用 static 选项;
- 如果只提供了静态库,可执行程序只能使用静态链接,但是程序不一定整体是静态链接;
- 如果只提供了动态库,默认只能动态链接,非得静态链接的话会发生链接错误。