Linux 之 【基础I/O】(动静态库的制作与使用、ar、ldconfig)

目录

1.静态库

1.1静态库的概念特点与静态链接

1.2静态库的创建与使用

创建静态库

ar

使用静态库

makefile文件

静态库的安装

2.动态库

2.1动态库的概念特点与动态链接

2.2动态库的创建与使用

创建动态库

使用动态库(形成可执行文件)

动态库的搜索路径

使用动态库(配置动态库路径)

ldconfig


将我们所实现的方法给别人用有以下两种方式:

提供源码文件(.h 头文件 + .c 源文件)。使用者需要重新编译,但能看到你的实现代码,优点是可调试、可修改、跨平台适应性好(源码可以在用户环境中针对特定平台重新编译),缺点是暴露实现细节,编译时间长提供库文件(.h 头文件 + .a/.so/.lib/.dll 库文件)。使用者直接链接,看不到源代码,优点是保护知识产权,编译快,版本控制方便,缺点是调试困难(未知实现),平台依赖性强(架构等绑定问题:x64库不能在ARM上运行)
头文件的本质是库的说明书,它告诉编译器有什么,

没有头文件,编译器就无法生成正确的函数调用代码

1.静态库

1.1静态库的概念特点与静态链接

静态库是一个包含多个已编译目标文件的归档文件,通常用于代码复用

在不同系统中有不同的格式和扩展名:
Linux/Unix: .a 文件(Archive,由 ar 命令创建)
Windows: .lib 文件(Library)
macOS: .a 或 .framework(框架包含静态库)

静态库的特点

  • 编译时链接:库代码在程序编译时被直接复制到最终的可执行文件中
  • 独立运行:生成的可执行文件不依赖外部库文件
  • 体积较大:相同库代码在每个使用它的程序中都有副本
  • 部署简单:只需分发可执行文件,不需要在系统上安装额外的库文件
  • 更新困难:库更新需要重新编译链接所有使用它的程序
  • 加载快,但占用更多磁盘/内存

静态库命名约定(去掉前后缀)
格式:lib<名称>.a
示例:libmath.a、libutils.a
链接时使用:-lmath 会自动查找 libmath.a

静态链接链接的是静态库静态链接发生在编译的最后阶段,主要步骤

源代码 → 编译 → 目标文件(.o) + 静态库(.a) → 链接器 → 可执行文件

1.2静态库的创建与使用

创建静态库

# 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

ar(archive)是 Unix/Linux 系统上的归档管理工具,主要用于创建、修改和提取静态库文件(.a 文件)
ar 有以下核心功能
创建静态库:将多个目标文件(.o)打包成单个归档文件
维护库内容:可添加、删除、替换库中的目标文件
提取文件:从库中提取单个或多个目标文件
ar [选项] <库文件名> <目标文件列表>

常用参数说明

参数全称作用
rreplace插入文件到归档(替换已存在的)
ccreate创建新归档(如不存在)
swrite index创建/更新符号表索引
ttable/list列出归档内容
xextract从归档提取文件
ddelete从归档删除文件
vverbose显示详细操作信息

使用静态库(形成可执行文件)

标准链接法(需要路径查找)
gcc main.c -L. -lmylib 告诉链接器:在当前目录(-L.)查找名为libmylib.a的库并链接。特点:
  • -L. 指定库搜索路径(.表示当前目录)
  • -lmylib 会自动查找 libmylib.a(自动添加lib前缀和.a后缀)
  • 如果不在-L指定目录或系统默认库目录,链接器会报错找不到库
直接链接法(无需路径查找)
gcc main.c libmylib.a 直接将静态库文件当作输入文件,编译器知道如何从其中提取需要的符号。特点:
  • 直接把库文件当作普通输入文件处理
  • 不依赖任何搜索路径,直接定位库文件
  • 即使库在当前目录,也不需要 -L.
  • 库不在当前目录,指明路径即可
gcc默认在系统目录和当前目录下寻找.h头文件,

但只在系统目录下寻找库文件(除非用-L指定当前目录)
gcc main.c -I ./lib/include(指定头文件路径)-L ./lib/mymathlib(库的路径)-l(指定哪一个库,库名称)
此时的可执行文件能直接运行,这是因为静态库函数的实现已拷贝至可执行文件中

makefile文件

#库名称 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

2.动态库

2.1动态库的概念特点与动态链接

动态库是一种在程序运行时才被加载的代码库,也称为:共享库、动态链接库

文件格式:
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并绑定真实地址 → 运行

2.2动态库的创建与使用

创建动态库

