Linux 之 【基础I/O】(动静态库的制作与使用、ar、ldconfig)
**目录** 1.静态库 1.1静态库的概念特点与静态链接 1.2静态库的创建与使用 创建静态库 ar 使用静态库 makefile文件 静态库的安装 2.动态库 2.1动态库的概念特点与动态链接 2.2动态库的创建与使用 创建动态库 使用动态库(形成可执行文件) 动态库的搜索路径 使用动态库(配置动态库路径) ldconfig * * 将我们所实现的方法给别人用有以下两种方式: > **提供源码…
**目录** 1.静态库 1.1静态库的概念特点与静态链接 1.2静态库的创建与使用 创建静态库 ar 使用静态库 makefile文件 静态库的安装 2.动态库 2.1动态库的概念特点与动态链接 2.2动态库的创建与使用 创建动态库 使用动态库(形成可执行文件) 动态库的搜索路径 使用动态库(配置动态库路径) ldconfig * * 将我们所实现的方法给别人用有以下两种方式: > **提供源码…
将我们所实现的方法给别人用有以下两种方式:
**提供源码文件(.h 头文件 + .c 源文件)。使用者需要重新编译,但能看到你的实现代码,优点是可调试、可修改、跨平台适应性好(源码可以在用户环境中针对特定平台重新编译),缺点是暴露实现细节,编译时间长提供库文件(.h 头文件 + .a/.so/.lib/.dll 库文件)。**使用者直接链接,看不到源代码,优点是保护知识产权,编译快,版本控制方便,缺点是调试困难(未知实现),平台依赖性强(架构等绑定问题:x64库不能在ARM上运行)
**头文件的本质是库的说明书,它告诉编译器有什么,
没有头文件,编译器就无法生成正确的函数调用代码**
静态库是一个包含多个已编译目标文件的归档文件,通常用于代码复用
在不同系统中有不同的格式和扩展名:
Linux/Unix: .a 文件(Archive,由 ar 命令创建)
Windows: .lib 文件(Library)
macOS: .a 或 .framework(框架包含静态库)
静态库的特点
静态库命名约定(去掉前后缀)
格式:lib<名称>.a
示例:libmath.a、libutils.a
链接时使用:-lmath 会自动查找 libmath.a
静态链接链接的是静态库,静态链接发生在编译的最后阶段,主要步骤:
源代码 → 编译 → 目标文件(.o) + 静态库(.a) → 链接器 → 可执行文件
# 1. 编译源文件为目标文件 gcc -c file1.c file2.c -o file1.o file2.o # 2. 打包成静态库 ar rcs libmylib.a file1.o file2.o
编译不链接,生成目标文件:gcc -c 只编译源文件为独立的可重定位目标文件(.o),不进行链接操作
打包加索引,创建静态库:ar rcs 将多个目标文件打包成归档文件(.a)并建立符号索引,供链接器快速查找。
ar(archive)是 Unix/Linux 系统上的归档管理工具,主要用于创建、修改和提取静态库文件(.a 文件)
ar 有以下核心功能
创建静态库:将多个目标文件(.o)打包成单个归档文件
维护库内容:可添加、删除、替换库中的目标文件
提取文件:从库中提取单个或多个目标文件
ar [选项] <库文件名> <目标文件列表>
常用参数说明
| 参数 | 全称 | 作用 |
|---|---|---|
r | replace | 插入文件到归档(替换已存在的) |
c | create | 创建新归档(如不存在) |
s | write index | 创建/更新符号表索引 |
t | table/list | 列出归档内容 |
x | extract | 从归档提取文件 |
d | delete | 从归档删除文件 |
v | verbose | 显示详细操作信息 |
标准链接法(需要路径查找)
gcc main.c -L. -lmylib 告诉链接器:在当前目录(-L.)查找名为libmylib.a的库并链接。特点:
直接链接法(无需路径查找)
gcc main.c libmylib.a 直接将静态库文件当作输入文件,编译器知道如何从其中提取需要的符号。特点:
**gcc默认在系统目录和当前目录下寻找.h头文件,
但只在系统目录下寻找库文件(除非用-L指定当前目录)**
gcc main.c -I ./lib/include(指定头文件路径)-L ./lib/mymathlib(库的路径)-l(指定哪一个库,库名称)
此时的可执行文件能直接运行,这是因为静态库函数的实现已拷贝至可执行文件中
#库名称 dy-lib=libmymethod.so static-lib=libmymath.a #一次性形成一个动态库与一个静态库 .PHONY:all all:$(dy-lib) $(static-lib) #制作动态库 $(dy-lib):mylog.o myprint.o gcc -shared -o $@ $^ mylog.o:mylog.c gcc -fPIC -c $^ myprint.o:myprint.c gcc -fPIC -c $^ #制作静态库 $(static-lib):mymath.o ar -rc $@ $^ #将.o文件打包成库文件的命令,replace and create mymath.o:mymath.c gcc -c $^ #自动形成同名的.o文件 #清理文件 .PHONY:clean clean: rm -rf *.o *.a *.so mylib #创建新目录存放自定义库 .PHONY:output output: mkdir -p mylib/include mkdir -p mylib/lib cp *.h mylib/include cp *.a mylib/lib cp *.so mylib/lib
(1)直接复制到系统目录(将静态库和头文件直接安装到系统标准目录,让编译器和链接器在默认搜索路径中找到它们)
# 1. 安装头文件到系统include目录 sudo cp /path/to/mymath.h /usr/include/ # 或更好位置 sudo cp /path/to/mymath.h /usr/local/include/ # 2. 安装静态库到系统库目录 sudo cp /path/to/libmymath.a /usr/lib64/ # 或 sudo cp /path/to/libmymath.a /usr/local/lib/ # 3. 直接使用库名链接 gcc main.c -lmymath -o program
(2)创建软连接到系统目录(在系统目录中创建软链接(快捷方式)指向实际的库文件和头文件,避免复制文件,便于更新)
# 1. 创建头文件目录的软链接 sudo ln -s /actual/path/to/include /usr/include/project_inc # 2. 创建静态库文件的软链接 sudo ln -s /actual/path/to/libmymath.a /usr/lib64/libmymath.a # 3. 使用库名链接 gcc main.c -I/usr/include/project_inc -lmymath -o program # 或如果系统已配置搜索/usr/include gcc main.c -lmymath -o program
动态库是一种在程序运行时才被加载的代码库,也称为:共享库、动态链接库
文件格式:
Linux/Unix: .so (Shared Object)
Windows: .dll (Dynamic-Link Library) + .lib (导入库)
macOS: .dylib (Dynamic Library)
动态库的特点
动态库通过运行时链接和代码共享机制实现了显著的内存节省和灵活的模块化开发,其核心优势在于允许多个程序共享同一份库代码副本、支持独立更新维护、促进跨语言调用和降低开发耦合度;然而这些优势也带来了运行时依赖、加载性能开销、版本兼容性复杂性和部署依赖性等挑战,形成了典型的空间换时间和灵活性换复杂性的权衡
动态库命名约定(去掉前后缀)
格式:lib<名称>.so(Linux/Unix)或 lib<名称>.dylib(macOS)
示例:libmath.so、libutils.so
链接时使用:-lmath 会自动查找 libmath.so
动态链接链接的是动态库,在编译时建立程序与动态库的"调用约定",在运行时由操作系统动态加载库并完成地址绑定,实现代码的共享和延迟加载
main.c → 编译 → main.o → 链接器 + libmath.so引用 → program(包含math的调用桩) → 运行时动态链接器加载libmath.so并绑定真实地址 → 运行
# 编译为位置无关代码 gcc -fPIC -c math.c -o math.o gcc -fPIC -c utils.c -o utils.o # 创建动态库 gcc -shared -o libmymath.so math.o utils.o # 或一步完成 gcc -fPIC -shared math.c utils.c -o libmymath.so
编译为位置无关代码:gcc -fPIC -c 将源代码编译成可在内存任意位置执行的目标文件,为动态库创建基础组件
创建动态库:gcc -shared 将多个位置无关的目标文件打包成单个可在运行时被多个程序共享的动态库文件
一步完成方式:gcc -fPIC -shared 直接从源代码生成动态库,将编译和链接合并为单个步骤,简化创建过程
-fPIC(Flag Position Independent Code):生成位置无关代码,使代码可在内存任意地址加载执行
动态库在运行时会被加载到内存的任意空闲地址,无法预先知道具体位置。因此必须生成能在任何地址正确执行的代码,所以需要-fPIC
# 编译程序(链接动态库) gcc main.c -L. -lmymath -o program
使用编译器时指定的-L和-l选项是为了让链接器在编译时找到动态库,验证符号存在并建立引用关系(确认:1. 调用的函数确实存在于某个库中;2. 建立程序到该库的调用链接框架)。
此时的可执行文件并不能直接运行,这是因为动态库函数调用地址绑定未完成,需要运行时重定位
运行时需要通过LD_LIBRARY_PATH或系统配置告诉操作系统的动态链接器(加载器)动态库的实际位置,以完成地址绑定和代码加载
Linux 搜索顺序:LD_LIBRARY_PATH 环境变量指定的目录/etc/ld.so.cache 中缓存的路径(由 ldconfig 维护)默认目录:/lib, /usr/lib, /usr/local/lib
Windows 搜索顺序:程序所在目录系统目录(C:\Windows\System32)PATH 环境变量指定的目录
(1)安装到系统目录
将动态库直接复制到 /lib64 或 /usr/lib64 等系统标准库目录
# 1. 复制动态库到系统目录 sudo cp /path/to/libmymath.so /usr/local/lib/ # 2. 更新动态库缓存 sudo ldconfig # 3. 直接使用(不需要额外路径) gcc main.c -lmymath -o program ./program
(2)创建系统软链接
# 1. 创建软链接(库文件保持原位置) sudo ln -s /home/user/project/lib/libmymath.so /usr/lib/libmymath.so # 2. 可选择更新缓存 sudo ldconfig # 3. 使用方式不变 gcc main.c -lmymath -o program ./program
(3)设置环境变量
# 1. 临时设置(当前终端有效) export LD_LIBRARY_PATH=/home/user/project/lib:$LD_LIBRARY_PATH # 2. 编译运行 gcc main.c -L/home/user/project/lib -lmymath -o program ./program # 3. 永久设置(用户级) echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/user/project/lib' >> ~/.bashrc source ~/.bashrc # 4. 永久设置(系统级,不推荐) sudo echo '/home/user/project/lib' > /etc/profile.d/mylib.sh
(4)配置系统路径
# 1. 创建配置文件 sudo nano /etc/ld.so.conf.d/mylib.conf # 内容:/home/user/project/lib # 2. 更新动态库缓存 sudo ldconfig # 3. 验证是否生效 ldconfig -p | grep mymath # 4. 使用(系统已识别路径) gcc main.c -L/home/user/project/lib -lmymath -o program ./program
ldconfig 是用于管理动态链接器运行时绑定的工具,主要功能是扫描系统库目录、创建共享库缓存,加速动态库的查找速度
主要功能:创建/更新缓存 # 扫描配置的目录,生成 /etc/ld.so.cache sudo ldconfig

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online