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)
动态库版本冲突 程序依赖的动态库版本系统中安装的版本不一致 安装程序所需版本的动态库 ,或重新编译程序使其适配系统中的库版本
相关推荐
Harvy_没救了3 小时前
【Linux】循环语句
linux·运维
小比特_蓝光3 小时前
Linux----进程概念
linux·运维·服务器
大卡片3 小时前
Linux进程基础
linux·运维·服务器
ShineWinsu3 小时前
对于Linux:“一切皆文件“以及缓冲区的解析
linux·运维·c++·面试·笔试·缓冲区·一切皆文件
LinuxRos4 小时前
I2C子系统与驱动开发:从协议到实战
linux·人工智能·驱动开发·嵌入式硬件·物联网
Mark White4 小时前
深入理解 Linux 打印体系:CUPS、驱动、ULD 与 Docker 容器化
linux·运维·docker
没头脑的男大4 小时前
宇树的自己电脑的适配
linux·服务器·网络
IMPYLH4 小时前
Linux 的 paste 命令
linux·运维·服务器·bash
Kk.08024 小时前
Linux(十三)fork + exec进程创建
linux·运维·服务器