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

【 linux 】动静态库的制作

目录

1. 认识动静态库

2. 理解动静态库

3. 动静态库的制作与对比

1.静态库的制作

2. 动态库的制作

3. 对比

4.认识ELF格式


1. 认识动静态库

本质上是一组预先编译好的代码、函数或资源的集合,供其他程序调用,以避免重复造轮子。根据链接时机加载方式的不同,库主要分为静态库动态库

静态库:在程序的编译链接阶段,链接器会将静态库中的代码完整复制并合并到最终的可执行文件中。linux/macOS中后缀是.a,windows中后缀是.lib

静态库的特点是独立性强,生成的可执行文件包含了所有依赖代码,运行时不需要外部库文件,部署方便。但是需要将代码完整复制一遍到可执行文件中更耗费资源,如果库进行更新的话所有的可执行文件都要重新编译链接非常不方便

动态库:在编译时将代码复制到可执行文件中,仅记录引用信息。代码在程序运行时由操作系统动态加载到内存中。linux中后缀是.so,macOS中是.dylib,windows中是.dll

动态库更节省空间,多个进程可以共享内存中的同一份库代码,显著减少磁盘和内存占用。只要接口(ABI)兼容,替换库文件即可生效,无需重新编译主程序

2. 理解动静态库

所有的库本质上都是源文件对应的.o,库也是要被安装到系统中的,可以以C标准库举例,/lib64/libc.so.6动态库文件,是程序运行时真正加载的文件,/usr/lib64/libc.a静态库版本

不同发行版路径可能不同,可以用以下命令确认

# 查看 libc 的实际路径 ldconfig -p | grep libc.so # 或者直接查找 find /lib* /usr/lib* -name "libc.so*" 2>/dev/null

C标准库是操作系统的核心组件,在安装操作系统时就已经预装,它是系统启动和用户空间程序运行的先决条件

3. 动静态库的制作与对比

1.静态库的制作

静态库的本质就是打一个包,我们可以自己写两个头文件和源文件,定义为mystdio.h,mystring.h,mystdio.c,mystring.c

将.c文件编译生成.o文件,在将.o文件打包生成.a文件

.PHONY: all clean all: libmy.a libmy.a: mystdio.o mystring.o ar rcs $@ $^ %.o: %.c gcc -c $< -o $@ clean: rm -f *.o libmy.a

目录结构是这样的

project/ ├── lib/ ← 静态库目录 │ ├── include/ ← 头文件(对外接口) │ │ ├── mystdio.h │ │ └── mystring.h │ ├── src/ ← 库源码(内部实现) │ │ ├── mystdio.c │ │ ├── mystring.c │ │ └── Makefile ← 只负责生成 libmy.a │ └── libmy.a ← 生成的静态库产物 │ └── app/ ← 主程序目录 ├── main.c ← 主函数入口 └── Makefile ← 只负责编译 main.c 并链接 libmy.a

编译链接生成可执行文件:

gcc main.c -I ..lib/include -L ../lib -l my -o app

介绍一下这几个命令都是干什么的,打包时需要用到ar -rc命令,rc是replace and create,存在同名.o替换,不存在插入,.a不存在创建

-大写i是查找头文件,连接任何的非C/C++标注库都需要指明-L,-l,小写l后面是.a文件名(去掉lib)

2. 动态库的制作

动态库的制作和静态库类似,编译阶段加上-fPIC命令产生位置无关码,gcc -c -fPIC *.c -o *.o

打包成库时加上-shared生成共享库格式,gcc -shared *.o -o .so

主程序的命令和静态库相同,对于静态库来说链接器需要将.a文件代码拷贝到main.c中,对于动态库链接器记录依赖,根据路径实时加载.so到内存

3. 对比

gcc/g++默认使用动态库,想用静态库需要加上-static(只存在静态库可执行程序只能静态链接)

linux系统中默认安装的大部分库都是动态库

库:应用程序=1:n

4.认识ELF格式

动静态库,可执行程序,.o文件都是ELF格式,ELF格式主要有以下几部分

