Nixpkgs 中的 Scheme 包管理:Akku 集成与 akkuPackages 使用指南
2026/9/18 12:34:29 网站建设 项目流程

Nixpkgs 中的 Scheme 包管理:Akku 集成与 akkuPackages 使用指南

【免费下载链接】nixpkgsNix Packages collection & NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs

本篇技术指南聚焦 Nixpkgs 中 Scheme 生态的包管理方案——基于 Akku(Akku.scm)语言包管理器构建的akkuPackages属性集。读者将掌握如何在 Nix 派生(derivation)与nix-shell中使用约两百个 R6RS/R7RS 库,理解包索引deps.toml的生成与更新机制,并从源码层面看懂 Nixpkgs 如何将 Akku 包体系接入标准构建流程。

Akku 与 Nixpkgs 的集成概览

Akku 是面向 Scheme 语言的语言级包管理器,其官方仓库同时镜像了 snow-fort(snow-fort.org/pkg)的包源。Nixpkgs 将 Akku 的包索引整体收入仓库,提供两层产物:

  • akku:Akku 可执行程序本身,位于顶层属性集,可直接安装使用(见 all-packages.nix 中inherit (recurseIntoAttrs (callPackage ../tools/package-management/akku { })) akku akkuPackages);
  • akkuPackages:由约两百个 R6RS 与 R7RS 库组成的包集合,每个包都是一个标准的 Nix 派生,可被放入其他派生(derivation)的buildInputs,也能够在nix-shell中正常工作。

这些包在构建期使用Chez SchemeChibi Scheme执行测试,从而保证进入 Nixpkgs 的包不仅可安装,还通过了上游自带测试用例的验证。

将 Akku 包用作构建输入

在 Nix 中引入一个 Akku 包的方式与引入任何常规 Nix 包完全一致——写入buildInputs。原文档给出的示例是为一组主要面向 Chez Scheme 的 SRFI 库(akkuPackages.chez-srfi)准备的:

{ buildInputs = [ chez akkuPackages.chez-srfi ]; }

这里chez提供 Chez Scheme 解释器,akkuPackages.chez-srfi提供 SRFI 库本体。两者同时出现在buildInputs中即可让派生在构建、测试与安装阶段找到对应的库路径。

为什么 nix-shell 中也能直接使用

Nixpkgs 为 Akku 包配备了一个 setup-hook.sh,这是其“放进buildInputs即生效”的关键。该钩子遍历一份覆盖主流 Scheme 实现的库搜索环境变量列表:

CHEZSCHEMELIBDIRS GUILE_LOAD_PATH IKARUS_LIBRARY_PATH MOSH_LOADPATH PLTCOLLECTS SAGITTARIUS_LOADPATH VICARE_SOURCE_PATH YPSILON_SITELIB LARCENY_LIBPATH IRONSCHEME_LIBRARY_PATH LOKO_LIBRARY_PATH DIGAMMA_SITELIB CHIBI_MODULE_PATH GAUCHE_LOAD_PATH

对每个变量,钩子都会通过addToSearchPath把包的lib/scheme-libs目录追加进去;同时对 Guile 还会追加lib/libobj(编译产物)到GUILE_LOAD_COMPILED_PATH,对 FFI 目录分别追加LD_LIBRARY_PATHDYLD_LIBRARY_PATH。从源码结构看,这意味着同一份包输出可以同时服务于 Chez、Guile、Chibi、Racket(PLTCOLLECTS)、Gauche 等多个实现——无论用户把包放进buildInputs还是通过nix-shell引入,对应解释器都能自动解析到这些库。

akkuPackages 的构建机制

akkuPackages并非手工编写的包列表,而是由一个统一的构建函数批量生成。其定义位于 default.nix:

  • 使用lib.makeScope newScope建立独立作用域,作用域内包含akku(可执行程序)、akkuDerivation(通用构建函数)与akkuPackages
  • deps = lib.importTOML ./deps.toml将包索引文件直接导入为 Nix 数据结构;
  • lib.mapAttrs (makeAkkuPackage akkuself) deps为索引中的每个条目调用makeAkkuPackage,生成对应的 Nix 派生;
  • 最后通过lib.recurseIntoAttrs packages让整个集合在 Hydra 等批量求值场景中可被递归遍历。

通用构建函数 akkuDerivation

akkuDerivation.nix 是每个 Akku 包派生背后的通用模板,其核心逻辑如下:

构建阶段(buildPhase):先删除上游的Akku.lockAkku.manifest,再执行akku install拉取并安装依赖;随后用 Guile 运行仓库自带的 parse-akku.scm(merge模式)扫描CHEZSCHEMELIBDIRS下所有metadata.sls,把当前包的名称、版本与已安装库清单合并写回.akku/lib/akku/metadata.sls,确保测试与后续使用阶段元数据完备。

测试阶段(checkPhase)doCheck = true默认开启测试。构建时分别导出CHEZSCHEMELIBDIRSCHIBI_MODULE_PATH指向.akku/lib,随后遍历两类测试文件:

  • 所有test*目录下的.sps文件;
  • 所有匹配run-test.scm文件。

执行方式按包类型区分:可执行文件直接运行;r7rs = true的包用chibi-scheme运行;其余用scheme-script(Chez)运行。这正是原文档所述“使用 Chez 与 Chibi Scheme 在构建期测试”的具体实现。若测试文件被列入SKIP环境变量则跳过(如chez-srfi在 overrides.nix 中列出了若干已知失败的测试文件)。

安装阶段(installPhase):将.akku/lib复制为$out/lib/scheme-libs.akku/bin复制为$out/bin;若存在ffilibobj目录则一并复制;最后用patchShebangs修正脚本解释器,并用wrapProgram为每个可执行程序注入CHEZSCHEMELIBDIRS前缀,保证脱离构建环境后依然能找到库。

