NixOS中nix-build构建包成功,导入configuration.nix时deno属性缺失报错
问题原因
nix-build 和 nixos-rebuild switch 使用的 pkgs 属性集存在差异,核心原因有两点:
- nixpkgs 版本不一致:
nix-build默认使用当前用户频道配置的<nixpkgs>(比如你本地通过nix-channel设置的版本),而nixos-rebuild调用的是 NixOS 系统配置中绑定的nixpkgs版本——这个版本可能和用户频道不同,甚至是经过定制的稳定分支,部分包(比如 Deno)可能未被纳入默认集合。 - 属性集实例不同:系统配置的
pkgs可能经过全局 override(比如在configuration.nix中设置了nixpkgs.config),和用户环境直接导入的pkgs并非同一个实例,即使版本相同,属性也可能有差异。
验证属性集差异的方法
1. 对比两者的 nixpkgs 版本
- 用户环境(nix-build 用的版本):
nix-build -E 'with import <nixpkgs> {}; pkgs.lib.version' - 系统环境(nixos-rebuild 用的版本):
在configuration.nix中临时添加以下配置,构建后查看输出:
执行config = { system.extraDependencies = [ (pkgs.writeText "system-nixpkgs-version" pkgs.lib.version) ]; };sudo nixos-rebuild build,然后查看生成的文件:cat /nix/store/*-system-nixpkgs-version
2. 检查 Deno 在两个属性集中的存在性
- 用户环境:
返回nix-instantiate -E "with import <nixpkgs> {}; builtins.hasAttr \"deno\" pkgs"true表示存在,false表示不存在。 - 系统环境:
修改configuration.nix加入检查:
构建后查看结果:config = { system.extraDependencies = [ (pkgs.writeText "deno-check" (builtins.toJSON { hasDeno = builtins.hasAttr "deno" pkgs; nixpkgsVersion = pkgs.lib.version; })) ]; };cat /nix/store/*-deno-check | jq
3. 直接对比属性集内容
使用 nix-diff 工具对比两个 pkgs 实例的差异:
- 导出用户环境的
pkgs:USER_PKGS=$(nix-build -E 'import <nixpkgs> {}') - 在
configuration.nix中添加导出系统pkgs的配置:config = { system.build.systemPkgs = pkgs; }; - 构建系统配置并获取系统
pkgs路径:sudo nixos-rebuild build SYSTEM_PKGS=$(readlink -f /run/current-system/systemPkgs) - 对比两者:
nix-diff $USER_PKGS $SYSTEM_PKGS
调试与解决步骤
1. 统一 nixpkgs 版本
将用户频道切换到和系统一致的版本,或者反过来。比如系统用的是 nixos-23.11,则用户执行:
nix-channel --add https://nixos.org/channels/nixos-23.11 nixpkgs nix-channel --update
2. 在 Derivation 中明确指定 nixpkgs
避免依赖外部传入的 pkgs,在你的脚本 derivation 中自行导入需要的 nixpkgs 版本:
let # 可以指定具体版本的 nixpkgs,比如 unstable pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/unstable.tar.gz") {}; in pkgs.stdenv.mkDerivation { name = "my-deno-script"; src = ./.; buildInputs = [ pkgs.deno ]; # 其他构建步骤... }
3. 在系统配置中显式引入 Deno
如果系统的 nixpkgs 版本确实不含 Deno,可从 unstable 分支导入:
let unstable = import <nixpkgs-unstable> {}; in config = { # 如果你需要在系统环境中运行 Deno environment.systemPackages = [ unstable.deno ]; # 在你的 derivation 中使用 unstable.deno 代替 pkgs.deno services.my-service.package = pkgs.callPackage ./my-package/default.nix { deno = unstable.deno; }; };
内容的提问来源于stack exchange,提问作者strickinato
相关产品推荐
相关产品推荐

