前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux环境下静态库和动态库的实现

Linux环境下静态库和动态库的实现

作者头像
ahao
发布于 2025-01-05 00:02:26
发布于 2025-01-05 00:02:26
14400
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

Linux 环境下静态库和动态库的实现

软件开发中,库是非常重要的组成部分。它们包含了一组可复用的函数和代码片段,用于提高开发效率和代码质量。在Linux系统中,库分为静态库和动态库两种。本文将介绍它们的实现方式,结合C语言代码进行说明,并详细解释其原理和使用方法。

静态库的实现

目录结构

静态库的目录结构如下(同理动态库也如此):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mylib/
├── include/
│   └── math_functions.h
├── lib/
│   └── libmath.a
└── main.c
什么是静态库

静态库(Static Library)是将多个目标文件(.o 文件)打包到一个单独的文件(通常以 .a 为扩展名)中,链接时将库的代码复制到最终的可执行文件中。

创建静态库

我们通过以下步骤创建一个静态库:

  1. 编写一个简单的C语言程序,包含一些需要复用的函数。
  2. 编译成目标文件(.o 文件)。
  3. 使用 ar 工具将目标文件打包成静态库。

以下是示例代码:

math_functions.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef MATH_FUNCTIONS_H
#define MATH_FUNCTIONS_H

int add(int a, int b);
int subtract(int a, int b);

#endif

math_functions.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "math_functions.h"

// 加法函数
int add(int a, int b) {
    return a + b;
}

// 减法函数
int subtract(int a, int b) {
    return a - b;
}

编译为目标文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc -c math_functions.c -o math_functions.o
# -c:仅编译源文件为目标文件,不链接

使用 ar 工具创建静态库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ar rcs libmath.a math_functions.o
# r:将目标文件添加到库中
# c:创建一个新的库文件
# s:索引库文件,提升访问效率

将头文件和库文件组织到目录结构中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mkdir -p mylib/include mylib/lib
mv math_functions.h mylib/include/
mv libmath.a mylib/lib/
使用静态库

创建一个使用静态库的程序:

main.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include "math_functions.h"  // 包含头文件

int main() {
    printf("5 + 3 = %d\n", add(5, 3));
    printf("5 - 3 = %d\n", subtract(5, 3));
    return 0;
}

编译并链接静态库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc main.c -I./mylib/include -L./mylib/lib -lmath -o static_example
# -I:指定头文件路径
# -L:指定库文件路径
# -l:链接指定的库(去掉前缀lib和后缀.a)

运行程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./static_example
使用Makefile管理静态库

创建一个 Makefile 文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 编译器
CC = gcc
# 静态库工具
AR = ar
# 编译选项
CFLAGS = -I./mylib/include
# 链接选项
LDFLAGS = -L./mylib/lib
# 使用的库
LIBS = -lmath

all: static_example

# 目标1:生成静态库
mylib/lib/libmath.a: mylib/include/math_functions.h mylib/include/math_functions.c
	$(CC) -c mylib/include/math_functions.c -o math_functions.o
	$(AR) rcs mylib/lib/libmath.a math_functions.o

# 目标2:生成可执行文件
static_example: main.c mylib/lib/libmath.a
	$(CC) main.c $(CFLAGS) $(LDFLAGS) $(LIBS) -o static_example

# 清理
clean:
	rm -f *.o mylib/lib/libmath.a static_example

使用 make 命令自动化构建和清理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
make
./static_example
make clean
静态库的特点
  • 优点
    • 链接后无需依赖外部库,部署简单。
    • 运行效率高。
  • 缺点
    • 可执行文件体积较大。
    • 库更新时需要重新编译应用程序。

动态库的实现

目录结构

动态库的目录结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mylib/
├── include/
│   └── math_functions.h
├── lib/
│   └── libmath.so
└── main.c
什么是动态库

动态库(Dynamic Library)在程序运行时被加载到内存中,通常以 .so 为扩展名。与静态库不同,动态库不被嵌入到可执行文件中,而是以共享方式供多个程序使用。

创建动态库
  1. 编写需要共享的函数代码。
  2. 使用 -fPIC 选项生成位置无关代码。
  3. 使用 gcc -shared 创建动态库。

示例代码与静态库相同,这里直接展示动态库的生成:

编译生成目标文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc -c -fPIC math_functions.c -o math_functions.o
# -c:仅编译源文件为目标文件,不链接
# -fPIC:生成与内存地址无关的代码,便于动态加载

创建动态库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc -shared math_functions.o -o libmath.so
# -shared:生成动态库文件

将库文件组织到目录结构中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mv libmath.so mylib/lib/
使用动态库
方法1:临时指定库路径
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc main.c -I./mylib/include -L./mylib/lib -lmath -o dynamic_example
export LD_LIBRARY_PATH=./mylib/lib:$LD_LIBRARY_PATH
./dynamic_example
  • export LD_LIBRARY_PATH:临时指定动态库路径。