ELF Header记录文件特征,Program Header Table记录段(segment)的信息,Section Header Table记录节(Section)的信息

库形成可执行程序需要进行Section的合并,相同属性合并成一个段(segment),关于如何合并的信息存储在Program Header Table中,所有需要被加载到内存中执行的 ELF 文件(包括可执行文件和共享库)都有 Segment;而不需要加载的文件(如.o目标文件、静态库.a)只有 Section,没有 Segment

实际过程

链接脚本(Linker Script)定义了 Output Section 的排列顺序和属性 → 链接器根据这些属性(R/W/X + ALLOC)将多个 Input Section 分配到不同的 Program Header 条目中 → 同时生成节头表和程序头表

没有 Segment 的文件,也没有 Program Header Table,可以执行readelf -l hello.o查看,可以用read -S hello.o读取Section Header节表头


http://www.zskr.cn/news/1422933.html

相关文章:

  • UniAR:统一预测人类视觉注意力与主观反馈的多模态模型
  • 往届上岸学员力荐!2026外科主任医师考试的金牌授课名师! - 医考机构品牌测评专家
  • 022、YOLOv11 C3k2 模块源码级解析:为什么替换 C2f 能提速还能涨点
  • 视听语音增强:从算法原理到短视频降噪的工程实践
  • 在安卓开发中快速接入大模型API,使用Taotoken实现智能代码补全
  • d2s-editor技术深度解析:暗黑破坏神2存档编辑器的实现原理与架构设计
  • 如何快速使用AzurLaneAutoScript:碧蓝航线全自动脚本的终极指南
  • 终极指南:用Ncorr破解材料变形测量的技术瓶颈
  • 郑州市管城区家电维修清洗|维小达 专业空调、冰箱、洗衣机、热水器、电视、油烟机、灶具、消毒柜、小家电维修清洗一站式服务 - 维小达科技
  • 深度拆解2026年GEO优化系统部署源头优选底层逻辑 全维度盘点高效稳定GEO优化软件服务商 - GEO贴牌代理
  • 豆包推广时代,贵州企业怎么选GEO优化服务商?成立时间长、性价比高、口碑好的才靠谱 - 优质企业观察收录
  • 英飞凌TC389平台下,AUTOSAR Fee模块的DaVinci配置避坑指南(附关键参数详解)
  • ArcGIS Pro脚本工具实战:5分钟搞定‘修改要素别名’自动化(含PyCharm配置)
  • PS 怎么直接修改文字?3 种方法轻松改字
  • xrdp远程连接Ubuntu花屏?可能是你的.xsession和startwm.sh在‘打架’
  • 如何用百度网盘API解决Python自动化文件管理难题
  • 3分钟上手Fooocus:零门槛AI绘画工具全解析
  • 基于ESP32与WS2812B的智能灯光系统:从FastLED编程到WLED部署实战
  • 杭州全屋定制哪家靠谱闭坑|2026 本地真实测评:莫干山全屋定制稳居榜首,品质家装闭眼选 - 商业新知
  • 终极指南:如何用Angry IP Scanner快速发现局域网中的所有设备
  • Kafka 高可用机制:Broker集群、分区副本、Leader与ISR
  • CTF和护网都搞不懂,还学什么网安?
  • 避坑指南:IfcOpenShell处理IFC4与IFC2X3版本时,编译和代码兼容性要注意什么?
  • IEEE论文排版进阶:5个LaTeX‘黑魔法’让你的图表公式更专业
  • 告别环境配置烦恼:保姆级教程带你用Arduino IDE 2.x搞定ESP32开发环境(Windows版)
  • Kafka 数据存储与清理机制:Topic、Partition、Segment与日志删除
  • 上海经济纠纷执行律师事务所推荐榜:商事执行胜诉前十 - 品牌2026
  • CANFD报文发送总失败?可能是BRS和FDF这两个关键属性没搞懂(CANoe/CAPL实战)
  • ESP32人脸识别项目避坑指南:MTMN模型参数调优实战(附完整配置代码)
  • 太仓定制柜子工厂哪家好?2026年5月选择参考 - 小李说家居