Ubuntu教学系列(四):软件包管理深度解析(从APT到源码编译)

引言

在Ubuntu系统的使用与开发中,软件包管理是用户必须掌握的核心技能之一。从依赖关系的精准解析到软件的高效安装与清理,每个环节都直接影响着开发效率与系统稳定性。然而,面对复杂的依赖冲突、多样的安装方式以及潜在的版本兼容性问题,许多观众老爷常感到无从下手。为此,本文以“系统性、实用性、深度解析”为目标,围绕Ubuntu软件包管理的全生命周期展开,旨在为各位观众老爷提供一套清晰、可落地的解决方案。

最后,如果大家喜欢我的创作风格,请大家在评论区评论 “666”“催更”,你们的支持就是我创作最大的动力!如果各位观众老爷觉得我哪些地方需要改进,请一定在评论区告诉我,马上改!在此感谢大家了。

各位观众老爷,本文通俗易懂,快速上手Ubuntu系统实操,收藏本文,关注up不迷路,后续将持续分享Ubuntu系统纯干货(请观众老爷放心,绝对又干又通俗易懂)。请多多关注、收藏、评论,评论区等你~~~





正 文

一、软件包依赖管理

本章工作内容围绕软件包依赖管理构建了一套完整方法论,涵盖依赖定义、诊断、修复及版本控制全流程。整套体系从理论到实践贯通依赖生命周期管理,降低环境不一致性风险,提升开发运维效率与软件交付质量。由于不同算法所需要的依赖版本不同,不建议在bash环境下直接安装与运行依赖和算法,推荐使用容器和虚拟环境,这样能够很好的避免出现干扰的情况。

本章节中出现的apt指令,第二章会进行详细解释,请各位观众老爷先暂时只需要能够会使用即可!


1.1 依赖类型与关系

1.1.1 依赖类型定义

软件包依赖类型与关系是构建可靠软件环境的核心要素,其本质在于描述不同组件间的相互作用及约束条件。依赖类型主要包括编译时依赖运行时依赖可选依赖冲突依赖传递依赖。这些类型通过依赖关系形成复杂的网络结构。理解类型与关系后,可针对性优化依赖声明(如缩小版本范围)、拆分模块或使用虚拟环境隔离冲突,从而提升系统的稳定性与可维护性。

(一)编译时依赖 vs 运行时依赖

编译依赖和运行依赖也叫做 强依赖(Depends),顾名思义,也就是想要软件运行所必要的依赖!必须要安装!

(二)可选依赖

可选依赖实际上是非必要的依赖,理论上讲,安与不安本质上并不影响软件的运行,主要应用于功能扩展支持。我们把这部分依赖叫做 推荐依赖(Recommends) 和 建议依赖(Suggests) 。

注释: 以下是 Debian/Ubuntu 系统中通过命令行查询 强依赖(Depends)推荐依赖(Recommends)建议依赖(Suggests) 的具体操作:

依赖类型命令格式作用
强依赖apt show <包名> | grep "Depends"查询必需依赖项
推荐依赖apt show <包名> | grep "Recommends"查询推荐安装的非必需组件
建议依赖apt show <包名> | grep "Suggests"查询可选的附加功能或文档
综合查询apt show <包名> | grep -E "Depends|Recommends|Suggests"同时显示三类依赖

(三)冲突依赖

依赖冲突实际上就是两个或多个软件包之间不能同时进行安装,或者版本/功能互斥,否则会引起报错。例如,同时安装 mysql-servermariadb-server就会引起报错。

sudo apt install mysql-server mariadb-server
# 报错:mariadb-server 与 mysql-server 冲突

(四)传递依赖

传递依赖通常出现在使用构建工具(如 npm )管理项目依赖的场景中,虽然简化了依赖管理,但也可能引发版本冲突和安全风险。建议应结合工具链主动分析依赖树,必要时通过排除、锁定版本或升级来解决隐患。

1.1.2 依赖关系查询

依赖关系查询帮助了解项目中直接依赖、传递依赖的层级结构和版本信息。查询办法较多,主要给各位观众老爷列出以下三种办法,仅供参考。

(一)正向依赖树

展示项目直接依赖的包及其嵌套传递依赖的层级结构。

