库的制作与原理1.0,库打包,协作,目标文件.o、ELF格式。

@bit::Shadow
✧(≖ ◡ ≖✿

目录

库的命名规范

.o文件

协作时库的合作

协作下库打包与更新

Linux下自动配置的库(C/C++)及头文件的查询:

指定头文件下gcc/g++编译

动态库

ldd

fPIC

.o链接库成为可执行文件

1.软链接

2.export链接

[gcc/g++ -c code.c -o code.o -Ⅰ 头文件处 -L 库处 -l真实库名 【无/-static】](#gcc/g++ -c code.c -o code.o -Ⅰ [头文件处] -L [库处] -l[真实库名] 【无/-static】)

-static

ELF

四部分

Section区域合并成为Secment

ELF形成可执行

*为什么要合并为Secment?

理解向动态库链接和加载


gitee

静态库(.a) Linux .lib Windows

动态库(.so) Linux .dll Windows // 常在".so"后加以".n"(n为数字),表示版本号。这是Linux的版本管理机制,由于解决版本兼容问题。

"库"其实就是大量.o文件构成的集合加以ar指令处理。

库的命名规范

"lib"+"真实名称"+"后缀"

像:libc.a的真实库名就是'c'。

.o文件

动静态库与.o文件均是ELF格式。

内容查询指令: readelf 选项 文件名/库名

.o文件形成流程:.cpp/.c ----> .o ---> 可执行文件/库文件(.a/.so)

内容:机器码 + 符号表 + 重定位信息 + 调试信息等等。

部分内容:

UND:undefined的缩写

协作时库的合作

前言:*.o + 对应所需 *.h 链接*.o:

gcc/g++ *.o ---> a.out

执行:./a.out

当多人协作传递时: .h 作为接口文件且说明文件,供以了解接口。

.o 作为"自己开发的 .o 文件 + 协作成员的.o"。

三者构成依赖关系以形成可执行文件。

协作下库打包与更新

ar -rc 库全称 *.o(打包对象) # r--replace(存在就更新) c--creat(不存在就创建)

例如:

bash 复制代码
ar -rc libmyc.a *.o  

常用结构:

压缩: tar czf lib.tgz lib

解压: tar xzf lib.tgz lib

Linux下自动配置的库(C/C++)及头文件的查询:

Linux下头文件路径: /usr/include

Linux下库文件路径: /lib64

ls查询库文件:

指定头文件下gcc/g++编译

-Ⅰ 头文件路径:头文件可能不会与.c/cpp文件在同一目录下,此时需要指定头文件位置的选项。(当前目录且非下级目录的.h文件则无需加'-I')。

-L 库文件路径 -l 真实库名称(小写kl的l):形成可执行文件的"库"定位选项,库没有在默认寻找位置:

  • /usr/lib

  • /usr/local/lib

  • /lib

    bash 复制代码
    $ gcc -I /usr/include/ -L /lib64 -lc -c code.c

演示效果:

动态库

ldd

ldd 查询一个可执行文件/共享库依赖哪些动态链接库。

fPIC

f:编译选项前缀由于控制代码生成、优化等。

PIC:Position independent code位置无关码。

-fPIC是gcc编译选项,是形成用于链接动态库的目标**.o文件**必备选项。

bash 复制代码
gcc -c -fPIC file.c -o file.o

gcc/g++ -c code.c -o code.o -Ⅰ 头文件处 -L 库处 -l真实库名 【无/-static】

-static

1.若无-static默认动态链接,若无动态库只能链接静态库。

2.-static是强制链接静态库命令若无静态库则报错。

3.IDE集成开发环境VS2022在安装过程中就存在配置库的环节。

对比项 静态库 (.a) 动态库 (.so)
链接时机 编译时 运行时
文件后缀 .a (archive) .so (shared object)
程序体积 大(包含库代码) 小(不含库代码)
内存占用 高(每个程序独立一份) 低(多程序共享一份)
依赖关系 无依赖,可独立运行 需要库文件存在
更新库 需重新编译程序 替换库文件即可
加载速度 快(无需查找) 稍慢(需动态链接)
符号冲突 容易冲突 隔离性好
编译命令 gcc -c -fPIC *.c ar rcs lib.a *.o gcc -c -fPIC *.c gcc -shared -o lib.so *.o
使用命令 gcc main.c -L. -lfoo gcc main.c -L. -lfoo 需设置 LD_LIBRARY_PATH

ELF

动静态库、.o文件(可重定向目标文件)均是"ELF"格式(一种二进制格式)

四部分

ELF Header:文件最开头,标识文件类型、机器架构、入口点、程序头表/节头表的位置和大小等。

Program Header Table:只有可执行文件和共享对象需要,描述如何将文件映射到进程地址空间。.o文件无此区域

Section(节):真正的内容数据,如++代码、数据、符号表、重定位表++等。

Section Header Table:描述各个Section节的信息,编译器、链接器使用。

一个 hello.o 文件内部大致如下(顺序可能因编译器而异):

Section (节) 内容说明 常见标记
.text 编译后的机器指令(代码) 可读、可执行
.data 已初始化的全局/静态变量 可读写
.bss 未初始化的全局/静态变量(不占用文件空间,只记录大小) 在加载时清零
.rodata 只读数据,如字符串常量、const 变量 只读
.symtab 符号表(全局、外部符号定义/引用) 链接器使用
.strtab 符号表中符号名称的字符串表
.rel.text 对 .text 的重定位条目(修正地址)
.rela.text 同上,但使用 rela 格式(带 addend)
.comment 编译器版本信息
.note.* 各种注释/属性(如 GNU-stack)
.shstrtab 节名称字符串表

各个.o文件链接成为可执行时会进行文件合并:

Section区域合并成为Secment
  • 合并原则:相同属性。如:只读、可读写。
  • 这样即便是不同的Section,加载到内存时,也可能加载到一起。
  • 这种合并原则在形成ELF时就在形成了。被记录于(Program Header Table内)。

☝Section 是逻辑划分,给链接器 用;Segment 是物理映射,给操作系统用。

ELF形成可执行

step1-将多份C/C++代码翻译为.o文件与配置的动静态库(ELF)。

step2-将多份.o文件section进行合并。

*为什么要合并为Secment?

section连续分布每个可存储最大4096,若有4097个字节必须另开一个节。这样降低了空间利用率,使用合并方式减少了内存碎片提供内存利用率。

理解向动态库链接和加载

未链接的.o文件,并未确定call的目标具体体现为call的目标地址为00:

在进行动态库的调用(如:printf()、外部函数run())前在反汇编层面(如:main的main.o 、 main.s文件)

均是call:00 00 00 00

*.o链接库成为可执行文件

1.软链接

sudo ln -fs 链接者 链接目标库

2.export链接

LD_LIBRARY_PATH 是 Linux 下用于临时指定共享库搜索路径的环境变量。

export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:追加路径 #追加式配置搜索路径

./a.out

运行程序时,会去 LD_LIBRARY_PATH 里找库

倾囊相授,持续深耕Linux

欢迎关注

相关推荐
ACP广源盛139246256731 小时前
GSV2231@ACP#三屏扩展旗舰芯片,TRAE SOLO 多任务并行开发核心引擎
运维·网络·人工智能·嵌入式硬件·gpt·电脑·音视频
程序猿乐锅1 小时前
Linux常用命令详解:目录、文件、压缩、编辑与查找
linux·运维·服务器
wyc是xxs1 小时前
用纯 Node.js 写了一个 JS 解释器 — kernel-js-lite
开发语言·javascript·npm·node.js
hai3152475431 小时前
AI工业化编程的黎明:由逻辑压缩到知识融合的范式跃迁
开发语言·人工智能·线性代数·机器学习·数学建模·概率论
文青小兵1 小时前
Linux云计算——docker 网络和部分挂载(二)
linux·docker·云计算
Cloud_Shy6181 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第一章 Item 7 - 9)
开发语言·数据库·python
এ慕ོ冬℘゜1 小时前
从零封装企业级通用确认弹窗组件|高复用、低耦合、适配全场景
开发语言·前端·javascript
郝学胜-神的一滴1 小时前
Qt 高级开发 020:水平布局手写代码实战
开发语言·c++·qt·系统架构·软件构建·用户界面
AOwhisky1 小时前
Ceph系列第五期:Ceph 对象存储(RADOS Gateway)精讲
linux·运维·笔记·ceph·gateway·对象存储