Linux:动静态库

article/2025/6/23 9:03:03

一:什么是库

库是写好的,现有的,成熟的可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人都从零开始写,因此库的存在一样非同寻常

本质上库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:

  • 静态库:.a[Linux]、.lib[Windows]
  • 动态库:.so[Linux]、.dll[Windows]

二:静态库 

2-1 本质 

静态库的本质就是将.o文件打包 ,并且.a静态库,本质是一种归档文件,不需要用户解包,而用gcc/g++直接进行链接即可

2-2 ar 命令 

基本语法:

 ar + 选项 + 归档文件(目标静态库文件)+ 成员文件

我们使用 ar -rc libmyc.a *.o 命令即可将当前路径下所有.o文件打包生成一个名为libmyc.a的静态库文件,其中静态库文件libmyc.a的真正文件名名去掉前缀lib和后缀.a剩余的部分,即myc。其中选项rc分别代表着replace和create,即如果已存在的文件发生更新即用更新后的文件替换原有文件,不存在的文件即新建

2-3 静态库的使用 

2-3-1 -L -l 选项 

假设我们将我们自己的代码拷贝至zhangsan目录下,如果将一个个.c和.h拷贝至zhangsan目录下将会非常麻烦而且非常费时(特别是文件很多的时候), 我们就可以将我们当前目录下的.c文件打包形成一个静态库文件并将这个静态库文件libmyc.a拷贝至zhangsan目录下,并将所有的.h文件拷贝至zhangsan目录下,如下图所示:

可是当我们使用 gcc -o usercode usercode.o 命令将usercode.o文件形成可执行文件usercode的时候为什么会报错表示找不到对应的方法呢?如下图所示:

 这是因为这些函数在自定义的静态库内实行的,而我们没有指定链接需要的库,那么就可以使用gcc -o usercode usercode.o -l myc 命令来指定需要库,其中 -l myc 表明在链接过程中去myc库中查找需要的源文件,可是我们执行了该命令后还是报错了,这是为什么呢?

这是因为静态库链接失败了,找不到指定要链接的库myc,这是因为静态库链接时会在系统指定的静态库路径下查找静态库文件,而我们如果需要链接我们自己的静态库文件就需要指定路径去查找静态库。因此如果我们要连接任何非C/C++的标准库(包括其他外部和我们自己写的),都需要指明 -L + 路径 表明去哪里找库和 -l + 静态库真正文件名 表明找什么库。因此当我们执行gcc -o usercode usercode.o -L .  -l myc 命令的时候就会在当前目录下查找名为myc的库,如下图所示,可以看到生成了可执行文件usercode

2-3-2 -I 选项

如上所示:在zhangsan目录下,mystdio.h 和 mystring.h这两个头文件在 ./lib/include目录下,而libmyc.a在 ./lib/mylib目录下,而usercode.c就在zhangsan 目录下 。如果我们此时直接执行gcc -c usercode.c 命令将usercode.c文件生成对应的同名.o文件就会报错 如下图所示:

可以看到提示我们找不到mystring.h这个我们自己写的头文件,这是因为这个头文件不在当前目录下也不在系统里面,而是在我们自己保存的路径下,因此我们需要提示编译器在哪里找我们的头文件。我们可以使用 -I + 路径 表明编译器也要在指定路径下查找头文件,执行 gcc -c usercode.c -I ./lib/include 命令就会生成对应的.o文件,如下图所示:

三:动态库(共享库)

3-1 动态库的生成

在前面我们提到静态库的生成依靠ar工具,而动态库文件的生成依靠gcc就可以了。首先我们先将.c 文件生成对应的 .o 文件,然后依赖gcc工具执行命令,详细步骤如下:

首先执行 gcc -fPIC -c *.c 命令将所有的.c 文件生成对应的同名 .o 文件,其中 -fPIC 是位置无关码,这里不做多解释,接着执行 gcc -shared -o libmyc.so *.o 命令表示将所有的 .o 文件生成一个动态链接库libmyc.so,其中动态链接库的真正名为去掉前缀 lib 和后缀 .so 后剩余的部分即myc,而-shared表明生成的是动态链接库而不是生成指定的可执行文件,如下图所示:

那么我们怎么查看我们生成的是动态链接库而不是可执行文件呢?执行file libmyc.so可查看libmyc.so文件的类型和相关信息,结果如下:

 3-2 -I -L -l 选项

如上所示:在zhangsan目录下,mystdio.h 和 mystring.h这两个头文件在 ./lib/include目录下,而libmyc.so在 ./lib/mylib目录下,而usercode.c就在zhangsan 目录下 。如果我们此时直接执行gcc -o usercode usercode.c 命令将usercode.c文件生成可执行文件usercode就会报错 如下图所示:

可以看到提示我们找不到mystring.h这个我们自己写的头文件,这是因为这个头文件不在当前目录下也不在系统里面,因此我们需要指定自己头文件的路径,执行 gcc -o usercode usercode.c -I lib/include/ 系统也就会在lib/include/路径下寻找头文件,然后报错表示找不到库,如下所示(原因同静态库所写一样)

执行 gcc -o usercode usercode.c -I lib/include/ -l myc 命令查找myc库还是报错,如下所示找不到库,那么我们就需要指定查找库的路径,执行 gcc -o usercode usercode.c -I lib/include/ -L lib/mylib/ -l myc 命令

可是运行时却报错表明找不到动态库如下图所示,可是我们在运行的时候不是已经告诉编译器在哪里在动态库并且动态库存在吗?

我们执行  ldd usercode  命令用来查看动态库myc的动态链接库的依赖关系,如下图所示:我们可以看到出现  libmyc.so => not found  的提示,意味着系统找不到libmyc.so这个动态链接库,这是为什么呢?

这是因为我们执行  gcc -o usercode usercode.c -I lib/include/ -L lib/mylib -l myc 命令时我们只告诉了gcc 去哪里找libmyc.so 这个动态链接库而没有告诉系统去哪里找所以系统在自己的默认路径下找不到就会报错,那么为什么动态库会出现这个情况而静态库却没有出现这个情况呢?这是因为静态库在链接时是直接将库的实现拷贝到可执行程序里,一旦形成可执行程序,可执行程序不再依赖静态库,而动态库在链接时在加载可执行程序的同时还要找到依赖的动态库,那怎么解决呢?

方法一:软链接

执行 sudo ln -fs /home/cwy/cw/linux/lesson22/zhangsan/lib/mylib/libmyc.so /lib64/libmyc.so 命令在lib64下创建一个libmyc.so的文件并将 /lib64/libmyc.so 软链接到前者 /home/cwy/cw/linux/lesson22/zhangsan/lib/mylib/libmyc.so

方法二:LD_LIBRARY_PATH

LD_LIBRARY_PATH是Linux下的一个环境变量,当操作系统运行程序时系统除了会在标准路径下查找程序运行所需要的动态库外,也会在该环境变量下查找动态库,而且LD_LIBRARY_PATH经常都是空的,但是不影响

执行 export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/cwy/cw/linux/lesson22/zhangsan/lib/mylib命令就会在环境变量LD_LIBRARY_PATH上添加/home/cwy/cw/linux/lesson22/zhangsan/lib/mylib这个目录。因此在执行 ./usercode 命令时,不仅会在系统的标准路径下查找动态库,还会在 /home/cwy/cw/linux/lesson22/zhangsan/lib/mylib 这个目录下查找动态库,从下图可以看得到我们成功将所需要的动态库libmyc.so 动态库链接成功.但是根据我们前面学过的环境变量的知识,环境变量的存在只是临时的,一旦将XShell关闭那么这个环境变量将不存在

方法三:/etc/ld.so.conf

/etc/ld.so.conf是Linux系统中用于配置动态链接库搜索动态库路径的配置文件,用于指定系统在运行时搜索动态库的目录路径。即系统在运行时也会在/etc/ld.so.conf路径下查看所有动态库的路径来查找动态库

首先在 /etc/ld.so.conf.d/ 的目录下创建一个后缀为conf的配置文件,例如执行 sudo touch /etc/ld.so.conf.d/dong.conf 命令即在/etc/ld.so.conf.d/路径下创建一个名为dong.conf 的配置文件,如下图所示创建成功

接着将需要使用的动态库路径通过编译器写入dong.conf这个文件中,这里使用nano日记写入,执行 sudo nano /etc/ld.so.conf.d/dong.conf 命令,将libmyc.so 动态库所在的路径 /home/cwy/cw/linux/lesson22/zhangsan/lib/mylib 写进去就行,如下图所示,将文件中的内容打印出来就是这个动态库所在的目录路径,表明写入成功