# 查看包的依赖链(以 curl 为例)
apt depends curl              # 输出直接依赖

(二)反向依赖追踪

查找系统中哪些已安装包依赖于指定包,列出反向依赖链。

# 查看包的依赖链(以 curl 为例)
apt rdepends curl            # 查看反向依赖(哪些包依赖 curl)

(三)npm/Node.js可视化依赖查询

可生成依赖树,直观显示模块间的层级与版本关联。

# 查看完整的依赖树(包含传递依赖)
npm ls                                 
# 输出树状结构,例如:
# my-app@1.0.0
# ├─┬ express@4.18.2
# │ ├── accepts@1.3.8         # 传递依赖
# │ └─┬ body-parser@1.20.2
# │   └── bytes@3.0.0        # 嵌套传递依赖

1.2 依赖问题诊断

1.2.1 常见错误类型

常见错误类型主要分为 依赖未安装依赖不满足版本冲突

# 依赖未安装
错误:无法安装,因为 包A 未安装。

# 依赖不满足
错误:无法安装,因为 包A 需要 包B (>= 2.0),但 包B 1.5 已安装

# 版本冲突
错误:包A 与 包B 冲突,无法共存

1.2.2 诊断工具

(一)模拟安装测试
模拟安装是功能预览包安装过程,无需实际修改系统。建议在关键操作前始终使用模拟安装验证!

sudo apt install -s <包名>        # 模拟安装
sudo apt remove -s <包名>         # 模拟卸载
sudo apt upgrade -s               # 模拟升级所有包

(二)检查损坏包

在 Debian/Ubuntu 系统中,常使用 dpkg 查找和修复损坏的软件包。(后续会解释dpkg指令)

dpkg -l | grep ^..r     # 查找状态异常的包(r=需要修复)

1.3 依赖问题解决

1.3.1 自动修复

以下是修复 Debian/Ubuntu 系统中损坏依赖问题的常用方法,结合实践中的经验(一般来讲依赖损坏的情况不多,反正我跑算法时,基本不会损坏,并且合理使用Dockerconda非常重要,不会影响bash环境,这也是我不慌的原因):

主要使用APT自动修复工具,适用场景为安装/卸载中断、依赖链断裂、软件包状态异常(如 iF 或 rc,iF:半配置状态;rc:未完全卸载状态)。

# 修复依赖关系,自动补全依赖
sudo dpkg -i some-package.deb  # 手动安装时,提示依赖缺失
sudo apt --fix-broken install  # 修复中断的依赖链
sudo apt-get -f install        # 等效操作

sudo apt upgrade               # 升级过程中报错
sudo apt --fix-broken install  # 修复依赖后重试

# 若修复过程中提示版本冲突,可尝试指定版本 
sudo apt install <package>=<version>

# 配置所有未配置的软件包
# 出现:E: dpkg 的操作被中断了,您必须手动执行 'sudo dpkg --configure -a' 以修复这个问题。  
sudo dpkg --configure -a

# 全面升级系统
sudo apt full-upgrade         # 全面升级系统

1.3.2 手动干预

强制版本降级,给各位观众老爷列举一个比较经典的案例,“ libcurl3 与 libcurl4 冲突”。

# 指定兼容版本
sudo apt install 包名=特定版本号

# 解决 libcurl3 与 libcurl4 冲突
sudo apt remove libcurl4                     # 移除冲突包
sudo apt install libcurl3=7.68.0-1ubuntu2    # 安装指定旧版本

1.4 版本控制

固化特定版本的依赖是解决版本冲突、确保构建稳定性的关键步骤。

# 固定软件包版本(防止自动升级)
sudo apt-mark hold nginx              # 锁定 nginx 版本
sudo apt-mark showhold                # 查看已锁定的包

# 查看锁定状态
sudo apt-mark showhold                     # 列出所有被锁定的包

# 解除锁定状态
sudo apt-mark unhold <package-name>     # 解除禁止

实际上,可以通过安装指定版本,也可实现类似效果!

sudo apt install <package-name>=<version>

1.5 章尾总结

这部分工作内容完全聚焦依赖管理的核心闭环:理解依赖类型 → 诊断问题 → 解决冲突 → 控制版本升级