包的属性来源:deps.toml 与 overrides.nix

每个包派生所需的versionurlsha256dependenciesdev-dependencieslicensesourcesynopsis等属性全部来自 deps.toml(当前索引含三千余行条目)。例如:

[arvyy-mustache] dependencies = ["akku-r7rs", "chez-srfi"] dev-dependencies = [] license = "mit" url = "http://snow-fort.org/s/gmail.com/nma.arvydas.silanskas/arvyy/mustache/1.0.2/arvyy-mustache-1.0.2.tgz" sha256 = "ea8085f6313851249dc41e86a5c455225f73f351046994296fe7fc6144f05d16" source = "snow-fort" synopsis = "Mustache templating 1.2.1 implementation" version = "1.0.2"

makeAkkuPackage会据此构造派生:

  • src = fetchurl { inherit url sha256; }unpackPhase = "tar xf $src"
  • buildInputsdependencies映射到作用域内的其他 Akku 包(map (x: akkuself.${x}) dependencies);
  • dev-dependencies进入nativeBuildInputs
  • r7rs = source == "snow-fort":来自 snow-fort 的包按 R7RS 处理,来自 Akku 官方归档的按 R6RS 处理;
  • license字符串经stringToLicense映射表(覆盖 bsd0、agpl、asl20、gpl 系列、lgpl 系列、cc0、publicDomain、srfi 等 30 余种 SPDX 标识)转换为 Nix 的 license 对象,支持列表形式的多许可。

随后通过overrideAttrs应用 overrides.nix 中按包名定制的修补:例如chez-srfi跳过特定测试、scheme-langserver在安装阶段补写 LSP 可执行入口、xyz-modemcommand -v替换which并补充lrzsz检查依赖、大量已知失效的包(如chibi-sslsrfi-64tex-parser等)被标记为brokenufo-thread-pool在 Darwin 上标记 broken、wak-htmlprag在 aarch64 上标记 broken 等。这些覆盖是包集合“开箱即用”的质量保障层。

更新包索引:deps.toml 的刷新流程

Akku 包索引不会自动保持最新,需要周期性刷新。原文档说明索引位于pkgs/tools/package-management/akku目录下,文件名为deps.toml,更新方式是在该目录内执行./update.sh

从源码看,update.sh 的完整逻辑是一条命令:

curl -sSf https://archive.akkuscm.org/archive/Akku-index.scm | guile parse-akku.scm deps > deps.toml

即:从 Akku 官方归档服务器拉取最新的Akku-index.scm包索引,交给 Guile 执行 parse-akku.scm(deps模式)解析,重新生成deps.toml。该脚本以nix-shellshebang 方式声明运行环境(nix-shell -I nixpkgs=../../../../ -i bash -p guile curl),直接指向仓库自身的 nixpkgs 提供guilecurl

parse-akku.scm 的解析逻辑

parse-akku.scm承担两个职责(通过命令行首个参数区分模式):

  • deps模式:逐条读取Akku-index.scm中的包记录,对每个包取versions列表中的最新版本,抽取licenseurlsha256depends(依赖)、depends/dev(开发依赖)、synopsisversion等字段,并按 URL 前缀判定source归属:以https://archive.akkuscm.org/开头记为akku,以http://snow-fort.org/开头记为snow-fort,否则记为UNKNOWN,最终输出为 TOML 格式写入deps.toml
  • merge模式:如前所述,在构建阶段合并多个包的installed-librariesinstalled-assets元数据,生成去重后的metadata.sls

刷新索引后,新包与新版本会出现在akkuPackages中,但需要留意:新包若存在构建或测试问题,通常需要在overrides.nix中登记相应的跳过测试、补丁或broken标记,这正是 Nixpkgs 维护者处理上游包质量差异的常规流程。

限制与注意事项

  • 包数量与覆盖范围akkuPackages覆盖 Akku/snow-fort 索引中约两百个包,并非全部可用——大量包在 overrides.nix 中被显式标记broken(例如chibi-sslchibi-mecabr6rs-closswish等),原因是测试失败、依赖缺失或不受支持的 Scheme 实现;
  • 运行时依赖akku程序本身在 akku.nix 中通过 Guile 3.0.10 构建(源码注释说明 Akku 目前自 Guile 3.0.11 起会构建失败,因此临时固定版本),并依赖curlgit作为运行时工具;
  • 版本语义akkuPackages中包名带akku-前缀(如akku-chez-srfipname实际为akku-chez-srfi),但用户访问时使用不带前缀的akkuPackages.chez-srfi形式,与构建产物名存在差异;
  • 更新节奏deps.toml需人工周期刷新,包版本并非实时镜像上游。

延伸阅读

  • Scheme 语言框架文档:doc/languages-frameworks/scheme.section.md(本文依据)
  • Akku 包集与构建函数定义:pkgs/tools/package-management/akku/default.nix
  • 通用派生模板:pkgs/tools/package-management/akku/akkuDerivation.nix
  • 包索引数据:pkgs/tools/package-management/akku/deps.toml
  • 包级修补与 broken 标记:pkgs/tools/package-management/akku/overrides.nix
  • 索引解析脚本:pkgs/tools/package-management/akku/parse-akku.scm
  • 更新脚本:pkgs/tools/package-management/akku/update.sh
  • 环境变量注入钩子:pkgs/tools/package-management/akku/setup-hook.sh
  • Akku 本体打包:pkgs/tools/package-management/akku/akku.nix

【免费下载链接】nixpkgsNix Packages collection & NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询