🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习 🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发 ❄️作者主页:一个平凡而乐于分享的小比特的个人主页 ✨收录专栏:Linux,本专栏目的在于,记录学习Linux操作系统的总结 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

Linux动态库与静态库技术详解
一、库的基本概念
什么是库?
库是预先编译好的代码集合,包含可重复使用的函数、类或资源,可以被多个程序共享使用。
库的两种主要形式:
二、静态库(Static Libraries)
1. 工作原理
+——————-+ +—————–+
| 你的源代码 | –> | 编译器 |
| (main.c) | | |
+——————-+ +—————–+
|
v
+——————-+ +—————–+
| 静态库 | –> | 链接器 |
| (libmath.a) | | (静态链接) |
+——————-+ +—————–+
|
v
+——————-+ +—————–+
| 独立的可执行文件 | | 包含库代码的 |
| (program) | | 完整副本 |
+——————-+ +—————–+
2. 创建和使用静态库
步骤1:编译源文件为目标文件
gcc -c add.c -o add.o
gcc -c subtract.c -o subtract.o
步骤2:创建静态库
# 使用ar命令创建静态库
ar rcs libmath.a add.o subtract.o
# 命令解释:
# ar – 归档工具
# r – 替换或添加文件到归档
# c – 创建归档(如果不存在)
# s – 创建索引
步骤3:使用静态库
gcc main.c -L. -lmath -o program
# -L. 指定库搜索路径(当前目录)
# -lmath 链接名为libmath.a的库
三、动态库(Shared Libraries)
1. 工作原理
+——————-+ +—————–+
| 你的程序 | | 动态库 |
| (program) | | (libmath.so) |
+——————-+ +—————–+
| |
| 运行时加载 |
+———>+<————–+
|
v
+—————+
| 内存中 |
| 共享的库代码 |
+—————+
2. 创建和使用动态库
步骤1:编译位置无关代码
# -fPIC 生成位置无关代码(Position Independent Code)
gcc -c -fPIC add.c -o add.o
gcc -c -fPIC subtract.c -o subtract.o
步骤2:创建动态库
# -shared 创建共享库
gcc -shared -o libmath.so add.o subtract.o
步骤3:使用动态库
# 编译时链接动态库
gcc main.c -L. -lmath -o program
# 设置运行时库搜索路径
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./program
四、详细对比表格
| 文件扩展名 | .a (Archive) | .so (Shared Object) |
| 链接时机 | 编译时 | 运行时 |
| 内存使用 | 每个程序都包含库的副本 | 多个程序共享内存中的同一副本 |
| 磁盘空间 | 可执行文件较大 | 可执行文件较小,但需要额外的库文件 |
| 更新维护 | 需要重新编译整个程序 | 只需替换库文件(保持ABI兼容) |
| 加载速度 | 启动快(代码已在内存中) | 启动稍慢(需要加载库) |
| 运行时依赖 | 无外部依赖 | 需要库文件存在且版本兼容 |
| 版本控制 | 简单(包含在程序中) | 复杂(需要版本管理) |
| 创建命令 | ar rcs libname.a *.o | gcc -shared -o libname.so *.o |
| 编译选项 | 不需要特殊选项 | 需要-fPIC生成位置无关代码 |
五、实际场景示例
场景1:Web服务器部署
# 使用静态链接:部署简单,但占用更多磁盘和内存
gcc -static webserver.c -lssl -lcrypto -o webserver_static
# 使用动态链接:节省资源,但需要确保目标系统有相应库
gcc webserver.c -lssl -lcrypto -o webserver_dynamic
场景2:软件更新
#mermaid-svg-msdArhewRAQWyjfT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-msdArhewRAQWyjfT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-msdArhewRAQWyjfT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-msdArhewRAQWyjfT .error-icon{fill:#552222;}#mermaid-svg-msdArhewRAQWyjfT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-msdArhewRAQWyjfT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-msdArhewRAQWyjfT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-msdArhewRAQWyjfT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-msdArhewRAQWyjfT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-msdArhewRAQWyjfT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-msdArhewRAQWyjfT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-msdArhewRAQWyjfT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-msdArhewRAQWyjfT .marker.cross{stroke:#333333;}#mermaid-svg-msdArhewRAQWyjfT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-msdArhewRAQWyjfT p{margin:0;}#mermaid-svg-msdArhewRAQWyjfT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-msdArhewRAQWyjfT .cluster-label text{fill:#333;}#mermaid-svg-msdArhewRAQWyjfT .cluster-label span{color:#333;}#mermaid-svg-msdArhewRAQWyjfT .cluster-label span p{background-color:transparent;}#mermaid-svg-msdArhewRAQWyjfT .label text,#mermaid-svg-msdArhewRAQWyjfT span{fill:#333;color:#333;}#mermaid-svg-msdArhewRAQWyjfT .node rect,#mermaid-svg-msdArhewRAQWyjfT .node circle,#mermaid-svg-msdArhewRAQWyjfT .node ellipse,#mermaid-svg-msdArhewRAQWyjfT .node polygon,#mermaid-svg-msdArhewRAQWyjfT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-msdArhewRAQWyjfT .rough-node .label text,#mermaid-svg-msdArhewRAQWyjfT .node .label text,#mermaid-svg-msdArhewRAQWyjfT .image-shape .label,#mermaid-svg-msdArhewRAQWyjfT .icon-shape .label{text-anchor:middle;}#mermaid-svg-msdArhewRAQWyjfT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-msdArhewRAQWyjfT .rough-node .label,#mermaid-svg-msdArhewRAQWyjfT .node .label,#mermaid-svg-msdArhewRAQWyjfT .image-shape .label,#mermaid-svg-msdArhewRAQWyjfT .icon-shape .label{text-align:center;}#mermaid-svg-msdArhewRAQWyjfT .node.clickable{cursor:pointer;}#mermaid-svg-msdArhewRAQWyjfT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-msdArhewRAQWyjfT .arrowheadPath{fill:#333333;}#mermaid-svg-msdArhewRAQWyjfT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-msdArhewRAQWyjfT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-msdArhewRAQWyjfT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-msdArhewRAQWyjfT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-msdArhewRAQWyjfT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-msdArhewRAQWyjfT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-msdArhewRAQWyjfT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-msdArhewRAQWyjfT .cluster text{fill:#333;}#mermaid-svg-msdArhewRAQWyjfT .cluster span{color:#333;}#mermaid-svg-msdArhewRAQWyjfT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-msdArhewRAQWyjfT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-msdArhewRAQWyjfT rect.text{fill:none;stroke-width:0;}#mermaid-svg-msdArhewRAQWyjfT .icon-shape,#mermaid-svg-msdArhewRAQWyjfT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-msdArhewRAQWyjfT .icon-shape p,#mermaid-svg-msdArhewRAQWyjfT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-msdArhewRAQWyjfT .icon-shape rect,#mermaid-svg-msdArhewRAQWyjfT .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-msdArhewRAQWyjfT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-msdArhewRAQWyjfT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-msdArhewRAQWyjfT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
软件v1.0
发现bug在库中
静态库方式
动态库方式
重新编译整个程序
发布100MB的更新包
只更新2MB的库文件
所有程序自动使用修复后的库
六、高级主题
1. 查看库信息
# 查看可执行文件依赖的库
ldd program
# 查看库中的符号
nm libmath.so
nm libmath.a
# 查看库的详细信息
readelf -d libmath.so
2. 版本控制
# 创建带版本的动态库
gcc -shared -Wl,-soname,libmath.so.1 -o libmath.so.1.0.1 *.o
ln -s libmath.so.1.0.1 libmath.so.1
ln -s libmath.so.1 libmath.so
# 设置rpath(避免设置LD_LIBRARY_PATH)
gcc -Wl,-rpath,'/usr/local/lib' main.c -lmath -o program
3. 库搜索路径顺序
1. 编译时指定的 -L 路径
2. 环境变量 LD_LIBRARY_PATH
3. /etc/ld.so.cache 中的缓存(由ldconfig维护)
4. 默认路径:/lib, /usr/lib, /lib64, /usr/lib64
七、实践建议
何时使用静态库?
- 需要独立部署,不依赖目标系统环境
- 对性能要求极高,避免运行时加载开销
- 库很小,静态链接不会显著增加程序大小
- 嵌入式系统,资源有限,运行时加载复杂
何时使用动态库?
- 库会被多个程序共享使用
- 需要频繁更新库而不重新编译程序
- 减少磁盘和内存使用量很重要
- 开发大型系统,模块化设计
八、常见问题解决
问题1:“libxxx.so: cannot open shared object file”
# 解决方案:
sudo ldconfig # 更新库缓存
# 或
export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH
问题2:版本冲突
# 检查当前加载的库版本
ldd program | grep libmath
# 创建符号链接指向正确的版本
ln -sf libmath.so.2.0.0 libmath.so.2
问题3:ABI兼容性
- 保持公共API稳定
- 添加新函数而不是修改现有函数
- 使用版本脚本控制符号可见性
九、最佳实践总结
通过理解这两种库技术的优缺点和适用场景,你可以根据具体需求做出最合适的选择,构建高效、可维护的Linux应用程序。



