[ Technical exchange] 玲珑杀手Go - layer子命令:高效构建玲珑应用,大幅降低磁盘压力
Tofloor
default avatar
System233
deepin
2025-03-11 14:19
Author

玲珑杀手Go - layer子命令:玲珑应用构建革命中的最后一块拼图

前言

在玲珑杀手Go最近更新的v1.4.x版本中,引入了全新的layer子命令,该命令独立于ll-builder之外实现了对玲珑layer文件的构建、打包、挂载/卸载和解析功能,无需生成~/.cache/linglong-builder构建缓存浪费存储空间,也不会产生大量无用的文件复制,大幅增强了玲珑应用的构建体验。

项目主页: https://github.com/System233/ll-killer-go.git

引言

在玲珑应用的打包过程中,传统的 ll-builder 工具因其重复性数据存储、低效的磁盘操作以及对构建环境的不够灵活支持,存在严重弊端。

相较之下,ll-killer 中的 layer 子命令工具以更高效、更轻量、灵活性更强的方式实现了构建与打包流程,尤其在 layer 文件管理上展现出明显优势。

本文将详细介绍 ll-builder 的不足,并着重阐述 ll-killer layer 子命令的核心优势、下载安装步骤以及常用子命令的实际使用案例。

相关内容:关于使用ll-kiler进行应用打包的详细信息,请查看上一篇文章:

玲珑杀手Go:全新玲珑应用本地构建系统,附Ubuntu源GIMP迁移示例-论坛-深度科技

目录


一、ll-builder 的缺点和弊端

ll-builder 在设计上存在严重缺陷,主要包括:

1. 存储浪费严重

每个使用 ll-builder 构建的应用都会在 ~/.cache/linglong-builderlinglong/output 下产生两份副本。即使是玲珑在后续更新中优化了重复的 develop 模块文件,最终仍会有两份重复的 binary 副本。早期玲珑甚至可能产生多达四份副本,虽然玲珑引入的 ostree 仓库可以对部分重复文件做硬链接处理,但依然难以避免同时在~/.cache/linglong-builderlinglong/output 下存在两份重复文件。

玲珑builder的文件存储结构

~/.cache/linglong-builder ├── layers │ ├── {base} │ └── {app} # binary+delelop模块 linglong/output的副本 ├── merged │ └── {app+base} # 通过ostree硬链接叠加实现的副本 ├── repo # ostree仓库 └── states.json . # 玲珑工程目录 ├── linglong │ ├── entry.sh │ └── output │ ├── _build │ ├── binary # binary模块 _build的副本 │ └── delelop # delelop模块 _build的副本 ├── linglong.yaml

2. 磁盘损耗大

在构建过程中,玲珑工程内的 build构建脚本 会将应用文件写入 $PREFIX,之后 ll-builder 会将其复制到 linglong/output/binarydevelop,再复制到 ~/.cache/linglong-builder。打包过程中,由于 mkfs.erofs 不能很好的支持预留文件头空间,还需再复制一遍临时文件以添加文件头,整个流程至少涉及 5 次文件复制,导致读写放大严重,增加了磁盘负担。

数据复制过程:

  1. build构建脚本->$PREFIX(linglong/output/_build)
  2. linglong/output/{binary,develop}
  3. ~/.cache/linglong-builder/{repo,binary,develop}
  4. tmp.erofs
  5. app.layer
  • 在旧版玲珑(约<=1.6.3)中,步骤2和3的读写量继续翻倍。

3. 默认执行 strip

默认启用 strip-symbols 对二进制文件进行符号剔除,这一行为可能对应用产生不可预知的影响,破坏用户对文件的预期。

4. 多任务并行构建问题

由于 ~/.cache/linglong-builder 中引入了 ostree,仅允许单个任务写入;此外,在新版本(v1.7.x)中,多任务构建可能导致自动重命名缓存目录,进而造成缓存损坏,ll-builder无法自行从错误中恢复。

只要同时跑两个ll-builder就有几率导致cache被重命名而重新构建cache。

5. 构建内容频繁清空

每次构建均会清空之前的构建内容,使得在同一构建环境中进行多次调整输出变得困难,同时伴随大量文件复制操作,让构建过程中本就不堪重负的磁盘雪上加霜。

6. 工具扩展性差

ll-builder 只支持内置的工具链,无法动态安装新工具,需要特制的 runtime,而且baseruntime相关的文档说明不足,导致构建难度大。

