在Nix模块options段引用pkgs.system时出现无限递归问题
NixOS配置无限递归错误分析
最小复现代码
以下是触发无限递归错误的NixOS最小配置:
(import <nixpkgs/nixos>) { configuration = { pkgs, ... }: { options = builtins.trace "Building a system with system ${pkgs.system}" {}; }; system = "x86_64-linux"; }
错误信息
执行nix-build时会抛出无限递归错误,移除对pkgs.system的引用则可避免:
$ nix-build error: infinite recursion encountered at /Users/charles/.nix-defexpr/channels/nixpkgs/lib/modules.nix:496:28: 495| builtins.addErrorContext (context name) 496| (args.${name} or config._module.args.${name}) | ^ 497| ) (lib.functionArgs f);
原因解析
从nixos/lib/eval-config.nix的实现可以看出,system参数的默认值来自pkgs,但pkgs本身的初始化又依赖system参数。当在模块的options阶段尝试访问pkgs.system时,就会形成循环依赖:模块解析需要先获取pkgs参数,而pkgs的构建又需要已知的system值,但此时system的确定过程又被模块参数解析卡住,最终触发无限递归。这意味着在模块的options定义阶段,无法直接访问pkgs.system,必须等到评估流程的后期(比如config阶段)才能安全获取。
实际场景需求
我需要自省一个flake,通过查询someFlake.packages.${pkgs.system}来找到需要生成配置选项的包,但当前的递归问题阻碍了这个操作。
内容的提问来源于stack exchange,提问作者Charles Duffy
相关产品推荐
相关产品推荐

