首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Linux动静态库以及动静态链接

Linux动静态库以及动静态链接

作者头像
用户11991900
发布于 2026-01-15 12:23:44
发布于 2026-01-15 12:23:44
3850
举报
静态库

ar 是 gnu 归档⼯具(打包), rc 表⽰ (replace and create)

打包成静态库: ar -rc libXXX.a *.o

代码语言:javascript
复制

// Makefile libmystdio.a:my_stdio.o my_string.o @ar -rc @ ^ %.o:%.c @gcc -c

在 Makefile 中,命令前的 @ 是 静默执行标记,核心作用是:隐藏命令本身的输出,只显示命令执行后的结果(或自定义 echo 提示)

用法

效果

适用场景

命令前加 @

隐藏命令本身,只显示执行结果/echo提示

绝大多数构建/清理/打包命令

命令前不加 @

显示命令本身 + 执行结果

调试 Makefile 时(查看实际执行的命令)

ar -tv libmystdio.a • t: 列出静态库中的⽂件 • v:verbose 详细信息

静态库的使用

程序中使用到库的内容时,需要将库进行链接。

Linux查找库的时候只会区lib64路径下去查。其他路径需要加路径

代码语言:javascript
复制

// 场景1:头⽂件和库⽂件安装到系统路径下 gcc main.c -l库名字 // 场景2:头⽂件和库⽂件和我们⾃⼰的源⽂件在同⼀个路径下 gcc main.c -L. -l库名字 // 场景3:头⽂件和库⽂件有⾃⼰的独⽴路径

• -L: 指定库路径

• -I: 指定头⽂件搜索路径

• -l: 指定库名

• 测试⽬标⽂件⽣成后,静态库删掉,程序照样可以运⾏

• 关于 -static 选项,稍后介绍

• 库⽂件名称和引⼊库的名称:去掉前缀 lib ,去掉后缀 .so ,.a ,如: libc.so -> c

gcc专门编译C语言,默认认识C标准库,所以不用显示使用-l。gcc默认区/lib64下查找库,所以标准库不用-L。

库不可以包含main函数!!

我给别人提供一个库,要提供: 1. .a库文件 2. .h头文件(你的库的使用手册)

使用别人的库: (在使用任何三方库时必须使用-l)

  1. 可以将头文件拷贝到/usr/include/下,库文件拷贝到/lib64/下。这就是安装的过程。   此时,在使用时,必须使用-l指明使用的是哪一个库。
  2. 使用选项-L -I -l指明条件,来使用静态库。头文件在预处理阶段就需要。
  3. 也可以在/lib64/下,与别人的库进行软链接。库文件拷贝到/lib64/下。使用-l找到别人的库
动态库

链接时,要使用-shared

生成.o文件时,要是用fPIC

代码语言:javascript
复制

// Makefile libmystdio.so:my_stdio.o my_string.o gcc -o @ ^ -shared %.o:%.c gcc -fPIC -c

• shared:表⽰⽣成共享库格式

• fPIC:产⽣位置⽆关码(positionindependentcode)

• 库名规则:libxxx.so

  1. 形成动态库,不使用ar,而是使用gcc,g++。可以知道,默认形成的是动态库,形成静态库要使用附加命令。
动态库的使用

库的名字要去掉前缀和后缀

ldd libXXX.so // 查看库或者可执⾏程序的依赖

代码语言:javascript
复制

// 场景1:头⽂件和库⽂件安装到系统路径下 gcc main.c -l库文件名 // 场景2:头⽂件和库⽂件和我们⾃⼰的源⽂件在同⼀个路径下 gcc main.c -L. -l库文件名 // 从左到右搜索-L指定的⽬录 // 场景3:头⽂件和库⽂件有⾃⼰的独⽴路径

只使用gcc main.c -I头⽂件路径 -L库⽂件路径 -lmymath时,执行可执行程序会有找不到库的情况。

这一步,是告诉了gcc我的库信息,是给编译器说的。

执行可执行程序的时候,会有找不到库的情况。这时是操作系统(加载器)找不到库。