7. 构建环境与运行时环境不一致

构建时强制引入开发依赖,且开发依赖会在运行时消失,导致在构建环境中不能可靠地进行依赖检查,在构建环境中测试正常的应用可能在构建后无法运行。

8. 不可配置的压缩算法

玲珑在1.7.7版本中给layer引入了高版本erofs才支持的zstd压缩算法,旧版玲珑无法安装,也无法检测是什么问题并告知用户解决方案,且用户无法手动配置压缩算法,这彻底破坏了layer文件的兼容性。

二、ll-killer 构建环境及其优势

针对 ll-builder 的种种弊端,ll-killer 提出了全新的构建与打包解决方案,其核心思路在于将构建环境与运行时环境完全一致,并消除不必要的文件复制与缓存浪费。主要特点包括:

1. 构建环境一致性

  • 在项目的 linglong/filesystem 内维护应用文件,ll-builder 仅作为 base 下载器。
  • 使用 ll-killer build 命令可反复进入构建环境,且退出后不会重置构建内容。
  • 构建环境仅使用 base 中的 binary 模块,完全避免了开发依赖问题,保证了构建与运行时环境一致性。

2. 打包过程更高效

  • ll-killer layer build 命令打包时仅需 2~3 次文件复制:首先运行工程内的buildScript脚本将应用文件复制到 $PREFIX,再利用 mkfs.erofs 命令创建 layer 文件并写入文件头。
  • 通过 mmap+memmove 技术,尽管受 mkfs.erofs 部分 bug 影响,仍然显著提升了在文件头部插入操作的性能。
  • 注:目前第3次复制为mkfs.erofs的bug所致,理想情况下为2次。

复制路径:

  1. build构建脚本->$PREFIX(linglong/output/build)
  2. app.layer
  3. app.layer (插入layer文件头)

3. 磁盘空间与缓存管理优化

  • 打包过程中只会生成一份文件副本,杜绝了 ~./cache/linglong-builder 下大量难以清理的缓存数据。
  • 支持多任务构建,无 ostree 参与,避免了多个项目间的缓存冲突。

4. 速度与灵活性提升

  • 相比 ll-builderll-killer 构建速度更快。
  • 可在宿主机上构建与打包,允许使用宿主机上的工具,提升了整体构建效率与灵活性。
  • 可以自由配置layer文件的各种参数,包括压缩算法。
  • 支持指定根文件系统,可以在任何根文件系统或base中构建。