注意事项

  1. 谨慎降级核心包:如 glibcsystemd 可能导致系统崩溃;
  2. 依赖隔离优先:使用 虚拟环境容器 处理非关键依赖冲突;
  3. 定期更新系统sudo apt update && sudo apt upgrade 减少累积问题;

二、软件包安装方式

Linux系统的软件包管理工具种类繁多,不同工具在功能、依赖处理、适用场景等方面存在显著差异。本章工作内容将从多角度深入对比分析aptdpkg.debSnap 的核心区别,并结合实际用例说明如何选择最佳工具。

2.1 APT 在线安装(官方源)

2.1.1 基本概念

apt 命令全称为Advanced Packaging Tool,是 Ubuntu/Debian 系统的核心软件包管理工具,用于自动化处理软件包的 安装、更新、卸载、依赖管理 等操作。其整合了apt-getapt-cacheapt-config 的常用功能,简化了操作流程,更适合普通用户日常使用(如 apt install 显示安装进度),但需管理员权限sudo执行。

2.1.2 apt 常见使用示例

# 下面这两个命令长得挺像的,别混淆,CET 4单词
sudo apt update          # 更新软件源列表,必须首先执行!!! 
sudo apt upgrade         # 升级所有可升级的包 
sudo apt full-upgrade    # 处理依赖关系变更

# 软件安装/卸载
sudo apt install nginx           # 安装软件包 nginx
sudo apt remove nginx            # 卸载软件包(保留配置) 
sudo apt remove --purge nginx    # 彻底删除(含配置)
sudo apt purge nginx             # 彻底删除(含配置)
# 两者删除效果相同,只是语法设计不同,官方推荐第二种。

# 搜索软件包
sudo apt search "python3 package"     # 搜索软件包 python3 package
sudo apt show package_name            # 查看详细信息

有些看官老爷就要问了:你说的这个我听过啊,但好像是apt-get吧?你是不是记错了啊,少打了“-get”,是不是在忽悠我啊!从实招来!!!

这可就冤枉我了,初学安装指令的看官老爷,经常能看到这两种安装指令,虽然都可以使用,但aptapt-get还是有一定区别的,具体如下表所示:

对比维度aptapt-get
发布时间2014 年(Debian 8 起默认)1998 年(早期版本)
功能定位用户友好型工具,整合常用操作底层工具,适合脚本调用
命令功能支持 searchshow等直接搜索需结合apt-cache实现搜索
依赖处理自动删除旧版本包释放空间保留旧版本包,需手动清理
输出信息显示升级包数量、进度条等详细信息仅输出基础操作日志
应用场景日常优先选择apt,操作更直观且功能全面脚本开发建议沿用apt-get,因其稳定性更高,兼容历史脚本

2.1.3 终端 apt 命令行**

# 标准流程
sudo apt update                # 更新软件源
sudo apt install 包名          # 安装最新版(如 `sudo apt install git`)

# 指定版本安装
sudo apt install 包名=版本号   
sudo apt install docker-compose-plugin=2.12.2   # example

2.2 .deb 包本地安装

2.2.1 基本概念

说明
定义Debian系列的二进制包格式,包含软件的可执行文件、配置文件及元数据。
特点依赖外部库,需通过包管理工具处理依赖关系。
适用场景Debian系发行版的标准化安装包,适合从本地或软件源安装。

通过上述基本概念,我们可以得知.deb 实际上就是一个集成的安装包,在实际过程中,还是需要我们在网上下载.deb软件包进行安装,这就不得不认识一个新的工具— dpkg !

说明
定位底层的包管理工具,直接操作.deb文件。
功能安装、卸载、查询已安装的.deb包,但不处理依赖关系
局限性安装失败时需手动修复依赖(如使用apt install -f)。

2.2.2 .deb 安装方法

安装前,先进入.deb软件包所在路径下,然后再运行下面的命令行。

sudo dpkg -i package.deb     # 安装本地.deb文件

2.3 Snap 容器化安装(不推荐)

2.3.1 基本概念

