从零开始:Linux环境下如何制作静态库与动态库
个人主页:chian-ocean
文章专栏-Linux
前言
动静态库是编程中两种主要的库类型,它们用于帮助开发者复用已有的代码,而不需要每次都从头开始编写。它们的主要区别在于链接和加载的时机、方式以及使用场景

库
库就是一些已经写好并且经过测试的功能模块,你只需要在自己的程序中“借用”这些功能,而无需重新做同样的工作。这样不仅节省了时间,还能提高代码的质量和稳定性。
库的形式
库的形式主要有两种,分别是 静态库 和 动态库。它们的区别在于程序如何使用这些库,以及库文件在程序中的存储方式。
静态库 (Static Library)
静态库是在程序编译时就被链接到可执行文件中的库,所有的库代码会被嵌入到最终生成的程序中。程序在运行时不再依赖外部的库文件。
文件扩展名:
- Linux/Unix 系统:
.a(archive) - Windows 系统:
.lib
动态库 (Dynamic Library)
动态库是在程序运行时加载的库,程序并不会将库的代码嵌入到程序中,而是在程序启动时,或者在程序运行时动态加载需要的库文件。
文件扩展名:
- Linux/Unix 系统:
.so(Shared Object) - Windows 系统:
.dll(Dynamic Link Library)
总结:
| 特性 | 静态库 | 动态库 |
|---|---|---|
| 链接时机 | 编译时链接,库代码被嵌入到程序中 | 运行时链接,程序在执行时动态加载库 |
| 可执行文件大小 | 程序文件较大,因为库代码被包含在其中 | 程序文件较小,只包含对库的引用,库的代码在外部 |
| 依赖关系 | 不依赖外部库文件,所有代码在可执行文件中 | 依赖外部库文件,程序必须确保运行时找到对应的库文件 |
| 共享 | 每个程序都包含自己需要的库代码,不共享 | 多个程序可以共享同一个库文件,节省内存和磁盘空间 |
| 更新 | 库文件更新时需要重新编译程序 | 库文件更新时,无需重新编译程序,只需要确保兼容性 |
| 性能 | 程序启动较快,因为所有代码都已经包含在内 | 程序启动时需要加载库文件,可能稍慢,且可能会有额外的内存管理开销 |
静态库
静态库的制作
**静态库(Static Library)**是一个打包了多个目标文件(.o 文件)或其他库文件的归档文件。它可以在编译时链接到程序中,生成最终的可执行文件。静态库的扩展名通常为 .a(在 Unix/Linux 系统上)。
编写源文件: 创建包含函数实现的 .c 文件,例如 math.c。
- 简单的加减乘除。
#include "mymath.h" int errno = 0 ;
int add(int x,int y)
{ return x + y;
}
int sub(int x,int y)
{ return x - y;
}
int mul(int x,int y)
{ return x * y;
}
int div(int x,int y)
{ if(y == 0) { errno = -1; return -1; } return x / y;
}
编写头文件: 创建包含函数实现的 .c 函数声明
#pragma once
#include <stdio.h>
extern int errno; int add(int x,int y);
int sub(int x,int y);
int mul(int x,int y);
int div(int x,int y);
编写Makefile:创建自动化构建文件
# 定义静态库的名称
lib=libmath.a # 生成静态库 libmath.a 的规则
# 依赖 mymath.o 文件,并将其打包成静态库
$(lib): mymath.o # 使用 ar 命令将目标文件 mymath.o 添加到静态库 libmath.a 中ar -rc $@ $^# 编译 mymath.c 文件为 mymath.o 目标文件的规则
mymath.o: mymath.c # 使用 gcc 编译 mymath.c 文件为目标文件 mymath.ogcc -c $^# 定义伪目标 clean,它用于清理构建产生的文件
.PHONY: clean
clean: # 删除所有目标文件 (.o) 和库文件 (lib*)rm -rf *.o lib* # 定义伪目标 output,它用于创建输出目录并复制必要的文件
.PHONY: output
output: # 创建 lib/include 目录mkdir -p lib/include # 创建 lib/libmymath 目录mkdir -p lib/libmymath # 将所有头文件复制到 lib/include 目录cp *.h lib/include # 将静态库 (.a 文件) 复制到 lib/libmymath 目录cp *.a lib/libmymath
静态库的使用
#include "mymath.h" // 包含自定义的头文件 mymath.hint main() {printf("add(1 + 1) = %d\n", add(1, 1));printf("sub(1 + 1) = %d\n", sub(1, 1));printf("mul(1 + 1) = %d\n", mul(1, 1));printf("div(1 + 1) = %d\n", div(1, 1));return 0;
}
写一个代码利用自己写的库;