方法2:将动态库复制到系统默认目录

将动态库复制到系统默认路径,例如 /usr/lib//usr/local/lib/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo cp mylib/lib/libmath.so /usr/lib/

运行程序时无需手动设置路径。

方法3:创建软链接

创建指向动态库的软链接:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo ln -s /path/to/mylib/lib/libmath.so /usr/lib/libmath.so
方法4:在 /etc/ld.so.conf.d/ 下添加配置文件

创建一个新的配置文件,例如 mylib.conf,内容为动态库的路径:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
echo "/path/to/mylib/lib" | sudo tee /etc/ld.so.conf.d/mylib.conf
sudo ldconfig

运行程序时无需手动设置路径。

使用Makefile管理动态库

创建一个 Makefile 文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 编译器
CC = gcc
# 编译选项
CFLAGS = -fPIC -I./mylib/include
# 链接选项
LDFLAGS = -L./mylib/lib
# 使用的库
LIBS = -lmath

all: dynamic_example

# 目标1:生成动态库
mylib/lib/libmath.so: mylib/include/math_functions.h mylib/include/math_functions.c
	$(CC) -c $(CFLAGS) mylib/include/math_functions.c -o math_functions.o
	$(CC) -shared math_functions.o -o mylib/lib/libmath.so

# 设置LD_LIBRARY_PATH
export_path:
	export LD_LIBRARY_PATH=./mylib/lib:$(LD_LIBRARY_PATH)

# 目标2:生成可执行文件
dynamic_example: main.c mylib/lib/libmath.so
	$(CC) main.c $(CFLAGS) $(LDFLAGS) $(LIBS) -o dynamic_example

# 清理
clean:
	rm -f *.o mylib/lib/libmath.so dynamic_example
动态库的特点
  • 优点
    • 多个程序可以共享同一个动态库文件,而不需要在每个程序中都包含库代码。因此,动态库使得磁盘空间的使用更加高效,尤其是在多个应用程序依赖同一个库时。
    • 动态库可以在不重新编译应用程序的情况下进行更新。只需替换系统中的动态库文件,所有依赖该库的程序都能自动使用新版本的库。
    • 动态库是在程序运行时加载的,系统可以根据需要加载和卸载库,从而提高内存使用的灵活性,尤其适合大规模的应用程序或需要频繁更新的程序。
    • 与静态库相比,动态库不嵌入可执行文件中,因此生成的可执行文件通常较小。这对于需要部署到多个设备或网络传输的程序非常重要。
  • 缺点
    • 动态库需要在运行时加载,这意味着应用程序必须依赖系统上正确版本的库文件。如果缺少某个库或版本不匹配,程序可能无法正常运行,导致“库未找到”或“版本冲突”等问题。这要求开发者和用户必须确保库的正确安装和配置。
    • 虽然动态库在内存和磁盘空间上节省了资源,但它们在加载和链接时会带来一定的性能开销。每次程序启动时,操作系统需要查找和加载相应的动态库,且在程序执行期间,动态链接可能导致额外的性能消耗。
    • 由于动态库是外部依赖,它们的存在和稳定性对程序的正常运行至关重要。如果动态库被删除、移动或损坏,应用程序就会无法运行,给用户带来不便。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Linux】从零开始认识动静态库 -动态库
这里出现了main函数的报错。因为代码中没有main函数,就不可能形成可执行程序!
叫我龙翔
2024/05/12
1100
【Linux】从零开始认识动静态库 -动态库
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
上次介绍了基础IO(二):Linux:基础IO(二.缓冲区、模拟一下缓冲区、详细讲解文件系统)
是Nero哦
2024/07/01
3030
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
动态库与静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
二肥是只大懒蓝猫
2023/03/30
2.4K0
动态库与静态库
【库函数】Linux下动态库.so和静态库.a的生成和使用
我在路径/root/host/my_program/asoc/include下创建四个文件
SarPro
2024/04/25
2.2K0
【库函数】Linux下动态库.so和静态库.a的生成和使用
【Linux探索学习】第二十五弹——动静态库:Linux 中静态库与动态库的详细解析
https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482
GG Bond1
2025/01/15
2120
【Linux探索学习】第二十五弹——动静态库:Linux 中静态库与动态库的详细解析
【Linux】软硬连接与动静态库
硬连接不是一个独立的文件,因为它没有的独立的inode号,用的是目标文件的inode
用户11029103
2025/03/10
1070
【Linux】软硬连接与动静态库
Linux 中的静态库和动态库简介及生成过程示例
Linux中的静态库和动态库简介及生成过程示例 【文章摘要】 在实际的软件开发项目中,不是每一行代码都需要我们亲自写。在我们的软件产品中,有一些代码(尤其是函数)的出现频率很高,它们可以被当作公共代码来反复使用。为了避免重复劳动,我们就把这些公共代码编译为库文件,供需要的程序调用。在Linux中,库分为静态库和动态库两种。 本文对静态库和动态库进行了详细的介绍,并用实际的C代码演示了这两种库的生成过程。 一、静态库和动态库简介 众所周知,程序一般需要经过预处理、编译、汇编和链接这几个步骤才能变成可执行的程
用户2017109
2018/06/19
1.6K0
Linux静态库与动态库加载
        关于库相比大家之前肯定使用过,比如C/C++里面的标准库,STL里面的各种库,我们在调用STL里的容器时都需要使用库,那么库到底是什么呢?
