ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

nixpkgs 中 Lean 4 的构建体系:buildLakePackage、leanPackages 作用域与 Lake 集成实践

nixpkgs 中 Lean 4 的构建体系:buildLakePackage、leanPackages 作用域与 Lake 集成实践 nixpkgs 中 Lean 4 的构建体系buildLakePackage、leanPackages 作用域与 Lake 集成实践【免费下载链接】nixpkgsNix Packages collection NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs本文基于 nixpkgs 手册的 Lean 4 章节系统讲解 nixpkgs 对 Lean 4 语言生态的支持如何用leanPackages.buildLakePackage以无网络hermetic方式构建依赖 mathlib 的 Lean 项目lakeHash参数如何支持 Nix 与 Lake 两种依赖解析的混合迁移以及leanPackages作用域的工具链替换、LSP 二进制补丁机制和开发 shell 的使用方式。读完本文你可以为 Lean 4 项目写出可复制的 Nix 构建表达式并理解其与 2020–2025 年旧版 per-module 集成架构的本质区别。概览nixpkgs 中的两套 Lean 4 入口nixpkgs 为 Lean 4 提供两个互补的入口leanPackages一个独立的包集合scope内置自己的 Lean toolchain并附带一组精选库——包括完整的 mathlib 依赖树pkgs.lean4一个独立的 Lean 4 编译器 derivation供在leanPackages包集合之外单独使用例如通过overrideScope注入自定义工具链。这两者组合后Lean 4 在 nixpkgs 中的定位与 Haskell 生态中haskellPackagesghc的组合类似作用域内所有库共享同一 toolchain构建时复用已编译产物保证 hermetic。用buildLakePackage构建 Lean 4 项目构建 Lean 4 项目的标准入口是leanPackages.buildLakePackage。手册给出的最小可用表达式如下leanPackages.buildLakePackage { pname my-project; version 0.1.0; src ./.; leanDeps with leanPackages; [ mathlib ]; lakeHash null; # all deps nix-managed; set to lib.fakeHash for Lake-managed deps }各参数的含义参数说明pname/version项目的名称与版本号用于生成 store 路径src项目源码目录此处./.指向包含 lakefile 的项目根leanDepsNix 管理的依赖列表。用with leanPackages; [ mathlib ]的写法即从leanPackages作用域引入 mathlib及其整个依赖树由作用域内部保证lakeHash控制 Lake 侧 fixed-output 拉取的行为三种取值见下节Hermetic 构建的实现机制buildLakePackage的依赖来源分两处声明依赖写在lakefile供 Lake 识别和Nix 表达式供 Nix 识别。其 hermetic 性来自一条明确的优先级规则依赖的.olean文件是 Lake library facet 的默认构建产物。leanDeps提供的 Nix 管理库直接复用这些.olean文件、不再重新编译buildLakePackage通过lake --packages把它们注入构建该标志优先于 Lake 自身的依赖解析从而产生 hermetic 构建。从源码结构看这意味着 lakefile 中为这些库声明的 fetch 配置在构建时不会触发网络访问——Lake 的包解析结果被 Nix 提供的.olean产物透明替换。lakeHash异构依赖解析与渐进式迁移buildLakePackage在 nixpkgs 所有 builder 中属于独树一帜的设计它支持异构依赖解析heterogeneous dependency resolution即 Nix 与 Lake 的依赖管理可以在同一个 derivation 内按包粒度组合leanDepsNix 管理的依赖lakeHashLake 管理的依赖走 fixed-output derivation 固定下来。lakeHash的三种取值语义lakeHash null默认值声明所有依赖都是 Nix 管理的构建时不执行任何 fixed-output 拉取。这是完全 nix 化后的终态lakeHash lib.fakeHash这是一个探测模式。构建会失败并报出 expected hash——该哈希对应的 fixed-output derivation 精确钉住了Lake 原本会拉取的全部依赖、减去 Nix 已管理的部分。把报告出的哈希回填到lakeHash即可固定 Lake 侧依赖具体的 hash 字符串正式钉住 Lake 管理的依赖集合。由此得到一条明确的渐进式采用路径on-rampNix 管理依赖按名称优先name precedence。因此把某个依赖从lakeHash固定集合移入leanDeps会改变 expected hash——这正是探测模式的自校验机制一个大型 Lean 项目可以先把不常变动的上游依赖用lakeHash钉住、把核心库如 mathlib迁入leanDeps然后逐个库迁移每次迁移后重新运行lib.fakeHash探测并更新哈希直到lakeHash null的完全 Nix 管理状态。项目根必须存在lake-manifest.json无论依赖走哪条解析路径项目根都必须存在lake-manifest.json。当所有依赖均为 Nix 管理时一个空清单即可满足 Lake{version:1.1.0,packagesDir:.lake/packages,packages:[]}这对应 Lake 1.1.0 版本的清单格式packages数组为空即表示没有任何 Lake 侧固定依赖。开发 shellnix develop下的工具链在nix develop中作用域化的lean4与buildLakePackage与 hermetic 构建使用同一套 toolchain保证开发时验证的构建与CI 中执行的构建一致。需要注意一个行为差异开发 shell 中 Lake 的正常依赖解析是可用的——Lake 可能从网络拉取未被leanDeps覆盖的依赖。这与 Nix 开发 shell 的常规行为一致shell 不承诺 hermetic因此本地开发体验与 vanilla Lake 项目基本对等nix develop/nix-shell在功能上对齐原生 Lake 开发流程。leanPackages作用域lib.makeScope与工具链替换leanPackages实现为lib.makeScope作用域内自带一个lean4属性。这意味着替换作用域的lean4会传播到作用域内所有包以及buildLakePackage——与haskellPackages替换ghc的语义相同。标准写法leanPackages.overrideScope ( self: super: { lean4 myCustomLean4; } )myCustomLean4可以直接使用顶层的pkgs.lean4独立编译器入口或任何等价 derivation。LSP 可用的关键leanPackages.lean4的二进制补丁leanPackages提供的lean4是经过二进制补丁binary-patched的版本目的是确保 Lean language server 能发现被包装的lake而非未包装的版本。其根源是 Lake 的serve子命令有一个棘手的调用模式serve从IO.appPathRust 运行时提供的可执行文件真实路径推导出LAKE路径然后在派生出的环境spawned environment中无条件设置LAKE环境变量这一机制绕过任何 wrapper——即使你在PATH里放了包装版lakelanguage server 启动的子进程拿到的仍是 store 中未包装路径。补丁的做法是改写二进制中的 store 路径引用使IO.appPath发现机制直接命中包装后的lake。其收益是完整的 LSP 集成——包括InfoView依赖 Lean 专属协议扩展且不需要污染用户的项目目录比如写一个假lake脚本进项目。缓存失效语义让位于 Nix 的依赖模型文档明确了一个重要的语义替换leanPackages.lean4取代了 Lake 对位于/nix/store/中依赖的内置缓存失效cache invalidation逻辑完全交由 Nix 的依赖模型处理。Lake 的trace 校验检查编译器 hash、平台和包身份被 Nix 已有的保证优雅地吸收subsumed。用更直白的话说Lake 本会自己校验上次编译依赖的编译器版本、目标平台、包身份是否变化来决定是否复用缓存而在 Nix 下.olean产物本身就在 store 里按内容哈希寻址compiler/platform/依赖任一变化都会改变产物路径因此这类一致性检查无需重复执行。缓存一致性责任委托给整合了流畅 Nix 集成的编排者——即 Nix 求值与构建系统本身。这也是前文leanDeps的.olean直接复用、不重编译能成立的底层原因。编辑器支持Lean 4 的编辑器集成包从PATH中发现工具链因此只要nix develop中leanPackages提供的lean4/lake在PATH里即可工作EmacsemacsPackages.nael与emacsPackages.nael-lsp前者基于 eglot后者基于 lsp-mode均可经 MELPA 安装提供 Lean 4 支持包括通过 eldoc 显示证明状态proof stateVSCodeunfree/ VSCodiumvscode-extensions.leanprover.lean4。与早期 Lean 4 Nix 集成的关系2020–2025 旧架构熟悉旧版集成的读者应注意buildLakePackage遵循完全不同的架构。旧架构2020–2025per-module derivation在求值期通过 import-from-derivationIFD发现依赖——那是一次调和声明式包管理与细粒度构建语义的大胆尝试但最终被 Nix 自身的求值模型所掣肘Lean 上游已将其移除见 Lean 上游提交 535435955b482176e8d62a54deebcacdec0827db新架构buildLakePackage把Lake 当作构建驱动build driverNix 只负责**包级package-level**边界。IFD 的求值期依赖发现被消除依赖发现发生在构建期lake --packages注入求值保持廉价且可缓存nix develop/nix-shell则负责与原生 Lake 开发体验的功能对等。小结与要点核对场景用法构建依赖 mathlib 的项目leanPackages.buildLakePackageleanDeps with leanPackages; [ mathlib ]全部 Nix 管理lakeHash null默认项目根放空lake-manifest.json部分 Lake 管理lakeHash lib.fakeHash探测 → 回填真实 hash → 逐步把库迁入leanDeps自定义 toolchainleanPackages.overrideScope (self: super: { lean4 myCustomLean4; })传播到所有包与buildLakePackage本地开发nix develop注意 shell 中 Lake 仍可能走网络解析编辑器Emacsnael/nael-lspVSCode/VSCodiumleanprover.lean4均从PATH发现工具链以上内容的依据是手册章节 doc/languages-frameworks/lean4.section.md属于 doc/languages-frameworks/index.md 的语言和框架一章。适用前提文中所有leanPackages、buildLakePackage、lakeHash行为均以该文档描述为准且lake-manifest.json的格式示例对应 Lake 1.1.0 清单版本若使用其他 Lake 版本需确认其清单格式兼容性。【免费下载链接】nixpkgsNix Packages collection NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表