- 此时的静态库在
/lib/libmymath的路径下。 - 头文件在
/lib/include的路径下。 - 可执行程序在
/mian的目录下。
库路径和头文件路径只有用户知道
gcc main.c -I ../lib/include/ -L ../lib/libmymath/ -lmymath
-
gcc main.c:使用gcc编译器来编译main.c文件。 -
-I ./lib/include/:这个选项告诉编译器在./lib/include/目录中查找头文件 (*.h)。-I后面跟着的是头文件所在的目录。 -
-L ./lib/libmymath/:这个选项告诉编译器在./lib/libmymath/目录中查找库文件 (*.a或*.so),-L后面跟的是库文件所在的目录。 -
-lmymath:这个选项告诉编译器链接libmymath库。编译器会自动查找并链接名为libmymath.a或libmymath.so的库文件。注意,lib前缀和.a后缀会被自动省略。
库路径和头文件路径在系统路径下
/usr/lib64 #库的系统默认路径
/usr/include #头文件的系统默认路径
这时候我们仅仅需要手动连接库就好了。
gcc main.c -lmymath
动态库
动态库的制作
- 把静态库的的方法做成动态库。
编写Makefile:创建自动化构建文件
# 定义变量dy_mymath,表示生成的动态库文件名
dy_mymath = libmymath.so# 生成动态库 libmymath.so 目标
# 该目标依赖于 mymath.o 文件
$(dy_mymath): mymath.o# 使用gcc命令生成动态库,-shared 表示生成共享库,-o 用于指定输出文件# $@ 代表目标文件(这里是 libmymath.so),$^ 代表所有依赖文件(这里是 mymath.o)gcc -shared -o $@ $^# 生成目标文件 mymath.o
# 该目标依赖于 mymath.c 文件
mymath.o: mymath.c# 使用gcc编译源文件 mymath.c 生成目标文件 mymath.o# -fPIC 生成位置无关代码(适用于动态库),-c 只编译源文件,不进行链接# $^ 代表依赖文件(这里是 mymath.c)gcc -fPIC -c $^# 声明 clean 为伪目标,表示 make clean 是一个命令,而不是文件
.PHONY: clean# clean 目标,用于清理生成的目标文件和动态库文件
clean:# 删除所有目标文件 (.o) 和共享库文件 (.so)# -rf 强制删除,不询问确认rm -rf *.o *.so
动态库的使用
库路径和头文件路径只有用户知道

gcc main.c -I ../ -L ../ -lmymath
-
-I../:此选项指定了头文件路径,告诉编译器去../目录下查找头文件。 -
-L../:此选项指定了库文件路径,告诉链接器去../目录下查找库文件。 -
-lmymath:告诉编译器链接libmymath.so动态库。链接器会自动在路径中查找名为libmymath.so的动态库文件。
库路径和头文件路径在系统路径下
/usr/lib64 #库的系统默认路径
/usr/include #头文件的系统默认路径
这时候我们仅仅需要手动连接库就好了。
gcc main.c -lmymath
执行可执行程序的时候就会报错:

./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
这个错误表明 动态库 libmymath.so 无法被加载,通常是因为系统在运行时无法找到该动态库。
动态库的加载
-
将动态库加载到
lib64系统路径下,拷贝到系统默认搜索的路径的下面 -
软链接到
lib64的系统路径下。
sudo ln -s /home/ocean/linux/file/lib_dyn/libmymath.so /lib64

将其软连接到系统路径下。

- 运行程序时指定动态库路径: 如果运行时无法找到动态库,使用
LD_LIBRARY_PATH来指定动态库的位置(临时)。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ocean/linux/file/lib_dyn

- 在
/etc/ld.so.conof.d建立自己的动态库的路径配置文件,然后执行ldconfig进行刷新。

