当前位置: 首页 > 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.cnnetsun.cn/news/2642809.html

相关文章:

  • 3个关键步骤:用DistroAV插件搭建专业级NDI直播工作流
  • 别再手动填DBC了!用CANdb++ Editor的3个隐藏技巧,效率翻倍
  • Python量化投资实战:用MOOTDX轻松解锁通达信金融数据宝库
  • 【护网入门】什么是护网行动?小白也能看懂的护网概念全解析
  • Unity独立游戏开发者必看:Player面板里这5个隐藏设置,能让你的游戏启动体验提升一个档次
  • 全链路监控与持续迭代:多模态AI系统的运维与优化
  • 告别Electron大体积!用Tauri把任意网站URL变成5MB的桌面软件(附完整配置流程)
  • DDS、SOME/IP、冰羚(iceoryx)大乱斗:智能汽车通信中间件选型深度解析
  • 扩散模型在机器人轨迹规划中的创新应用
  • 告别付费iSaver!用Wallpaper Engine免费搞定Win10动态锁屏(保姆级教程)
  • CMake编译选项进阶:用target_compile_options和生成器表达式实现跨平台条件编译
  • 终极音乐解放指南:3分钟破解网易云音乐NCM格式限制
  • 2026论文降AIGC软件:11款工具实测谁在“智能”谁在“智障”?
  • 如何永久保存微信聊天记录:WeChatMsg终极数据留存指南
  • 终极Windows热键冲突解决方案:hotkey-detective完整使用指南
  • 仅剩3席!Lindy 2024认证自动化工程师内训资料包(含私有化部署checklist+审计日志解析工具)
  • 免费录音转文字怎么操作?2026保姆级教程手把手教你永久免费转写
  • AI建站工具怎么选?一份写给新手的选型标准与对比指南
  • 完整指南:RevokeMsgPatcher深度解析Windows平台消息防撤回技术实现
  • 基于Next.js与OpenAI API构建智能简历生成器:全栈AI应用开发实践
  • BERT Miniatures系列解析:为什么BERT uncased L-12 H-256 A-4适合资源受限环境
  • WebSocket协作体验示例:Figma
  • Speechless微博备份工具:5分钟快速导出PDF的终极指南
  • 创客教育中的电路设计:从面包板到生活应用的全流程实践
  • 2026年市场营销进阶指南:工作后有哪些含金量高、值得考的证书?助你突破职业瓶颈
  • Windows热键冲突终极指南:用Hotkey Detective快速找回被占用的快捷键
  • AI科研绘图转矢量用什么工具最好?
  • 【Lindy自动化ROI速算工具包】:3分钟测算客服成本下降47%的关键阈值
  • 不用每月花 29 刀!OpenScreen这个开源屏幕录制神器让你 0 成本做出 Screen Studio 级产品演示视频
  • VMware里给Ubuntu虚拟机换网卡后启动失败?可能是磁盘空间告警的‘连锁反应’