首页 > 解决方案 > 由 appimage-builder 创建的巨大 appimage

问题描述

我正在将我编写的应用程序打包到 AppImage 中,以便可以将其交付给 Linux 用户。

我正在使用的 GUI 工具包的一个关键特性是它小巧轻便,允许我编译一个静态链接到大约 6Mb 的 GUI 库的构建。

然而,在构建 AppImage 之后——我按照说明进行操作——使用所有功能(基本上只包括使用文件浏览器对话来加载文件)——它会生成一个绝对巨大的 AppImage,大约 200Mb!

我知道 AppImages 应该是“一点点”大,但是当本机编译的二进制文件(包括静态链接的 GUI 工具包)只有 6Mb 时,作为可移植性的提议解决方案,这完全是疯狂的。

但是,我根本不相信我需要全部 200Mb。一个与我非常相似的软件,但另外使用 Qt(相比之下相当臃肿)只有大约 30Mb。我实际上怀疑 appimage-builder 做错了什么 - 我认为它列出了我在使用文件浏览器对话框作为依赖项时探索的目录中的文件(它们是大文件)。我没有其他真正的解释。但如果是这样,我该如何阻止它这样做呢?

为什么我的那么大?我能做些什么呢?

作为记录,我正在使用这种方法来构建我的 AppImage

  1. 分别构建我的二进制文件
  2. 运行appimage-builder --generate并填写表格
  3. 跑步appimage-builder --recipe AppImageBuilder.yml --skip-tests

编辑:删除明显不需要的正在打包的文件已将 appimage 的大小减小到140Mb,但这仍然比我见过的同等 appimage 大 5 倍。是否有一些我不知道的技巧/选项?

标签: linuxportabilityappimage

解决方案


最近几天开始使用 AppImage 并面临同样的问题。

很快:通过任何可能的方式检查您的应用程序的依赖关系,并将配方配置为仅包含具体的依赖关系,并避免包含任何未真正使用的主题/图标/等包:)

我的案例是一个小应用程序,用 Dart (with Flutter) 编写。构建的项目本身重约 22MB(du -sh .在输出目录中)。我的主机操作系统是 Linux Mint (Cinnamon)。

第一次运行appimage-builder --generate它时,我生成了一个“配方”,其中包含要安装的 17 个包和要从中复制的一堆库/lib/x86_64-linux-gnu/。当我从这个配方生成 AppImage 时,结果大约是 105MB,在我看来这对于小型应用程序来说非常大。

我的第一个实验是清理包含的文件部分,因为我猜应该从 apt 安装“所有必要的”库。我参考了网络上的一些配置,其中仅标记了几个库用于 include 和 wasexclude部分,其中包含一些与 DE 相关的文件(主题、字体、图标等)

使用它我得到了大约 50MB 的结果(仍然足够大)。

从这个问题引用了下一个实验 - https://github.com/AppImageCrafters/appimage-builder/issues/130#issuecomment-843288012.bundle.yml不久 - 生成 AppImage 文件后,文件夹内 出现了文件文件AppDir,其中包含已部署的库。建议是尝试从中排除一些东西。appimage-builder可能这是一个足够好的建议,但是如果至少通过(docker 容器)的官方测试破坏了导致 AppImage 文件的结果,则检查每个包/库需要很长时间。我面临的结果比任何合理的尺寸缩减都要多。

我的下一个实验是减少应该从包管理器安装的依赖项并使用主机系统中的文件。我删除了文件夹AppDir并重appimage-builder-cache新生成了食谱。在下一步中,我评论了所有应该从包管理器安装的包,并只留下了包含的文件。结果失败,因为需要一个包,但添加后我得到了 AppImage 结果为 36MB。这听起来比开始 105MB 甚至之前的 50MB 的结果要好得多。

在这里,我得到了小小的“提升”——内置于 AOT 二进制文件中的 Flutter 项目,无需运行时。所以我检查ldd了我的应用程序的输出,然后将所需库的列表映射到 appimage-builder 检测到的库文件列表。最后有些是正确的,有些在输出中找不到,ldd有些在ldd输出中,但 appimage-builder 没有检测到。我添加了所有未检测到的,删除了所有未使用的。我的最终结果是 26MB,它通过了所有 appimage-builder 测试(在 fedora、cent、debian、ubuntu 和 arch 的 docker 镜像中运行)

我知道这对于持续构建来说已经够糟糕了,因为它需要始终检查使用过的库并在发生变化时调整配置,但是对于足够罕见的构建,我想它在好与坏之间有某种平衡。


推荐阅读