当前位置: 首页 > news >正文

linux库的制作

一、库文件介绍

维度内容
定义一组预先编译好的函数、类或数据的集合,以文件形式存在,用于被其他程序调用
本质可执行代码的二进制形式,是代码复用的一种方式,将常用功能封装起来,方便开发者在不同项目中使用
作用1.提高开发效率:避免重复编写相同功能的代码,减少开发时间
2.便于代码维护:集中管理功能模块,修改和升级库时只需更新库文件,无需修改使用库的程序
3.保护代码隐私:将核心代码封装在库中,只提供接口供外部使用,隐藏实现细节
分类说明
库的分类静态库和共享库(动态库)
跨平台问题不同平台(如 Linux vs Windows)的指令集、二进制格式、系统调用不同,导致库无法跨平台直接使用(如 Linux 的 .so 不能在 Windows 上运行)
Linux平台静态库命名libxxx.a(以 lib 为前缀 + 自定义库名 + .a 后缀
Linux平台动态库命名libxxx.so(以 lib 为前缀 + 自定义库名 +.so 后缀
动态库版本命名libxxx.so.x.y.z,其中x 为主版本号(不兼容旧版),y 为次版本号(兼容旧版),z 为发行版本号(修复问题不影响接口)

二、静态库介绍及制作

2.1 静态库介绍

在静态链接方式下,最终生成的可执行文件不仅包含程序本身的编译后代码,还包含了所依赖的静态库1和静态库2的全部被使用到的代码

维度内容
定义静态库在程序编译链接阶段,其代码会被完整地“复制”到最终生成的可执行文件中,成为可执行文件的一部分。编译完成后,静态库与可执行文件“绑定”,运行时无需额外依赖
特点1.可执行文件独立运行,不依赖外部库文件
2.静态库会使可执行文件体积较大,但效率比较高
3.若静态库更新,需重新编译链接程序
文件格式Windows平台为 .lib,Linux平台为 .a,Mac平台为 .a

2.2 静态库制作及使用

步骤说明示例命令
准备源文件编写实现库功能的源文件(如 .c 或 .cpp)-
编译生成目标文件使用编译器将源文件编译成目标文件(如 .o 或 .obj)gcc -c 源文件.c -o 目标文件.o
打包生成静态库使用归档工具将目标文件打包成静态库ar -cr 静态库.a 目标文件.o
编译主程序并链接静态库

编译主程序并链接静态库,生成可执行文件。

若库名为 libmyadd.a,则库名写 myadd,编译器自动拼接 lib 前缀和 .a 后缀查找库文件

gcc 目标文件.o -l库名 -L库路径 -o 可执行文件

最后一步可执行文件不需要加后缀

2.3 静态库所用核心选项

工具选项作用示例命令
GCC-c只编译不链接,生成目标文件(.o)gcc -c add.c -o add.o
GCC-o指定输出文件名称gcc -c main.c -o main.o
GCC-l指定要链接的库名(省略lib前缀和.a后缀)gcc main.c -lmyadd -o main
GCC-L指定库文件搜索路径gcc main.c -L./lib -lmyadd -o main
AR-c创建新的归档文件(静态库)ar -cr libmyadd.a add.o
AR-r目标文件添加到归档文件中(替换已存在的文件)ar -cr libmyadd.a add.o

三、动态库介绍及制作

3.1 动态库介绍

动态链接仅在运行时调用动态库可执行文件体积小且便于库更新,但需确保运行时库文件存在且版本兼容。调用动态库的时候是用库的符号表进行调动

维度内容
定义动态库也称之为共享库,是在程序运行时才被加载到内存中,可以被多个可执行文件共享使用,为它们提供函数、数据等资源
特点1.可执行文件运行时,需依赖系统中存在的动态库
2.可执行文件体积小(只记录的动态库的引用,没有记录全部的库)有效节省磁盘和内存空间
3.更新灵活,只要接口不变,无需重新编译依赖它的可执行文件
文件格式Windows平台为 .dll,Linux平台为 .so,Mac平台为 .dylib

3.2 动态库制作及使用

步骤说明示例命令
准备源文件编写实现库功能的源文件(如 .c 或 .cpp)-
编译生成与位置无关的目标文件使用编译器编译源文件时,添加 -fPIC 选项生成位置无关代码(PIC)的目标文件gcc -c -fPIC 源文件.c -o 目标文件.o
链接生成动态库使用编译器将目标文件链接为动态库,多个程序可共享同一份动态库文件,节省内存gcc -shared 目标文件.o -o 动态库.so
编译时链接动态库

编译时通过 -L 指定路径、-l 指定库名生成可执行文件

库名不包含前缀和后缀

gcc 源文件.c -l库名 -L库路径 -o 可执行文件

可能还需要创建符号链接,动态库版本管理中的可选步骤,用于为带版本号的动态库(如 libxxx.so.1.0.0)创建简化的符号链接(如 libxxx.so),方便编译时查找。

3.3 加载动态库方法

运行时加载动态库方法说明示例操作
LD_LIBRARY_PATH环境变量通过环境变量临时指定库搜索路径export LD_LIBRARY_PATH=$PWD
/etc/ld.so.conf配置文件编辑配置文件添加库路径,然后更新缓存sudo vim /etc/ld.so.conf(添加路径),然后sudo ldconfig
系统默认路径库放入系统默认目录,更新缓存通过mv命令:系统级库放/usr/lib,用户自定义库放/usr/local/lib,然后sudo ldconfig
运行时加载动态库方法优点缺点
LD_LIBRARY_PATH环境变量方便临时测试,无需修改系统配置仅对当前终端生效,不持久,可能被滥用
/etc/ld.so.conf配置文件系统级生效,永久有效,影响所有用户需要 root 权限
系统默认路径简单直接,无需额外配置可能污染系统库目录,与包管理器管理的库冲突

3.4 动态库所用核心选项

工具选项作用示例
gcc(编译阶段)-c只编译不链接,生成目标文件(.o),不生成可执行程序gcc -c add.c -o add.o
gcc(编译阶段)-fPIC生成位置无关代码(PIC),确保动态库可被加载到内存任意地址并正常运行(动态库必需)gcc -c -fPIC add.c -o add.o
gcc(编译阶段)-o指定输出文件名称(如目标文件.o或动态库.so)gcc -c -fPIC add.c -o add.o
gcc(链接阶段)-shared目标文件(.o)链接为动态库(.so),是生成动态库的核心选项gcc -shared add.o -o libmyadd.so
gcc(使用阶段)-L定动态库的搜索路径(编译时用于查找 .so 文件)gcc main.c -lmyadd -L./lib -o main
gcc(使用阶段)-l指定要链接的动态库名称(省略lib前缀和.so后缀,如 libmyadd.so 对应 -lmyadd)gcc main.c -lmyadd -L. -o main
系统工具ldconfig更新系统动态库缓存,使新添加的动态库(如放入/usr/lib)被系统识别(需sudo权限)sudo ldconfig

-static 表示静态链接

四、静态库与动态库的区别

对比维度静态库动态库
链接方式编译时链接运行时链接
可执行文件体积体积大体积小
内存占用多个程序使用时,每个程序都有一份库的副本,占用内存多多个程序共享同一份库,内存中只有一份副本,节省内存
更新维护更新需重新编译链接程序库更新只需替换库文件,无需重新编译链接程序
依赖性运行时依赖运行时依赖,库缺失程序无法运行
适用场景适合对程序独立性要求高、库不常更新、且对可执行文件启动速度有要求的场景适合库需要频繁更新、多个程序共享库功能、且希望减小可执行文件体积的场景

静态库在程序运行的时候不需要在系统中,因为静态库编译时已链接到程序,运行时无需依赖

静态库与动态库的核心差异在于链接时机。

五、库制作常见问题及解决方案

问题类型可能原因解决方法
静态库链接时提示未定义的引用库文件路径错误、库名拼写错误、库中确实不存在该函数或变量的定义检查库路径和库名是否正确,确认库中是否实现了所需功能
动态库运行时提示无法找到库文件库文件路径未加入系统默认搜索路径未通过环境变量指定动态库复制到系统默认库路径(如 /usr/local/lib),或设置相应的环境变量(如 Linux 的 LD_LIBRARY_PATH)
动态库版本冲突程序依赖的动态库版本系统中安装的版本不一致安装程序所需版本的动态库,或重新编译程序使其适配系统中的库版本
http://www.jsqmd.com/news/637588/

相关文章:

  • 从Deduction到Induction:探索中西思维差异在AI发展中的映射
  • 递归、搜索与回溯算法(专题二:深搜)
  • ConvNeXt 系列改进:ConvNeXt 用于视频行为识别:3D ConvNeXt 改进与 Kinetics 实验
  • 告别Pyppeteer安装烦恼:手动下载Chromium并指定路径的保姆级教程
  • 为什么91%的AIAgent代码生成项目在POC后流产?奇点大会首席架构师亲授“生成-验证-归档”黄金三角工作流(含自动化测试覆盖率阈值表)
  • 不只是下载器:把aria2打造成你的Windows 11自动化下载中心(支持批量、代理与脚本集成)
  • 2026年3月必看!市场口碑好的铁皮螺旋风管公司评测推荐,行业内铁皮螺旋风管实力厂家哪家好安庆茗力通风工程市场认可度高 - 品牌推荐师
  • Termwind与Laravel完美集成:构建专业级控制台命令
  • 英飞凌iLLD封装库实战指南:从基础配置到高级应用
  • AIAgent个性化辅导系统在SITS2026真实课堂中的效果跃升47%(附学情归因模型与教师干预阈值表)
  • 注意力机制模块:顶会 TGRS 2026:LSK 注意力(大核选择)复现与 YOLOv8 集成实验
  • vLLM本地缓存实战,重复提交直接复用不浪费算力
  • 磐维数据库PanWeiDB单机多实例部署详解:用户隔离、端口规划与目录结构最佳实践
  • 2026年知名的1688托管运营/1688托管运营装修靠谱公司推荐 - 品牌宣传支持者
  • 二叉搜索树、二叉排序树(查找、插入和删除)——Java版本
  • STM32G474的ADC实战避坑:从CubeMX配置到代码调试,手把手教你精准采集3.3V电压
  • 一丹一世界FLUX.1图像生成服务:支持移动端触控的7861 WebUI部署全流程
  • Java-二叉排序树
  • 如何部署TinyRecursiveModels:生产环境中的7个关键步骤与最佳实践
  • 别再死记硬背Bagging了!用狼人杀和Python代码,5分钟搞懂随机森林的‘投票’精髓
  • Datadog 发布 OpenTelemetry Go 自动插桩工具
  • 如何优化AutoTrain Advanced多模态模型部署:模型拆分与推理加速完整指南
  • 终极指南:Open Images边界框标注技术详解——600+对象类别的精确定位方案
  • 2026届必备的五大AI学术网站解析与推荐
  • 告别环境冲突!用Anaconda在PyCharm里为PyTorch项目创建独立的CUDA环境(保姆级图文)
  • Rust模块系统深度解析
  • 别再只用AES-ECB了!手把手教你用Python复现CTF经典攻击,从密文块反推HTTP请求
  • 如何解决宝塔面板7.x升级到8.x后部分插件不兼容报错_在插件商店重装受影响插件以适配新Python环境
  • Google Earth Engine(GEE)——沿海国家高程数据库(CoNED)
  • 【IET出版】第十一届信息科学、计算机技术与交通运输国际学术会议(ISCTT 2026)