- 同样也可以进行动态库的加载。
相关文章:
从零开始:Linux环境下如何制作静态库与动态库
个人主页:chian-ocean 文章专栏-Linux 前言 动静态库是编程中两种主要的库类型,它们用于帮助开发者复用已有的代码,而不需要每次都从头开始编写。它们的主要区别在于链接和加载的时机、方式以及使用场景 库 库就是一些已经写好并且经过测试…...
【智能体Agent】ReAct智能体的实现思路和关键技术
基于ReAct(Reasoning Acting)框架的自主智能体 import re from typing import List, Tuplefrom langchain_community.chat_message_histories.in_memory import ChatMessageHistory from langchain_core.language_models.chat_models import BaseChatM…...
Java进阶:Zookeeper相关笔记
概要总结: ●Zookeeper是一个开源的分布式协调服务,需要下载并部署在服务器上(使用cmd启动,windows与linux都可用)。 ●zookeeper一般用来实现诸如数据订阅/发布、负载均衡、命名服务、集群管理、分布式锁和分布式队列等功能。 ●有多台服…...
QT-绘画事件
实现颜色的随时调整,追加橡皮擦功能 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QColor> #include <QPoint> #include <QVector> #include <QMouseEvent> #include <QPainter> #include <Q…...
鸿蒙NEXT开发-端云一体化开发
注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 目录 端云一体化开发基本概念 传统架构 端云一…...
大模型——股票分析AI工具开发教程
大模型——股票分析AI工具开发教程 在本教程中,我们将利用Google Gemini 2.0 Flash模型创建一个简单但有效的股票分析器。 你是否曾被大量的股票市场数据所淹没?希望有一个私人助理来筛选噪音并为您提供清晰、可操作的见解?好吧,你可以自己构建一个,而且由于 Python 的强…...
nexus 实现https 私有镜像搭建
1、安装nexus 1.1 安装JDK17 rpm -ivh jdk-17.0.13_linux-x64_bin.rpm 1.2 下载安装包解压到指定目录 tar zxvf nexus-3.77.2-02-unix.tar.gz -C /usr/local 2、运行nexus 默认8081端口 cd /usr/local/nexus-3.77.2-02 && bin/nexus start 3、配置nexus私有docker 镜…...
颈椎X光数据集(cervical spine X-ray dataset)
颈椎X光数据集(cervical spine X-ray dataset) 一.颈椎X光(1248张原始图像,无处理,jpg格式) 二.颈椎X光(1000张原始图像,无处理,jpg格式) 此数据…...
(动态规划 完全背包 零钱兑换)leetcode 322
本题为完全背包 与01背包的区别是 物品可以任意取 而01背包只能取一次 这就导致了状态转移方程的不同 1.当放不下:的时候 转移方程是一样的 取0到i-1 物品,背包容量为j的最优值 else 2.放得下:就是取 0到i-1 物品,背包容量为j的最优值和 “0到i的[j-w[i]]v…...
【AI大模型】DeepSeek + Kimi 高效制作PPT实战详解
目录 一、前言 二、传统 PPT 制作问题 2.1 传统方式制作 PPT 2.2 AI 大模型辅助制作 PPT 2.3 适用场景对比分析 2.4 最佳实践与推荐 三、DeepSeek Kimi 高效制作PPT操作实践 3.1 Kimi 简介 3.2 DeepSeek Kimi 制作PPT优势 3.2.1 DeepSeek 优势 3.2.2 Kimi 制作PPT优…...
Pytorch的一小步,昇腾芯片的一大步
Pytorch的一小步,昇腾芯片的一大步 相信在AI圈的人多多少少都看到了最近的信息:PyTorch最新2.1版本宣布支持华为昇腾芯片! 1、 发生了什么事儿? 在2023年10月4日PyTorch 2.1版本的发布博客上,PyTorch介绍的beta版本…...
rabbitmq-amqp事务消息+消费失败重试机制+prefetch限流
1. 安装和配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency><dependency> <groupId>com.fasterxml.jackson.core</groupId> <arti…...
【HarmonyOS Next】自定义Tabs
背景 项目中Tabs的使用可以说是特别的频繁,但是官方提供的Tabs使用起来,存在tab选项卡切换动画滞后的问题。 原始动画无法满足产品的UI需求,因此,这篇文章将实现下面页面滑动,tab选项卡实时滑动的动画效果。 实现逻…...
Sass 模块化革命:深入解析 @use 语法,打造高效 CSS 架构
文章目录 前言use 用法1. 模块化与命名空间2. use 中 as 语法的使用3. as * 语法的使用4. 私有成员的访问5. use 中with默认值6. use 导入问题总结下一篇预告: 前言 在上一篇中,我们深入探讨了 Sass 中 import 语法的局限性,正是因为这些问题…...
【渗透测试】反弹 Shell 技术详解(一)
反弹 Shell 技术详解 一、前置知识 反弹 shell(Reverse Shell)是一种技术,攻击者利用它可以在远程主机上获得一个交互式的命令行接口。通常情况下,反弹 shell 会将标准输入(stdin)、标准输出(…...
python:pymunk + pygame 模拟六边形中小球弹跳运动
向 chat.deepseek.com 提问:编写 python 程序,用 pymunk, 有一个正六边形,围绕中心点缓慢旋转,六边形内有一个小球,六边形的6条边作为墙壁,小球受重力和摩擦力、弹力影响,模拟小球弹跳运动&…...
Windows 图形显示驱动开发-WDDM 3.2-本机 GPU 围栏对象(二)
GPU 和 CPU 之间的同步 CPU 必须执行 MonitoredValue 的更新,并读取 CurrentValue,以确保不会丢失正在进行的信号中断通知。 当向系统中添加新的 CPU 等待程序时,或者如果现有的 CPU 等待程序失效时,OS 必须修改受监视的值。OS …...
23种设计模式之《模板方法模式(Template Method)》在c#中的应用及理解
程序设计中的主要设计模式通常分为三大类,共23种: 1. 创建型模式(Creational Patterns) 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。 工厂方法模式࿰…...
DEV-C++ 为什么不能调试?(正确解决方案)
为了备战pat考试,专门下载了DEV C,然后懵圈的发现,怎么无法调试(╯□)╯︵ ┻━┻ 然后整了半天,终于在网上找到相应的解决方案!!!-> Dev C 5.11 调试初始设置 <- 一共四步…...
【C++设计模式】第五篇:原型模式(Prototype)
注意:复现代码时,确保 VS2022 使用 C17/20 标准以支持现代特性。 克隆对象的效率革命 1. 模式定义与用途 核心思想 原型模式:通过复制现有对象(原型)来创建新对象,而非通过new构造。关键用…...
告别pip install torch:手把手教你离线安装PyTorch 1.5.1(含CUDA 9.2配置)
离线环境下的PyTorch 1.5.1实战部署指南:从依赖解析到CUDA配置 在科研机构封闭网络或企业开发环境中,离线安装深度学习框架往往成为阻碍项目推进的第一道门槛。PyTorch作为动态图计算的代表框架,其离线部署涉及Python环境管理、CUDA驱动适配…...
【免费下载】 符合标准(GB、JB)的SolidWorks模板
符合标准(GB、JB)的SolidWorks模板 【下载地址】符合标准GBJB的SolidWorks模板 本仓库提供了一系列符合国家标准(GB)和机械行业标准(JB)的SolidWorks模板文件,适用于各种工程设计和绘图需求。这些模板涵盖了不同尺寸的…...
NSIS进阶玩法:手把手教你用HM NIS Edit打造个性化安装界面(替换图标、文字与进度条)
NSIS深度定制指南:从默认界面到品牌化安装体验 当用户双击你的安装程序时,第一印象往往决定了他们对产品的整体期待。那些千篇一律的NSIS默认界面,就像穿着标准制服的接待员——功能完备但缺乏个性。作为开发者,我们完全有能力让安…...
深入SmoothL1Loss:从Faster R-CNN到YOLO,看一个损失函数如何影响模型精度
深入解析SmoothL1Loss:目标检测模型中的边框回归利器 在目标检测领域,边框回归(Bounding Box Regression)是决定模型定位精度的关键环节。当我们翻阅Faster R-CNN、YOLOv3等经典模型的源码时,会发现一个反复出现的损失…...
铸件去毛刺,伯朗特机器人带气动打磨头,恒力去除浇口残余
在铸造行业,无论是金属还是非金属铸件,脱模后都会不可避免地产生飞边、毛刺及浇口残余。这些瑕疵不仅影响产品外观,更可能妨碍后续装配,甚至在部件受力时成为应力集中点,影响产品使用寿命与安全性。传统的人工去毛刺作…...
如何快速掌握哔哩下载姬Downkyi:面向新手的完整使用指南
如何快速掌握哔哩下载姬Downkyi:面向新手的完整使用指南 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等&…...
无王无帝定乾坤,来自田间第一人 海棠藏圣定山河
无王无帝定乾坤,来自田间第一人。 自古山河安定,世人皆归功于帝王镇守、朝堂统御, 仿佛万里乾坤唯有王权可镇、唯有霸业可安。 然则山河气运自有天道,世间安定自有公理, 强权只能维系一时疆域,正道方能稳固…...
别再用strlen了!C++里sizeof和字符数组的坑,我帮你踩完了
别再用strlen了!C里sizeof和字符数组的坑,我帮你踩完了 在C编程中,处理字符串和字符数组时,sizeof和strlen这两个看似简单的概念常常让初学者陷入困惑。特别是在信息学竞赛或日常编程中,错误地使用它们可能导致难以察…...
C# + OpenCVSharp实战:搞定工业零件旋转角度匹配(附完整源码)
C# OpenCVSharp工业视觉实战:高精度旋转零件匹配的工程化实现 在自动化生产线中,零件定位的准确性直接关系到装配质量和生产效率。当数以千计的金属零件以随机角度通过传送带时,传统的人工检测或固定角度的模板匹配方法往往束手无策。某汽车…...
拷贝漫画第三方客户端完全解析:解锁高效漫画阅读新体验
拷贝漫画第三方客户端完全解析:解锁高效漫画阅读新体验 【免费下载链接】copymanga 拷贝漫画的第三方APP,仅提供基础功能,更多丰富功能请移步官方版本 项目地址: https://gitcode.com/gh_mirrors/co/copymanga 在数字阅读日益普及的今…...