说明
定义由Canonical主导的跨发行版容器化包格式 .snap,包含软件及其所有依赖。
特点自包含:无需外部依赖,支持隔离运行环境;
自动更新:强制更新机制,用户无法禁用;
跨平台:可在任何支持Snap的Linux发行版上运行;
缺点安装包体积大,启动速度较慢,且与系统主题集成较弱

2.3.2 Snap 安装方法

sudo snap install package       # 安装Snap包

2.4 源码编译安装( 必须要会!!

2.4.1 源码编译安装通用流程

源码编译安装一般包含以下步骤:

  1. 环境准备:安装编译器、构建工具(如CMake)、基础依赖库;
  2. 依赖安装:根据项目要求安装特定依赖项(如第三方库);
  3. 源码获取:通过Git克隆或下载压缩包;
  4. 编译与安装:执行编译命令并安装到系统路径;
  5. 测试验证:运行示例或测试脚本验证功能;

2.4.2 以 ORB_SLAM3 为例的编译安装详解

  1. 环境准备
    基础工具的安装,gitg++cmakevim
# 安装Git、G++、CMake、Vim
sudo apt install git g++ cmake vim
  1. 依赖安装
    (1)Eigen3 — 线性代数库
    必须使用源码编译安装,避免apt安装路径问题!
git clone https://github.com/eigenteam/eigen-git-mirror
cd eigen-git-mirror && mkdir build && cd build
cmake .. && sudo make install  # 默认安装至/usr/local/include/eigen3

注释:

# 从 GitHub 克隆 Eigen 库的官方镜像仓库
git clone https://github.com/eigenteam/eigen-git-mirror  # git clone 会创建一个名为 eigen-git-mirror 的目录,并将仓库内容下载到该目录。

# 进入仓库目录,创建并切换到 build 子目录。
cd eigen-git-mirror && mkdir build && cd build
# 等效操作
cd eigen-git-mirror
mkdir build
cd build

# 生成构建系统文件(如 Makefile)
cmake ..
# .. 表示 CMakeLists.txt(项目配置文件)位于上一级目录。
# CMake 会自动检测系统环境(如编译器、依赖库)并生成适配的构建规则。

# 编译并安装库文件到系统目录
sudo make install

(2)Pangolin — 可视化库
依赖项:

sudo apt install libgl1-mesa-dev libglew-dev libpython2.7-dev pkg-config

编译安装:

git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin && mkdir build && cd build
cmake .. && make -j4 && sudo make install

注释:

# 和Eigen3编译安装相同部分就不再进行解释

# 编译源码
make -j4    # 使用 4 个线程并行编译代码。
# 指定并行任务数(通常设为 CPU 核心数,如 4 核用 -j4,8 核用 -j8),一般推荐j2,避免编译失败。

在软件编译过程中,使用 make -j4 与否通常由项目的性质和构建需求决定,以下是两者的关键区别:

项目关键步骤 是否有必要用 -j4
Eigen头文件复制(无编译) ❌ 不需要
Pangolin编译源代码 → 链接 → 安装 ✅ 推荐使用(节省时间)

(3)OpenCV — 图像处理库
推荐OpenCV 3.4.x(避免4.x的.pc文件缺失问题)。

# 安装依赖
sudo apt install libgtk2.0-dev libjpeg-dev libtiff5-dev libjasper-dev
# 编译安装(以3.4.3为例)
unzip opencv-3.4.3.zip && cd opencv-3.4.3
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j4 && sudo make install

(4)Boost库
用于多线程和文件系统操作

wget https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz
tar -xzvf boost_1_75_0.tar.gz && cd boost_1_75_0
./bootstrap.sh && sudo ./b2 install

注释:

# 下载 Boost 源码包
wget https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz

# 解压源码并进入目录
tar -xzvf boost_1_75_0.tar.gz && cd boost_1_75_0

# 生成构建系统
./bootstrap.sh

# 编译并安装
sudo ./b2 install

git clonewget 是两种常用于获取远程资源的命令行工具,但它们的用途和工作机制有本质区别。以下是详细对比:

命令用途
git clone克隆完整的 Git 仓库,包括代码、版本历史、分支和元数据( .git 目录)。
wget从网络下载单个文件或整个目录(静态资源),不涉及版本控制。
  1. 源码获取
git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git
cd ORB_SLAM3
  1. 编译与安装
# 复习以下,下面操作是给予build.sh写入的权限,并运行
chmod +x build.sh
./build.sh
  1. 测试验证
    推荐EuRoC MAV数据集进行数据测试。
./Examples/Stereo-Inertial/stereo_inertial_euroc ./Vocabulary/ORBvoc.txt ./Examples/Stereo-Inertial/EuRoC.yaml /path/to/MH_01_easy ./Examples/Stereo/EuRoC_TimeStamps/MH01.txt

2.5 章尾总结

(一)安装方式对比速查表

方式命令示例适用场景注意事项
APTsudo apt install firefox官方稳定版软件版本可能较旧
DEBsudo dpkg -i chrome.deb第三方.deb包需手动解决依赖
Snapsudo snap install vscode最新版/沙箱隔离占用空间较大
源码./configure && make自定义编译选项需自行维护

(二)注意事项

  1. 优先选择 APT:官方源最安全稳定,对于大多数用户,APT因其自动化依赖处理和软件源集成,是日常管理的首选;
  2. 慎用Snap:仅在需要最新版本、跨平台兼容或应用隔离时使用,注意其性能与存储开销;
  3. 应急使用dpkg:当网络不可用或需调试包安装问题时,可临时使用dpkg,但需配合apt install -f修复依赖;
  4. 避免混合使用工具:同一软件通过不同工具安装可能导致版本冲突,建议统一管理策略;

三、软件包卸载与清理

这部分工作内容主要为承接上一章关于软件的安装,由于部分软件已经不再需要,所以为了提高空间利用率,需要卸载某些软件,这就需要接下来的操作。

3.1 检索软件包

打开终端,查看是否存在某个软件包(这里我给各位观众老爷列出多种方式,选择你喜欢的一款即可 ~~~ ),查不到就说明不存在(没有弹出任何信息或指出不存在):

(一)使用APT管理的包

# 列出所有已安装包
apt list --installed   # 显示简洁列表

# 搜索特定包
dpkg -l | grep -i "包名"   # 过滤关联包(例如 `dpkg -l | grep -i vim`)

# 查看包详情
apt show 包名   # 显示版本、依赖关系等信息

(二)Snap

snap list   # 显示版本及发布者认证状态

(三)手动安装或源码包

# 全局搜索文件路径
which 程序名   # 定位可执行文件(例如 `which firefox`)

# 深度搜索残留文件
find / -name "*程序名*"   # 检查配置文件或手动安装痕迹

3.2 完全卸载

(一)APT卸载

sudo apt purge package       # 卸载软件和配置

(二)dpkg卸载

# 卸载软件
sudo dpkg -r package         # 卸载软件(保留配置)
sudo dpkg --purge package    # 卸载软件并删除所有配置文件
sudo dpkg -P package         # 卸载软件并删除所有配置文件(简写)

# 验证
dpkg -l | grep <包名>        # 若彻底清除,此处应无输出

(三)Snap卸载

sudo snap remove package

3.2 清理无用包

# 删除孤儿包
sudo apt autoremove

# 清理旧内核
sudo apt autoremove --purge

# 清除缓存
sudo apt clean        # 全部删除
sudo apt autoclean    # 仅保留最新

3.3 章尾总结

这一章和上面相比,是比较容易掌握的,难度系数很低,相对也就没什么可总结的了,把上面操作熟练即可!


结 束 语

能够看到这里的观众老爷,无疑是对up的最大肯定和支持,在此恳求各位观众老爷能够多多点赞、收藏和关注(强烈推荐大家关注一下up主和新建的这个合集“Ubuntu系统教学系列”)。在这个合集中,未来将持续给大家分享关于Ubuntu系统生态中的多种常见开发实用操作。未来也将继续分享Docker、conda、ROS等等各种实用干货。感谢大家支持!




往期回顾 — 专栏 “Ubuntu系统教学系列”


专栏: Ubuntu系统教学系列

Ubuntu教学系列(一):安装win11+Ubuntu双系统并配置Ubuntu常用软件

Ubuntu教学系列(二):安装微信和QQ通讯软件以及输入法

Ubuntu教学系列(三): “高频率” 终端命令行指令操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值