我正在寻找为 C++ 二进制文件(但将来可能是任何其他软件)创建安装程序的方法,以包含依赖项,以便最终用户可以独立和离线运行安装程序,因为在某些情况下,软件需要在没有互联网连接的远程位置安装。运行 Gnome 的 Raspberry Pi OS 和 Ubuntu(均为基于 Debian 的发行版)桌面安装需要安装程序。
最多问题在 stackexchange 上,有关为基于 Debian 的发行版离线安装软件包的问题,假设对目标操作系统上已经安装的内容有一些先验知识(或能够找出所需的软件包),并建议生成缺少的软件包列表(sudo apt install --dry-run <package>
),然后从可以访问互联网的机器上下载(apt download
),然后传输到目标机器进行安装,然而,这个问题的目的是在除了操作系统主版本之外对目标机器一无所知的情况下确定选项。
以下是依赖项的示例列表:
ladspa-sdk
libasound2-dev
libcurl4-openssl-dev
libfreetype6-dev
libglu1-mesa-dev
libjack-jackd2-dev
libwebkit2gtk-4.0-dev
libx11-dev
libxcomposite-dev
libxcursor-dev
libxcursor-dev
libxext-dev
libxinerama-dev
libxrandr-dev
libxrender-dev
mesa-common-dev
以已安装的 Raspberry Pi OS (Bullseye) 为例,在没有互联网连接的情况下raspios_arm64-2023-05-03
运行时,sudo apt install --dry-run <dependencies>
会显示 98 个需要安装的软件包列表。如果我随后建立互联网连接来下载这些软件包,其中一些软件包第一次会失败,因为它们已被更高版本取代,不再存在于存储库中,而新版本直到apt update
第一次运行以刷新可用软件包列表时才会被选择:
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/c/curl/libcurl4-openssl-dev_7.74.0-1.3%2bdeb11u7_arm64.deb 404 Not Found [IP: 2a04:4e42:82::644 80]
E: Failed to fetch http://deb.debian.org/debian/pool/main/libx/libx11/libx11-dev_1.7.2-1_arm64.deb 404 Not Found [IP: 2a04:4e42:82::644 80]
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/w/webkit2gtk/gir1.2-javascriptcoregtk-4.0_2.38.5-1%7edeb11u1_arm64.deb 404 Not Found [IP: 2a04:4e42:82::644 80]
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/w/webkit2gtk/gir1.2-webkit2-4.0_2.38.5-1%7edeb11u1_arm64.deb 404 Not Found [IP: 2a04:4e42:82::644 80]
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/w/webkit2gtk/libjavascriptcoregtk-4.0-dev_2.38.5-1%7edeb11u1_arm64.deb 404 Not Found [IP: 2a04:4e42:82::644 80]
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/w/webkit2gtk/libwebkit2gtk-4.0-dev_2.38.5-1%7edeb11u1_arm64.deb 404 Not Found [IP: 2a04:4e42:82::644 80]
运行后sudo apt update
,执行相同的命令会获取上面失败的相同软件包的后续版本,然后可以使用相同的apt download
命令下载这些软件包。
无论如何,在尝试安装到早期 Bullseye 版本的 Raspberry Pi OS 时,下载的 98 个软件包raspios_arm64-2023-05-03
都不是预期的版本,并且这样做会导致很多依赖性错误:sudo dpkg -i *.deb
raspios_arm64-2021-11-08
dpkg: error processing package libglib2.0-dev:arm64 (--install):
dependency problems - leaving unconfigured
dpkg: dependency problems prevent configuration of libglvnd-dev:arm64:
libglvnd-dev:arm64 depends on libegl-dev (>= 1.3.0-1); however:
Package libegl-dev:arm64 is not configured yet.
libglvnd-dev:arm64 depends on libgles-dev (>= 1.3.0-1); however:
Package libgles-dev:arm64 is not configured yet.
dpkg: error processing package libglvnd-dev:arm64 (--install):
dependency problems - leaving unconfigured
dpkg: dependency problems prevent configuration of libglx-dev:arm64:
libglx-dev:arm64 depends on libx11-dev; however:
Package libx11-dev:arm64 is not configured yet.
dpkg: error processing package libglx-dev:arm64 (--install):
dependency problems - leaving unconfigured
dpkg: dependency problems prevent configuration of libharfbuzz-dev:arm64:
libharfbuzz-dev:arm64 depends on libglib2.0-dev (>= 2.19.1); however:
Package libglib2.0-dev:arm64 is not configured yet.
...
Processing was halted because there were too many errors.
如果不捆绑 debian/raspbian 镜像的全部内容并刷新 apt 包索引,我看不出有可靠的方法能够使用 .deb 包为独立离线安装程序安装所需的依赖项。这里还有其他使用 .deb 包安装依赖项的想法吗?
我正在考虑的替代方案是:
- 应用图像
- 扁平包装
- Snapcraft
然而,snapd
和flatpak
都需要安装 apt 依赖项(尽管数量大大减少 - 这可能更易于管理),但除此之外,snaps(至少)还需要一个基础映像(例如 core20、core22)才能运行。
我一直在研究的另一个想法是从所有依赖 .deb 文件中提取共享对象,并将它们作为安装程序的一部分捆绑在一起,提取到特定文件夹然后使用export LD_LIBRARY_PATH=/path/to/shared/objects/folder:$LD_LIBRARY_PATH && ./binary
- 这似乎适用于一些早期实验,但我还没有做过广泛的测试,想知道这是否有点脆弱,或者是否可能需要依赖文件(.so 文件除外)。
Snapcraft 的吸引力在于它得到了 Canonical 的支持,但似乎 AppImages 可能是唯一可靠的部署方法,旨在将运行应用程序所需的所有内容捆绑为独立的可执行文件(而不是安装程序) - 是这样吗,或者有人用其他方式解决了这个问题?