什么是库文件
一般来说,一个程序,通常都会包含目标文件和若干个库文件。经过汇编得到的目标文件再经过和库文件的链接,就能构成可执行文件。库文件像是一个代码仓库或代码组件的集合,为目标文件提供可直接使用的变量、函数、类等。
库文件包含了静态链接库和动态链接库两种。两者最根本的区别在与在程序编译的过程中,如何处理库文件和目标文件的链接关系。
静态链接库
静态链接库在Linux系统中以.a文件的形式存在。
在上图程序编译的链接阶段,静态库会完全复制到可执行文件中,一旦可执行文件构建完成,就不再需要静态库的存在,可执行文件在后续的使用中,也不再依赖这个静态库。
动态链接库
虽然静态库非常容易理解且不会引入依赖问题,但是试想一下,如果你在统筹构建一个无比庞大的工程,这时,其中一个开发者升级了他所开发的库。这时,你就需要花费很长的时间来重新构建这个如此庞大的工程。这时,你就可以使用动态库来避免这个问题。
动态库在程序编译的**链接阶段,仅将一些重要的信息,如重定位和符号表信息复制到可执行文件中,**可执行文件在后面执行的过程中,如果需要引用这个库文件,就会根据这些信息从系统中寻找对应的库文件以实现对应的功能。
静态库和动态库的区别
区别 | 静态库 | 动态库 |
---|---|---|
可执行文件大小 | 较大 (因为动态库的内容会被完全复制到可执行文件中) | 较小 |
占用磁盘大小 | 较大 (如果有多个可执行文件都用到同一个静态库,这个静态库会被多次复制到不同的可执行文件中) | 较小 (即使多个可执行文件都需要用到同一个动态库,他们也只是共用同一个动态库文件) |
扩展性与兼容性 | 全量更新 (库文件的更新会引起整个可执行文件的重新编译及发布) | 增量更新 (不需要重新编译可执行文件,只需发布动态库文件) |
依赖问题 | 无依赖问题 (已构建的可执行文件不依赖其他静态库文件) | 有依赖问题 (可执行文件的执行需要系统存在依赖的动态库文件) |
复杂程度 | 简单 | 复杂 (会引起很多问题,例如如何在运行时确定地址,库文件版本管理等) |
加载速度 | 快 | 慢 |
CMake 中 target_link_libraries 的 PRIVATE,PUBLIC 和 INTERFACE 的区别
情况 | 使用参数 |
---|---|
只有源文件(.cpp)中包含了库文件 | PRIVATE |
只有头文件(.hpp)中包含了库文件 | INTERFACE |
源文件和头文件都包含了库文件 | PUBLIC |
这里只是简单介绍了以下,具体的细节和解析请参考《CMake学习笔记.md》
参考链接
CMake教程(二)- 添加静态库文件和动态库文件