但是到这一步还不行,我们还需要执行 sudo  ldconfig  更新配置文件

四:动静态库

动静态库能否同时存在呢?如果能同时存在又会如何呢?答案是动态库和静态库可以同时存在并且动态库和静态库同时存在的时候,会发生动态链接。如下图所示:在当前路径下,同时存在着libmyc.a这个静态库和libmyc.so这个动态库

当我们执行 gcc -o code usercode.c -I lib/include/ -L lib/mylib/ -l myc  命令时,我们没有指定是链接libmyc.a这个静态库还是链接libmyc.so这个动态库只是表明查找myc这个库,可以看到编译器默认链接了动态库。因此

那如果我们就是想使用静态链接呢?那就必须指定 -static  ,如果要静态链接必须存在静态库,如果不存在就会报错,如下所示:


http://www.hkcw.cn/article/mftrKCkLxp.shtml

相关文章

【图像处理入门】2. Python中OpenCV与Matplotlib的图像操作指南

一、环境准备 import cv2 import numpy as np import matplotlib.pyplot as plt# 配置中文字体显示(可选) plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False二、图像的基本操作 1. 图像读取、显示与保存 使用OpenCV…

设计模式——装饰器设计模式(结构型)

摘要 文中主要介绍了装饰器设计模式,它是一种结构型设计模式,可在不改变原有类代码的情况下,动态为对象添加额外功能。文中详细阐述了装饰器模式的角色、结构、实现方式、适合场景以及实战示例等内容,还探讨了其与其他设计模式的…

生活小记啊

最近生活上的事情还是蛮多的,想到哪写到哪。 工作 三月的某个周六,正在加班写技术方案,大晚上写完了听到调动通知,要去新的团队了。 还是蛮不舍的,看着产品从无到有,一路走过来,倾注了不少感…

【android bluetooth 案例分析 04】【Carplay 详解 2】【Carplay 连接之手机主动连车机】

1. 背景 在【android bluetooth 案例分析 04】【Carplay 详解 1】【CarPlay 在车机侧的蓝牙通信原理与角色划分详解】中我们从整理上介绍了车机中 carplay 相关基础概念。 本节 将详细分析 iphone手机主动 连接 车机carplay 这一过程。 先回顾一下 上一节, carpla…

【Kotlin】数字字符串数组集合

【Kotlin】简介&变量&类&接口 【Kotlin】数字&字符串&数组&集合 文章目录 Kotlin_数字&字符串&数组&集合数字字面常量显式转换数值类型转换背后发生了什么 运算字符串字符串模板字符串判等修饰符数组集合通过序列提高效率惰性求值序列的操…

FreeCAD源码分析: 串行化工具

本文分析FreeCAD中的串行化工具。 注1:限于研究水平,分析难免不当,欢迎批评指正。 注2:文章内容会不定期更新。 零、预修 0.1 QDataStream 0.2 Boost.Iostreams 0.3 Zipios 0.4 Xerces-C 一、核心组件 1.1 Base::Writer 1.2 Ba…

【R语言编程绘图-plotly】

安装与加载 在R中使用plotly库前需要安装并加载。安装可以通过CRAN进行,使用install.packages()函数。加载库使用library()函数。 install.packages("plotly") library(plotly)测试库文件安装情况 # 安装并加载必要的包 if (!requireNamespace("p…

设计模式——系统数据建模设计

摘要 本文主要介绍了UML在软件系统分析和设计中的应用,详细阐述了六大类关系(泛化、实现、依赖、关联、聚合、组合)及其在UML类图中的表示方法,并通过具体例子说明了这些关系在实际编程中的应用。同时,文章还概述了UM…

37. Sudoku Solver

