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

库是预先编译好的代码集合,包含可重复使用的函数、类或资源,可以被多个程序共享使用。
+-------------------+ +-----------------+
| 你的源代码 | --> | 编译器 |
| (main.c) | | |
+-------------------+ +-----------------+
|
v
+-------------------+ +-----------------+
| 静态库 | --> | 链接器 |
| (libmath.a) | | (静态链接) |
+-------------------+ +-----------------+
|
v
+-------------------+ +-----------------+
| 独立的可执行文件 | | 包含库代码的 |
| (program) | | 完整副本 |
+-------------------+ +-----------------+步骤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的库+-------------------+ +-----------------+
| 你的程序 | | 动态库 |
| (program) | | (libmath.so) |
+-------------------+ +-----------------+
| |
| 运行时加载 |
+--------->+<--------------+
|
v
+---------------+
| 内存中 |
| 共享的库代码 |
+---------------+步骤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) | 动态库 (.so) |
|---|---|---|
文件扩展名 | .a (Archive) | .so (Shared Object) |
链接时机 | 编译时 | 运行时 |
内存使用 | 每个程序都包含库的副本 | 多个程序共享内存中的同一副本 |
磁盘空间 | 可执行文件较大 | 可执行文件较小,但需要额外的库文件 |
更新维护 | 需要重新编译整个程序 | 只需替换库文件(保持ABI兼容) |
加载速度 | 启动快(代码已在内存中) | 启动稍慢(需要加载库) |
运行时依赖 | 无外部依赖 | 需要库文件存在且版本兼容 |
版本控制 | 简单(包含在程序中) | 复杂(需要版本管理) |
创建命令 | ar rcs libname.a *.o | gcc -shared -o libname.so *.o |
编译选项 | 不需要特殊选项 | 需要-fPIC生成位置无关代码 |
# 使用静态链接:部署简单,但占用更多磁盘和内存
gcc -static webserver.c -lssl -lcrypto -o webserver_static
# 使用动态链接:节省资源,但需要确保目标系统有相应库
gcc webserver.c -lssl -lcrypto -o webserver_dynamic
# 查看可执行文件依赖的库
ldd program
# 查看库中的符号
nm libmath.so
nm libmath.a
# 查看库的详细信息
readelf -d libmath.so# 创建带版本的动态库
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 program1. 编译时指定的 -L 路径
2. 环境变量 LD_LIBRARY_PATH
3. /etc/ld.so.cache 中的缓存(由ldconfig维护)
4. 默认路径:/lib, /usr/lib, /lib64, /usr/lib64# 解决方案:
sudo ldconfig # 更新库缓存
# 或
export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH# 检查当前加载的库版本
ldd program | grep libmath
# 创建符号链接指向正确的版本
ln -sf libmath.so.2.0.0 libmath.so.2通过理解这两种库技术的优缺点和适用场景,你可以根据具体需求做出最合适的选择,构建高效、可维护的Linux应用程序。