5. 可靠性加强

  • 没有自定义复制行为,不会出现ll-builder的复制错误 (#1039)
  • 不会擅自修改构建结果中的二进制文件内容(no-strip)

三、ll-killer layer 子命令使用案例

ll-killer 提供了多个子命令来管理 layer 文件,下面分别介绍常用命令及其使用场景。

命令概览

$ ll-killer layer --help 独立于玲珑的layer管理器,提供强大的layer文件处理支持,需要安装erofs-utils。 Usage: ll-killer layer [command] Available Commands: pack 将文件夹打包为layer。 build 无需ll-builder, 直接将当前项目构建为layer。 mount 挂载layer文件。 umount 卸载layer挂载点。 dump 输出layer信息。 Flags: -h, --help help for layer Use "ll-killer layer [command] --help" for more information about a command.
  • 每一个子命令都有详尽的帮助文档,推荐查看。

1. 获取与配置最新 ll-killer

在使用ll-killer工具之前,需要在主机上获取此工具,如果你已经安装最新版本的ll-killer (版本>=1.4.0) 则可以跳过本步骤。

  1. 安装必要依赖
    确保系统中安装了以下依赖:

    # 用于依赖检查和搜索功能 sudo apt install apt-file
  2. 下载最新版本的 ll-killer
    当前最新版本为 v1.4.5,下载命令如下:

    wget https://github.com/System233/ll-killer-go/releases/latest/download/ll-killer-amd64 -O ll-killer chmod +x ll-killer # 镜像地址,如果上面的链接下载不动,可以尝试将链接替换为这个镜像地址。 # https://ll-killer.win/releases/latest/download/ll-killer-amd64

    以上脚本下载的是 amd64架构,ll-killer-go还支持 arm64loong64架构,可以修改链接中的 amd64至其他版本,或进入项目Releases页手动下载。

    03-23日更新 镜像地址:为了解决国内用户的下载问题,维护了一个镜像地址,大家可以将上面命令中的GitHub链接替换为此地址进行下载

    https://ll-killer.win/releases/latest/download/ll-killer-amd64
    同时可以在此地址查看项目的release页,获取更新说明以及每个文件的哈希值等信息:
    https://ll-killer.win/releases

    其他下载方式
    如果上面的链接下不动,可以网上搜索github release 下载加速,然后把链接粘进去加速下载,再把文件放入相应位置。

    ⚠警告:从第三方地址加速下载时,注意文件的安全性。Releases页面提供了各个文件的sha1校验码,在文件下载完成后务必使用 sha1sum校验文件的完整性。

  3. 全局安装(可选)
    为了方便全局使用,可以将 ll-killer 安装到 ~/.local/bin

    mkdir -p ~/.local/bin mv ll-killer ~/.local/bin ll-killer -v

    如果提示找不到命令或 ~/.local/bin 未添加至 PATH,请执行:

    echo 'export PATH=$HOME/.local/bin:$PATH' >>~/.bashrc source ~/.bashrc
  • 后续章节假设ll-killer已全局安装,且ll-killer版本>=1.4.x

2. 高效构建玲珑项目并生成layer

  • 功能说明
    ll-killer layer build子命令在宿主机上启动一个模拟ll-builder的构建环境,直接在宿主机上将当前项目构建为 layer,避免不必要的ostree提交和磁盘复制。

    • 本命令用于取代ll-killer项目中的 ll-builder build+ll-builder export --layer命令组合。
    • 如果项目不基于ll-killer,但构建脚本不使用任何base特定功能,也可以使用本命令加速打包。
    • 如果你希望在构建脚本中使用宿主机中的工具,可以使用本命令进行构建。
    • 🚀 你可以在命令参数中指定根文件系统,如指定使用玲珑的base所在的路径作为rootfs,如不指定则使用宿主机的根目录。

    此构建模式提供以下内容,以模拟ll-builder环境:

    环境变量

    LINGLONG_APPID="{APPID}" PREFIX="/opt/apps/{APPID}/files" TRIPLET="x86_64-linux-gnu|aarch64-linux-gnu|loongarch64-linux-gnu|..." KILLER_PACKER=1 ## killer构建环境标识

    目录

    • /project: 项目目录
    • /run/host/rootfs: 与宿主机相同
    • /: 与指定的rootfs相同。

    后处理

    • 为快捷方式和服务单元添加ll-cli run前缀
    • KILLER_PACKER 标识当前处于killer环境,killer环境下setup.sh会自动跳过符号链接修复,
      可以在启动前设置KILLER_PACKER=0禁用该行为。
  • 示例

    $ ll-killer layer build [准备构建环境] Layer元数据: 名称: curl ID: curl 版本: 8.11.1.0 模块: binary 类型: app 基础: main:org.deepin.base/23.1.0/x86_64 渠道: main 命令行: [/opt/apps/curl/files/entrypoint.sh] 元数据版本: 1.0 描述: command line tool for transferring data with URL syntax curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks. 架构: x86_64 [运行构建脚本] 'test-rel' -> 'test' 'test-abs' -> '/opt/apps/curl/files/test' 'file-abs' -> '/opt/apps/curl/files/file' 'file-rel' -> 'file' 'noext-abs' -> '/notexist' 'noext-rel' -> 'notexist' 'bin-abs' -> '/bin' 'bin-rel' -> 'bin' '/project/applications' -> '/opt/apps/curl/files/share/applications' '/project/applications/gimp.desktop' -> '/opt/apps/curl/files/share/applications/gimp.desktop' '/project/applications/zutty.desktop' -> '/opt/apps/curl/files/share/applications/zutty.desktop' '/project/applications/zutty2.desktop' -> '/opt/apps/curl/files/share/applications/zutty2.desktop' '/project/applications/zutty3.desktop' -> '/opt/apps/curl/files/share/applications/zutty3.desktop' '/project/applications/zutty4.desktop' -> '/opt/apps/curl/files/share/applications/zutty4.desktop' [文件后处理] *处理快捷方式和右键菜单 /opt/apps/curl/files/share/applications/gimp.desktop /opt/apps/curl/files/share/applications/zutty.desktop /opt/apps/curl/files/share/applications/zutty3.desktop /opt/apps/curl/files/share/applications/zutty4.desktop /opt/apps/curl/files/share/applications/zutty2.desktop [打包输出] mkfs.erofs 1.8.2 Build completed. ------ Filesystem UUID: 7009cb7f-896e-4916-9782-4f17dbfc35a0 Filesystem total blocks: 6 (of 4096-byte blocks) Filesystem total inodes: 25 Filesystem total metadata blocks: 3 Filesystem total deduplicated bytes (of source files): 0 文件已输出至: curl_8.11.1.0_x86_64_binary.layer

3. 打包文件夹为 layer

  • 功能说明
    将具有 layer 结构的文件夹(参考 linglong/output/binary 目录)打包为 layer。该命令利用 mkfs.erofs 直接对目录进行打包,省去了传统 ll-builder 中将文件提交到 ostree 的步骤,减少了不必要的文件复制和缓存生成,保护磁盘寿命。

    • 上一节中的 ll-killer layer build 子命令会自动调用本功能,本功能也可以单独使用。
  • 示例

    # 列出文件结构 $ tree -L 1 linglong/output/binary linglong/output/binary ├── curl.install ├── entries ├── files ├── info.json └── linglong.yaml # 打包此文件夹 $ ll-killer layer pack linglong/output/binary mkfs.erofs 1.8.2 Build completed. ------ Filesystem UUID: 2e8c228f-d0d3-4eb4-9bfa-db276c6d9f09 Filesystem total blocks: 10 (of 4096-byte blocks) Filesystem total inodes: 30 Filesystem total metadata blocks: 4 Filesystem total deduplicated bytes (of source files): 0 文件已输出至: curl_8.11.1.0_x86_64_binary.layer

4. 挂载和卸载 layer

  • 挂载 layer
    使用该命令可以将 layer 文件挂载到指定目录,方便查看和调试。

    ll-killer layer mount <layer文件名> <挂载目标目录> -- [erofsfuse 选项]

    示例

    $ ll-killer layer mount curl_8.11.1.0_x86_64_binary.layer curl erofsfuse 1.8.2 <W> erofs: curl_8.11.1.0_x86_64_binary.layer mounted on curl with offset 868 $ ls curl -l 总计 20 -rw-r--r-- 1 system system 291 3月11日 17:36 curl.install drwxr-xr-x 3 system system 44 3月11日 17:36 entries drwxr-xr-x 4 system system 236 3月11日 17:36 files -rwxr-xr-x 1 system system 801 3月11日 17:36 info.json -rwxr-xr-x 1 system system 763 3月11日 17:36 linglong.yaml
  • 卸载 layer
    当不再需要访问挂载内容时,可使用以下命令卸载:

    ll-killer layer umount <挂载目录> -- [fusermount 选项]

    示例

    $ ll-killer layer umount curl $ ls curl -l 总计 0

5. 输出 layer 信息

  • 功能说明
    该命令用于输出 layer 文件的详细信息,帮助用户诊断和验证 layer 内容。

  • 使用方法

    ll-killer layer dump <layer文件> -- [dump.erofs 选项]

    常用参数:

    • -x:显示文件头信息;
    • -l:显示 Layer 信息;
    • -e:显示 Erofs 信息;
    • -a:显示全部信息(默认启用)。

    示例:

    $ ll-killer layer dump curl_8.11.1.0_x86_64_binary.layer Layer文件头: 文件名: curl_8.11.1.0_x86_64_binary.layer 文件大小: 25444 字节 魔数: <<< deepin linglong layer archive >>> 元数据大小: 824 字节 数据偏移量: 868 Layer元数据版本: 版本: 1 Layer元数据: 名称: curl ID: curl 版本: 8.11.1.0 模块: binary 类型: app 基础: main:org.deepin.base/23.1.0/x86_64 渠道: main 命令行: [/opt/apps/curl/files/entrypoint.sh] 元数据版本: 1.0 描述: command line tool for transferring data with URL syntax curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks. 大小: 32063 字节 架构: x86_64 Erofs信息: Filesystem magic number: 0xE0F5E1E2 Filesystem blocksize: 4096 Filesystem blocks: 6 Filesystem inode metadata start block: 0 Filesystem shared xattr metadata start block: 0 Filesystem root nid: 36 Filesystem lz4_max_distance: 65535 Filesystem sb_size: 128 Filesystem inode count: 25 Filesystem created: Tue Mar 11 17:36:11 2025 Filesystem features: sb_csum mtime 0padding Filesystem UUID: cb6e643e-a762-4310-8d50-61d271f1a51d

四、总结

ll-killer 通过重构构建环境,打破 ll-builder 在文件复制、缓存管理、多任务构建及环境一致性方面的局限,实现了更高效、节省资源的构建与打包流程。

无论是打包layer的高效处理,还是直接在宿主机构建的便捷操作,都使得 ll-killer 成为当前构建领域的强有力工具。用户可以通过简单的下载安装步骤迅速上手,并利用丰富的子命令灵活应对各种场景,从而大大提高开发与发布效率。

对玲珑ll-builder的建议

ll-killer已经通过实践中证明在构建阶段引入ostree是100%的负优化,强烈建议删除构建的阶段的~/.cache/linglong-builder,仅保留baseruntime下载功能,进一步降低对磁盘的压力和损耗。

Reply Favorite View the author
All Replies
2 / 2
To page
MeGusta
deepin
2025-03-24 12:22
#21

deepin25更新到当前的linglong1.7.10版本,ll-killer就无法正常运行了,报错如下:

ll-killer-output-20250324.zip

我运行的脚本:

build-qgis-stable-with-inkscape-saga-20250322.zip

Reply View the author
System233
deepin
2025-03-28 18:38
#22
MeGusta

deepin25更新到当前的linglong1.7.10版本,ll-killer就无法正常运行了,报错如下:

ll-killer-output-20250324.zip

我运行的脚本:

build-qgis-stable-with-inkscape-saga-20250322.zip

抱歉现在才看到反馈,之前看到玲珑某个版本改了/tmp目录,会对依赖ll-builder的ll-killer build模式产生影响,因为ll-killer依赖/tmp文件系统与ll-builder容器内的ll-killer传输文件,来实现环境的重入。
由于/tmp文件系统的变化,可能不好修复,不过已经有替代方法,就是弃用ll-builder,使用killer完全接管构建环境。

以下是对你的构建流程有用的更新:

  • 1.4.17 实现了完全无需ll-builder情况下的构建支持,基于layer的自定义base功能,可以使用原生ostree管理玲珑的base,使用make中的ENABLE_OSTREE参数启用。
  • v1.4.11 开始,支持应用的自动化测试,运行make test以使用。
  • v1.4.27 开始,make自动删除不属于当前应用的快捷方式,不用再自己手动删除了,【默认启用】,使用make ENABLE_RM_DESKTOP=1启用。
  • v1.4.34 开始,支持无需ll-cli的自动化测试,从构建到测试可以完全不需要安装玲珑,使用make ENABLE_TEST_NOCLI=1选项启用。
  • v1.5.0 开始,优化了ptarce环境的性能,【默认启用】,使用make ENABLE_PTRACE=1启用。

由于需要代替ll-builder管理ostree,于是做了这个功能在makefile里,建议使用make管理项目。
你的构建脚本可以简化为:

# 提前准备sources.list,apt.conf.d/limit.conf等 # 初始化项目文件 ll-killer init # 可选:创建build.sh并赋予可执行权限,在make执行apt安装步骤【之前】自动调用 # 可选:创建post-build.sh并赋予可执行权限,在make执行apt安装步骤【之后】自动调用 # 如执行“添加程序入口版本号”,“去除QGIS的jpg文件关联”等步骤,注意这个脚本是在容器中运行的,$BUILD_DIR/diff/usr/之类的文件已经叠加到容器根目录。 # 可以运行`make build`进入当前配置(config.mk)下的构建环境,在环境中测试相关的命令,测试完可以在外面$BUILD_DIR/diff/中查看效果。 # 可选:创建deps.list文件,写入依赖包名,空格隔开或一行一个,在apt安装步骤过程中一起安装。 # 如 python3-pip python3-geopandas python3-shapely inkscape fcitx5-frontend-qt5 fcitx-frontend-qt5 saga mdbtools fonts-open-sans # 自动创建yaml并构建项目,最后输出layer文件 # ENABLE_OSTREE:启用ostree,移除ll-builder依赖。 # ENABLE_TEST_NOCLI:启用ll-cli.sh,使用killer模拟的玲珑环境进行自动化测试,移除ll-cli依赖。 make PKG=qgis ENABLE_OSTREE=1 # 执行自动化测试 make test

关于make的其他更多选项可以运行make help,如需修改参数可以make config 参数=值,或直接编辑config.mk。

关于更新killer时的github网络问题可以用这个地址解决: https://ll-killer.win/releases/latest/download/ll-killer-amd64

Reply View the author
2 / 2
To page