使用静态库的时候没这个问题,是由于静态库当中的方法,拷贝到了我的程序内部。程序运行,就不需要库了。

动态库加载时的查找问题(运行时的查找问题)
  1. 将库文件拷贝到/lib64路径下

(拷⻉ .so ⽂件到系统共享库路径下,⼀般指 /usr/lib、/usr/local/lib、/lib64 或者开 篇指明的库路径等 )

  1. 将库文件,在/lib64/下的文件中,建立软链接(向系统共享库路径下建⽴同名软连接)

ln -s 路径 /lib64/lib库名.so

1 2方法可以认为本质是一样的。

  1. 更改环境变量: LD_LIBRARY_PATH

动态搜索路径除了搜索/lib64还会在该环境变量中寻找。将库的路径导入其中。

LD_LIBRARY_PATH = $ LD_LIBRARY_PATH + 路径

  1. ldconfig⽅案:配置/ etc/ld.so.conf.d/ ,ldconfig更新
代码语言:javascript
复制

[root@localhost linux]# cat /etc/ld.so.conf.d/bit.conf /root/tools/linux [root@localhost linux]# ldconfig // 要⽣效,这⾥要执⾏ldconfig,重新加载库搜索路径

在/etc/ld.so.conf.d/下新建文件,将你的库的路径拷贝进去。再执行ldconfig命令

静态链接(Static Linking)

1. 原理

静态链接在**编译阶段**将所有依赖的库代码复制到最终的可执行文件中。

  • 使用的库文件:.a(静态库)
  • 链接器:ld(由gcc调用)
2. 示例
代码语言:javascript
复制

gcc -c main.c -o main.o gcc -c math.c -o math.o ar rcs libmath.a math.o # 创建静态库 gcc main.o -L. -lmath -o main_static

  • -L.:指定库搜索路径为当前目录
  • -lmath:链接libmath.a
3. 特点

优点

缺点

可执行文件独立运行,无外部依赖

文件体积大

启动速度快(无需运行时加载)

库更新需重新编译所有程序

部署简单(单文件分发)

内存浪费(多程序重复加载相同库)


三、动态链接(Dynamic Linking)

1. 原理

动态链接在**程序运行时才加载所需的共享库(.so)**,由**动态链接器(ld-linux.so)**完成。

  • 使用的库文件:.so(共享库)
  • 链接器:ld(生成部分链接的可执行文件)
  • 运行时加载器:ld-linux.so
2. 示例
代码语言:javascript
复制

gcc -fPIC -c math.c -o math.o # 生成位置无关代码 gcc -shared -o libmath.so math.o # 创建共享库 gcc main.c -L. -lmath -o main_dynamic # 编译时链接(仅记录依赖)

运行时必须设置库路径:

代码语言:javascript
复制

export LD_LIBRARY_PATH=. ./main_dynamic

3. 特点

优点

缺点

可执行文件体积小

依赖外部.so文件,部署复杂

多程序共享内存中的同一份库,节省内存

启动时有轻微加载开销

库更新无需重新编译程序(接口兼容)

可能出现“依赖地狱”或版本冲突


四、动静态链接对比总结

特性

静态链接

动态链接

链接时机

编译时

运行时

可执行文件大小

大(库代码被复制)

小(仅记录依赖)

内存使用

每个进程独立加载库

多进程共享一份库

库更新

需重新编译程序

替换.so即可(接口兼容)

运行依赖

无

依赖.so存在且路径正确

典型用途

嵌入式、独立工具

桌面系统、共享服务

  • 工具推荐:
    • ldd:查看依赖的共享库
    • nm:查看符号表
    • objdump:反汇编目标文件
    • readelf:查看ELF文件结构
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 静态库
    • 静态库的使用
  • 动态库
    • 动态库的使用
    • 动态库加载时的查找问题(运行时的查找问题)
  • 静态链接(Static Linking)
    • 1. 原理
    • 2. 示例
    • 3. 特点
  • 三、动态链接(Dynamic Linking)
    • 1. 原理
    • 2. 示例
    • 3. 特点
  • 四、动静态链接对比总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档