为 Ubuntu 18.04 和 20.04 构建 deb 包:依赖项问题

为 Ubuntu 18.04 和 20.04 构建 deb 包:依赖项问题

我有一个 C++ 二进制应用程序,我将它打包到 Ubuntu 20.04 上的“deb”包中。这个“deb”包有我定义的几个依赖项:

$ dpkg -I my-package-1.0.0.deb 
new Debian package, version 2.0.
...
Package: my-package
Version: 1.0.0
Architecture: amd64
Depends: libfreetype6,libgcc-s1,libgl1,libglew2.1,libglvnd0,libglx0,...
...

这个包运行良好,除了当我尝试在 Ubuntu 18.04 上安装它时:

$ sudo dpkg -i my-package-1.0.0.deb
Selecting previously unselected package my-package.
(Reading database ... 198305 files and directories currently installed.)
Preparing to unpack my-package-1.0.0.deb ...
Unpacking my-package (1.0.0) ...
dpkg: dependency problems prevent configuration of my-package:
 my-package depends on libgcc-s1; however:
  Package libgcc-s1 is not installed.
 my-package depends on libglew2.1; however:
  Package libglew2.1 is not installed.

错误中的这些软件包(libgcc-s1, libglew2.1)在 Ubuntu 18.04 中不存在或存在但版本不同。因此,我有一个一般性问题:

是否可以创建与多个 Ubuntu 版本兼容的“deb”包?如何做?

或者唯一的解决方案是为每个版本的 Ubuntu(以及每个其他 Linux 发行版)构建一个软件包?

当存在依赖关系时,构建“deb”包最常用的策略是什么?

答案1

是否可以创建与多个 Ubuntu 版本兼容的“deb”包?如何做?或者唯一的解决方案是为每个版本的 Ubuntu(以及每个其他 Linux 发行版)构建一个包?当存在依赖关系时,构建“deb”包最常用的策略是什么?

您唯一的解决方案是为每个版本的 Ubuntu 构建一个软件包(以及为每个其他 Linux 发行版构建一个软件包 - 即使您可能不是在制作一个.deb,而是制作一个.rpm或这些发行版使用的任何其他格式)。

这确实是传统 APT 软件包系统(以及 Redhat 和 Arch 上的竞争系统)的一个主要缺点。您的软件必须编译为使用目标系统上恰好存在的依赖项版本。

这是开发 Snap、Flatpak 和 Appimage 等较新的打包系统的主要动机之一。这些系统允许以更少依赖发行版和发行版本的方式打包 Linux 软件。

答案2

正如 Vanadium 所提到的,.deb需要为要支持的每个发行版的每个版本创建软件包。但是,我使用 C++ 可执行文件和库创建了许多软件包,而且我几乎从来不需要列出依赖项(因此,我经常不知道它们在最终软件包中是什么)。

以下是我的一个例子as2js 项目

Depends: libas2js (= ${binary:Version}), ${misc:Depends}

这告诉包生成器自动添加所有依赖项(${misc:Depends}部分)。我添加的唯一显式依赖项是此项目所创建部分的依赖项。在这里,我们看到了对libas2js同一版本的包的依赖。

如果你链接到动态库,你还需要像${shlibs:Depends}这样包含:

Depends: ${shlibs:Depends}, ${misc:Depends}

现在,该列表是根据库和可执行文件中的共享库列表创建的。因此,这正是您当前运行构建的系统所必需的。

如果你想支持 Ubuntu 目前支持的所有版本,我建议你使用电力供应协议针对您的代码(除非 100% 确定)。如果您可以创建 VirtualBox 计算机,您还可以为每个要支持的操作系统版本创建一个实例,并在每台计算机上运行构建系统。

答案3

打开终端并输入:在 Ubuntu 18.04 中将 my-package-1.0.0.deb 文件复制到桌面。打开终端并输入:

sudo apt update
cd ~/Desktop/
wget http://mirrors.kernel.org/ubuntu/pool/main/g/gcc-10/gcc-10-base_10-20200411-0ubuntu1_amd64.deb http://mirrors.kernel.org/ubuntu/pool/main/g/gcc-10/libgcc-s1_10-20200411-0ubuntu1_amd64.deb http://mirrors.kernel.org/ubuntu/pool/universe/g/glew/libglew2.1_2.1.0-4_amd64.deb
sudo apt install ./gcc-10-base_10-20200411-0ubuntu1_amd64.deb ./libgcc-s1_10-20200411-0ubuntu1_amd64.deb ./libglew2.1_2.1.0-4_amd64.deb
sudo apt install ./my-package-1.0.0.deb

上述命令也适用于所有当前支持的 Ubuntu 版本。这是一个幸运的情况。一般来说,不要指望一组神奇的命令适用于所有当前支持的 Ubuntu 版本,因为不同 Ubuntu 版本中同一软件包的软件包依赖关系和软件包依赖关系版本要求可能不同。

在 Ubuntu 20.04 中,依赖包已在默认的 Ubuntu 存储库中可用,因此步骤更加简单。打开终端,将目录更改为cd包含 my-package-1.0.0.deb 的目录,然后输入:

sudo apt install ./my-package-1.0.0.deb

相关内容