题目描述 37. Sudoku Solver 回溯 class Solution {vector<vector<bool>> row_used;vector<vector<bool>> col_used;vector<vector<bool>> box_used;public:void solveSudoku(vector<vector<char>>& board) {row_used.r…

【Java开发日记】基于 Spring Cloud 的微服务架构分析

目录 1、Spring Cloud 2、Spring Cloud 的核心组件 1. Eureka&#xff08;注册中心&#xff09; 2. Zuul&#xff08;服务网关&#xff09; 3. Ribbon&#xff08;负载均衡&#xff09; 4. Hystrix&#xff08;熔断保护器&#xff09; 5. Feign&#xff08;REST转换器&a…

进程间通信IV System V 系列(linux)

目录 消息队列 原理 操作 补充概念 信号量 (原子性计数器) 原理 操作 (和共享内存相似) 总结 小知识 消息队列 原理 在内核中建立一个队列&#xff0c;进程可以相互进行通信&#xff0c;通过队列进行IPC&#xff0c;就是进程之间发送带类型的数据块。 操作 接口和共享…

【MySQL】索引(B+树详解)

MySQL(五)索引 一、索引的减I/O设计 1.读取量 2.搜索树 2.1方向 2.2有序 3.分多叉 3.1B树 弊端: 3.2B树 3.2.1非叶子-搜索字段 3.2.1.1海量分叉 3.2.1.1.1最大式 3.2.1.1.2最快式 3.2.1.2缓存内存 3.2.1.2.1字段总量小 3.2.1.2.2时间复杂度 3.2.1.3区间搜索向…

2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷4:共计6题带解析)

2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷4:共计6题带解析) 第1题:最佳情侣身高差(题目及解析) 题目描述 专家通过多组情侣研究数据发现,最佳的情侣身高差遵循着一个公式:(女方的身高) 1.09 =(男方的身高)。如果符合,你俩的身…

5.31 day33

知识点回顾&#xff1a; PyTorch和cuda的安装 查看显卡信息的命令行命令&#xff08;cmd中使用&#xff09; cuda的检查 简单神经网络的流程 数据预处理&#xff08;归一化、转换成张量&#xff09; 模型的定义 继承nn.Module类 定义每一个层 定义前向传播流程 定义损失函数和优…

【C++】模板

目录 1、函数模板 基本用法 函数模板的实现原理 函数模板的实例化 模板参数的匹配原则 2、类模板 类模板的定义格式 类模板的实例化 1、函数模板 基本用法 template < typename T >返回值类型 函数名(参数列表){} template 是模板的意思&#xff0c;typename是…

第六十二节:深度学习-加载 TensorFlow/PyTorch/Caffe 模型

在计算机视觉领域,OpenCV的DNN(深度神经网络)模块正逐渐成为轻量级模型部署的利器。本文将深入探讨如何利用OpenCV加载和运行三大主流框架(TensorFlow、PyTorch、Caffe)训练的模型,并提供完整的代码实现和优化技巧。 一、OpenCV DNN模块的核心优势 OpenCV的DNN模块自3.3…

Linux系统下安装配置 Nginx

Windows Nginx https://nginx.org/en/download.htmlLinux Nginx https://nginx.org/download/nginx-1.24.0.tar.gz解压 tar -zxvf tar -zxvf nginx-1.18.0.tar.gz #解压安装依赖&#xff08;如未安装&#xff09; yum groupinstall "Development Tools" -y yum…

qwen3解读

1. 模型架构 重点&#xff1a; 思维模式和非思维模式这两种不同的操作模式集成到一个模型中。这样可以让用户在这些模式间切换&#xff0c;而不是在不同模型间切换。多阶段的后培训方法&#xff1a;增强推理和非推理模式。将基础模型和人的偏好结合。 预训练阶段&#xff1a…

用127.0.0.1访问VMware虚拟机中间件

文章目录 前言一、虚拟机安装、插件安装二、改虚拟机配置1.更改虚拟机使用的是 NAT 模式2.编辑 VMware 的 NAT 设置并添加端口转发 总结至此大功告成了&#xff01;&#xff01;&#xff01; 前言 docker 安装中间件很方便,平时使用windows作开发,如果想快速安装中间件,那么首…

【大模型部署】mac m1本地部署 ChatGLM3-6B 超详细教程

本人环境&#xff1a;macOS 15.5 (Sonoma) - Apple M1 / 16 G 目标&#xff1a;在 mac m1 16G 上 完全离线 的本地模型目录上&#xff0c;跑通官方 ChatGLM3-6B 目录 背景 & 踩坑记录 准备工作 新建 Conda 环境并安装依赖 关键环境变量 运行 composite_demo 常见报错与…