什么是库文件?
单一模型:将程序中所有功能全部实现于一个单一的源文件内部。编译时间长,不易于维护和升级,不易于协作开发。
分离模型:将程序中的不同功能模块划分到不同的源文件中。缩短编译时间,易于维护和升级,易于协作开发。
可以简单地把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。
代码复用,避免重复造轮子!提高开发效率!(。-ω-)zzz
1、静态库和动态库的本质区别
(*^▽^*) 是 链接时机 !
- 静态库 是"++编译时打包++ ":++编译器会把库代码完整复制到可执行文件中++,生成的程序像个"自给自足的胖子",不依赖外部文件,但体积大、更新麻烦。
- 动态库 是"++运行时调用++ ":++程序运行时才去加载库文件++,多个程序能共用同一份库,像个"灵活的共享仓库",体积小、更新方便,但少了库就跑不起来。
链接静态库就是链接器将库中被调用的代码复制到调用模块中。
链接动态库就是链接器在调用模块的调用语句处嵌入一段进入调用函数入口地址的指令。
2、关键差异
| 对比维度 | 静态库 | 动态库 |
|---|---|---|
| 可执行文件大小 | 较大(包含库代码) | 较小(仅包含调用接口) |
| 运行依赖 | 无(独立运行) | 必须存在对应库文件 |
| 内存占用 | 多个程序运行时重复占用内存 | 多个程序共享同一份内存 |
| 更新方式 | 改库后必须重新编译整个程序 | 直接替换库文件即可生效 |
| 启动速度 | 较快(无需运行时加载) | 稍慢(需动态链接) |
3、不同系统下的格式
| 系统 | 静态库格式 | 动态库格式 | 避坑提示 |
|---|---|---|---|
| Windows | .lib | .dll | .lib可能是静态库或"导入库"(仅用于链接.dll),别搞混! |
| Linux | .a | .so | 命名必须以lib开头(如libxxx.a),版本号藏在.so后面(如libssl.so.1.1) |
| macOS | .a | .dylib | 系统库常用.framework格式,本质是包含动态库的文件夹 |
4、使用场景
-
如果你在开发一个小巧的工具、需要极致性能的系统组件、或者希望部署简单到只有一个文件 ,选择静态库。
-
如果你在开发一个大型应用、操作系统组件、需要被多个程序共享的公共库,或者希望支持插件架构 ,选择动态库。
-
在实际项目中,通常是混合使用,将一些核心的、稳定的、或对性能要求极高的模块静态链接,而将一些大的、可选的、或需要独立更新的模块作为动态库。
5、Linux下的静态库操作
构建

ar命令
ar [选项] <静态库文件> <目标文件列表>
-r :将目标插入到静态库中,已存在则更新
使用



6、Linux下的动态库操作
-fpic 和 -fPIC 都是用于生成位置无关代码 的编译器选项,主要用于创建共享库(动态库)。
position independent code
-
-fPIC:通用、安全、推荐使用 -
-fpic:在某些特定情况下可能有优化,但兼容性较差 -
使用场景:主要用于创建共享库(动态库)
-
黄金法则 :当不确定时,总是使用
-fPIC
在现代系统中,-fPIC 和 -fpic 的性能差异通常很小,因此为了更好的兼容性,建议始终使用 -fPIC。

编译、链接合并成一步:
bash
gcc -shared -c -fPIC calc.c show.c -o libmath.so
运行前必须告诉系统动态库在哪:
bash
export LD_LIBRARY_PATH=&LD_LIBRARY_PATH:.
可参考资料