# 编译为位置无关代码 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

    ldconfig 是用于管理动态链接器运行时绑定的工具,主要功能是扫描系统库目录、创建共享库缓存,加速动态库的查找速度
    主要功能:创建/更新缓存 # 扫描配置的目录,生成 /etc/ld.so.cache sudo ldconfig
    • 读取 /etc/ld.so.conf 和 /etc/ld.so.conf.d/*.conf
    • 扫描所有配置目录中的 .so 文件
    • 创建二进制缓存文件 /etc/ld.so.cache
    • 加速运行时库查找(避免每次遍历目录)

    Read more

    AI入门系列:AI入门者的困惑:常见术语解释与误区澄清

    AI入门系列:AI入门者的困惑:常见术语解释与误区澄清

    引言 人工智能领域充满了令人困惑的专业术语和概念误区。对于刚接触AI的新手而言,机器学习、深度学习、神经网络这些名词常常让人一头雾水。很多初学者会将AI简单地等同于机器人,或者误以为AI已经具备人类水平的思维能力。实际上,AI是一个包含多个子领域的广阔学科,每个术语都有其特定的含义和应用范围。理解这些基础概念的区别,避免常见的认知误区,是踏入AI世界的第一步。本文将系统梳理AI领域的核心术语,澄清普遍存在的误解,帮助初学者建立正确的认知框架,为后续的深入学习打下坚实基础。 AI到底是什么?从科幻到现实的转变 很多人一听到AI,就想到《终结者》里的天网或者《黑客帝国》里的矩阵。但实际上,AI远比这些科幻场景要"接地气"得多。 想象一下,当你对手机说"嘿,Siri,明天天气怎么样?",手机能够理解你的话,查找天气信息,并用语音回答你。这就是AI在工作,它包含了语音识别、自然语言处理、信息检索等多个技术。 AI的本质是让机器完成那些过去只有人类才能完成的任务。但这并不意味着机器要变得像人一样思考,而是让机器在特定任务上表现得像人一样聪明。 误区澄清:

    By Ne0inhk

    最新龙虾AI(OpenClaw v2026.3.8)全平台部署教程|零报错、高安全,新手也能10分钟上手

    最近OpenClaw龙虾AI爆火,作为开源可私有化部署的AI智能体,它区别于普通聊天AI,能“动手”完成跨应用自动化任务——整理微信消息、定时提醒、浏览器自动化等,实用性拉满。但不少开发者反馈,网上教程多为旧版本,且忽略了工信部最新安全预警,部署时频繁出现权限报错、闪退、盗版捆绑等问题。 本文基于2026年3月10日官方最新稳定版(v2026.3.8),结合Windows、macOS、Linux、手机端(安卓/鸿蒙)四大平台,详细拆解“新手一键部署”“进阶自定义部署”“Ollama本地模型对接”全流程,同步规避工信部预警提到的安全风险,全程复制命令即可操作,新手也能零失败完成部署。 一、部署前必看:核心认知+环境准备(避坑第一步) 1.1 龙虾AI核心定位(必懂) OpenClaw龙虾AI是开源免费的本地AI执行网关,核心优势是“数据本地存储、全平台兼容、自动化执行”,无需上传数据到第三方平台,

    By Ne0inhk
    别让 AI 越权!OpenClaw 权限配置完全指南

    别让 AI 越权!OpenClaw 权限配置完全指南

    一、限制只能聊天(纯对话模式) 适用场景:只想让 AI 帮你思考、写文案、做分析,不需要它执行任何文件操作或命令。 从 2026.3.2 版本开始,OpenClaw 默认已经收紧了权限,但如果你想确保它彻底无法调用工具,可以这样配置: 核心配置命令: bash openclaw config set tools.profile messaging tools.profile 的四种模式对比: 表格 模式能力范围适用场景messaging纯对话,禁用所有工具(文件读写、命令执行、技能调用等)只想聊天、咨询的场景minimal极简工具集(如只允许网页搜索)需要查信息但不执行操作default基础工具集(文件读写、部分命令)日常轻度使用full完整工具集(包括高风险操作)开发、自动化等场景 验证配置: bash openclaw config

    By Ne0inhk
    告别“选择困难症”:我是如何用 AI Ping 实现大模型自由,还能省下 50% 成本的?

    告别“选择困难症”:我是如何用 AI Ping 实现大模型自由,还能省下 50% 成本的?

    告别“选择困难症”:我是如何用 AI Ping 实现大模型自由,还能省下 50% 成本的? * 写在最前面 * 场景一:从“写脚本卡壳”到“批量生成” * 场景二:开发路上的“万能插头” * 使用感受 * 一点小建议与期待 * 写在最后 🌈你好呀!我是 是Yu欸🚀 感谢你的陪伴与支持~ 欢迎添加文末好友🌌 在所有感兴趣的领域扩展知识,不定期掉落福利资讯(*^▽^*) 写在最前面 版权声明:本文为原创,遵循 CC 4.0 BY-SA 协议。转载请注明出处。 在这个大模型“百花齐放”甚至“百模大战”的时代,作为一名既要写代码开发,又要频繁输出技术内容(写博文、做视频)的开发者,我每天最大的烦恼就是: “今天这个任务,

    By Ne0inhk