咬咬
2024/06/12
4280
Linux静态库与动态库加载
静态库(.a)与动态库(.so)的简明介绍
gcc有很多关于静态库,动态库的选项如-l,-L,-fPIC,-shared -Wl,-soname,看着很复杂容易混淆,其实静态库和动态库都是应需而生,只要有了一个线索都很容易理解。
racaljk
2018/10/10
1.7K0
【Linux】动静态库的制作与使用
注意动态库中生成 .o 文件时gcc 要带选项 -fPIC ,表示生成位置无关码。
aosei
2024/01/23
2420
【Linux】动静态库的制作与使用
Linux gcc编译生成静态库和共享动态库的过程
这篇文章主要通过实例演示在Linux下如何使用gcc分别编译生成静态库和动态库文件以及其它程序如何使用这个生成的静态库和动态库。
typecodes
2024/03/29
8490
Linux gcc编译生成静态库和共享动态库的过程
【Linux】动静态库
静态库是一种在编译阶段将库文件的内容直接整合到目标程序中的库文件形式。使用静态库后,库的代码会成为可执行文件的一部分,运行时不需要依赖外部库。
用户11305458
2025/01/09
1570
【Linux】动静态库
动态库和静态库
在 Linux 编程中,库是组织和共享代码的一个重要机制,主要分为静态库(Static Library)和动态库(Dynamic Library)。下面详细介绍它们的类型、使用方式、优缺点以及总结。
ljw695
2024/10/30
2350
【Linux基础IO】Linux IO编程入门:揭秘动态库与静态库的秘密
前言:在Linux的浩瀚编程海洋中,IO(输入/输出)操作作为系统与外界交互的基石,其重要性不言而喻。无论是文件读写、网络通信还是设备驱动,都离不开IO操作的支撑。而在这个过程中,动静态库作为代码复用和模块化的重要手段,扮演着至关重要的角色。它们不仅简化了开发流程,提高了开发效率,还通过优化资源使用和减少编译时间等方式,为Linux程序的性能和可维护性保驾护航
Eternity._
2024/10/01
1360
【Linux基础IO】Linux IO编程入门:揭秘动态库与静态库的秘密
linux 动态库 静态库_静态库里面包含动态库
那么这三个时间有什么作用呢? 我们在使用自动化构建工具Makefile时,如果连续make会发现:
全栈程序员站长
2022/11/10
7.6K0
linux 动态库 静态库_静态库里面包含动态库
详解动态库和静态库
在C、C++中我们使用过标准库,比如在使用strerror、vector、string等时,都只是调用了这些函数接口,这些都是需要具体的实现。
南桥
2024/06/03
2650
详解动态库和静态库
动态库与静态库:深入解析与应用
静态库 是一种在编译时被链接到目标代码中的库。它通常以 .a 文件(在 Unix/Linux 系统中)或 .lib 文件(在 Windows 系统中)的形式存在。
用户11396661
2025/02/16
1950
Linux软硬链接与动静态库
我们看到, 真正找到磁盘上文件的并不是文件名, 而是inode, 其实在linux中可以让多个文件名对应于同一个inode.
用户11317877
2025/02/19
1390
Linux软硬链接与动静态库
Linux基础——gcc编译、静态库与动态库(共享库)
1、静态库的命名格式 lib + 库的名字 + .a 例:libMyTest.a (MyTest为静态库的名字)
全栈程序员站长
2022/11/10
9K0
Linux基础——gcc编译、静态库与动态库(共享库)
【Linux系统IO】六、动静态库
​ 我们之前学 gcc 的时候也有接触过一点动静态库的知识,现在要把它单独拿出来讲,主要是因为我们后面肯定在自己开发的时候需要包装自己的库,此时就需要有动静态库的原理知识和使用知识!
利刃大大
2025/03/11
1070
【Linux系统IO】六、动静态库
相关推荐
【Linux】从零开始认识动静态库 -动态库
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验