You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Nix构建含Rust/Python的Calyx依赖库遇nix-shell错误求助

问题背景

目标

尝试编写Nix derivation构建Calyx(同时运行所有测试验证构建/安装结果)。Calyx包含多个相互依赖的Rust和Python模块,各模块的构建测试需依赖其他模块构建完成。Python模块运行似乎需要源代码支持。

实现方案

  • 使用rustPlatform.buildRustPackage构建Rust子目录calyx,关闭测试检查
  • 使用pkgs.buildPythonPackage构建Python子目录calyx-py,关闭测试检查
  • 使用pkgs.buildPythonPackage构建Python子目录fud,关闭测试检查
  • 使用symlinkJoin将src(fud运行所需)与上述包链接在一起
    • 在fixup阶段执行fud的配置步骤
    • 在installCheck阶段用单独构建的runt运行calyx和fud的检查

完整Nix表达式

{
  # source code repo
  src,
  # nix stdlib
  lib,
  rustPlatform,
  # dependencies
  python3,
  python3Packages,
  runt,
  calyx,
  jq,
  z3,
  cvc5,
  whichSmt ? "z3",
}:

let
  srcTomlMeta = (builtins.fromTOML (builtins.readFile "${src}/Cargo.toml")).workspace.package;
  smt =
    if (whichSmt == "z3") then
      z3
    else if (whichSmt == "cvc5") then
      cvc5
    else
      throw "invalid value for `whichSmt`; must be either \"z3\" or \"cvc5\"";
in
rustPlatform.buildRustPackage {
  pname = "filament";
  version = srcTomlMeta.version;

  inherit src;
  cargoPatches = [ ./add-Cargo.lock.patch ];
  cargoHash = "sha256-VMsjEP4/ivVe2UrXuZvMuiEhIr8RruHOX/e2kL0CJgU=";

  nativeBuildInputs = [
    python3
    python3Packages.numpy
    runt
    calyx
    jq
    smt
  ];

  patches = [ ./runt.toml.patch ];
  doCheck = false;
  doInstallCheck = true;
  installCheckPhase = ''
    ln -s $out ./result
    runt -d
    rm ./result
  '';

  meta = {
    inherit (srcTomlMeta) description homepage;
    license = lib.licenses.mit;
    platforms = lib.platforms.all;
  };
}

成功构建命令

nix-build -E 'let pkgs = import <nixpkgs> {}; in pkgs.callPackage ./calyx/package.nix {runt = pkgs.callPackage ./runt/package.nix {}; }'

遇到的问题

运行以下命令创建加载Calyx的nix-shell时报错:

nix-shell -E 'let pkgs = (import <nixpkgs> {}); in pkgs.mkShell { buildInputs = [pkgs.callPackage ./calyx/package.nix {runt = pkgs.callPackage ./runt/package.nix {}; } ]; }' --show-trace

错误信息:

error: Dependency is not of a valid type: element 1 of buildInputs for nix-shell

完整错误追踪:

error:
       … while calling the 'derivationStrict' builtin
         at <nix/derivation-internal.nix>:9:12:
            8|
            9|   strict = derivationStrict drvAttrs;
             |            ^
           10|

       … while evaluating derivation 'nix-shell'
         whose name attribute is located at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:336:7

       … while evaluating attribute '__impureHostDeps' of derivation 'nix-shell'
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:451:7:
          450|       __propagatedSandboxProfile = unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
          451|       __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [
             |       ^
          452|         "/dev/zero"

       … while calling the 'foldl'' builtin
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:435:11:
          434|         computedImpureHostDeps =
          435|           unique (concatMap (input: input.__propagatedImpureHostDeps or [])
             |           ^
          436|             (stdenv.extraNativeBuildInputs

       … while calling the 'concatMap' builtin
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:435:19:
          434|         computedImpureHostDeps =
          435|           unique (concatMap (input: input.__propagatedImpureHostDeps or [])
             |                   ^
          436|             (stdenv.extraNativeBuildInputs

       … while calling anonymous lambda
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:435:30:
          434|         computedImpureHostDeps =
          435|           unique (concatMap (input: input.__propagatedImpureHostDeps or [])
             |                              ^
          436|             (stdenv.extraNativeBuildInputs

       … from call site
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:435:37:
          434|         computedImpureHostDeps =
          435|           unique (concatMap (input: input.__propagatedImpureHostDeps or [])
             |                                     ^
          436|             (stdenv.extraNativeBuildInputs

       … while calling anonymous lambda
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:312:13:
          311|       (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
          312|       (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs'))
             |             ^
          313|     ]

       … from call site
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:312:18:
          311|       (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
          312|       (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs'))
             |                  ^
          313|     ]

       … while calling 'getOutput'
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/lib/attrsets.nix:1797:23:
         1796|   */
         1797|   getOutput = output: pkg:
             |                       ^
         1798|     if ! pkg ? outputSpecified || ! pkg.outputSpecified

       … while evaluating a branch condition
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/lib/attrsets.nix:1798:5:
         1797|   getOutput = output: pkg:
         1798|     if ! pkg ? outputSpecified || ! pkg.outputSpecified
             |     ^
         1799|       then pkg.${output} or pkg.out or pkg

       … in the left operand of the OR (||) operator
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/lib/attrsets.nix:1798:32:
         1797|   getOutput = output: pkg:
         1798|     if ! pkg ? outputSpecified || ! pkg.outputSpecified
             |                                ^
         1799|       then pkg.${output} or pkg.out or pkg

       … in the argument of the not operator
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/lib/attrsets.nix:1798:10:
         1797|   getOutput = output: pkg:
         1798|     if ! pkg ? outputSpecified || ! pkg.outputSpecified
             |          ^
         1799|       then pkg.${output} or pkg.out or pkg

       … from call site
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:312:25:
          311|       (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
          312|       (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs'))
             |                         ^
          313|     ]

       … while calling anonymous lambda
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/lib/lists.nix:334:29:
          333|   */
          334|   imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
             |                             ^
          335|

       … from call site
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/lib/lists.nix:334:32:
          333|   */
          334|   imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
             |                                ^
          335|

       … while calling anonymous lambda
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:281:15:
          280|     imap1
          281|       (index: dep:
             |               ^
          282|         if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep

       … while calling the 'throw' builtin
         at /nix/store/lbmzs66dzl6vp7klrplq0c607s7majp9-source/pkgs/stdenv/generic/make-derivation.nix:284:14:
          283|         else if isList dep then checkDependencyList' ([index] ++ positions) name dep
          284|         else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}"
             |              ^
          285|       deps;

       error: Dependency is not of a valid type: element 1 of buildInputs for nix-shell

疑问

  1. 该错误的含义是什么?
  2. 操作哪里有误?如何用Nix正确构建这个包?

解答

1. 错误含义解析

这个错误表示你传递给buildInputs的某个元素不是Nix认可的有效依赖类型。Nix接受的有效依赖类型包括:

  • Derivation(Nix构建输出的标准包)
  • null
  • 字符串(通常是本地路径或环境变量配置)
  • 本地文件路径

你的情况是buildInputs中的元素不符合上述类型,导致Nix无法完成依赖解析。

2. 问题根源与修复方案

问题根源

你的Nix表达式存在循环依赖:在构建filament包时,nativeBuildInputs中声明了calyx参数,但调用callPackage时又将这个包本身作为calyx参数传入,导致生成了一个递归的无效结构,而非正常的derivation,最终被mkShell检测为无效依赖。

另外,你的实现思路和实际代码不匹配:你描述要构建calyx、calyx-py、fud三个模块后链接,但实际代码只构建了filament,且错误地将自身作为依赖传入。

修复步骤

步骤1:拆分各模块的独立构建

分别为三个核心模块编写单独的derivation:

1.1 Calyx Rust模块(calyx/default.nix)
{ lib, rustPlatform, src }:
rustPlatform.buildRustPackage {
  pname = "calyx";
  version = (builtins.fromTOML (builtins.readFile "${src}/Cargo.toml")).workspace.package.version;
  src = "${src}/calyx";
  cargoLock.lockFile = "${src}/calyx/Cargo.lock";
  cargoHash = "sha256-..."; # 替换为实际的cargo hash
  doCheck = false; # 后续测试通过后可开启
}
1.2 Calyx Python模块(calyx-py/default.nix)
{ lib, buildPythonPackage, src, calyx }:
buildPythonPackage {
  pname = "calyx-py";
  version = (builtins.fromTOML (builtins.readFile "${src}/Cargo.toml")).workspace.package.version;
  src = "${src}/calyx-py";
  propagatedBuildInputs = [ calyx ];
  doCheck = false;
}
1.3 Fud工具(fud/default.nix)
{ lib, buildPythonPackage, src, calyx, calyx-py, python3Packages, jq, z3 }:
buildPythonPackage {
  pname = "fud";
  version = (builtins.fromTOML (builtins.readFile "${src}/Cargo.toml")).workspace.package.version;
  src = "${src}/fud";
  propagatedBuildInputs = [
    calyx
    calyx-py
    python3Packages.click
    python3Packages.requests
    python3Packages.numpy
    jq
    z3
  ];
  doCheck = false;
  postInstall = ''
    # 初始化fud配置
    fud config global.cache-directory "$out/.fud-cache"
  '';
}

步骤2:编写整合包

创建整合包,将三个模块和源码链接(解决fud需要源码的问题):

{ lib, symlinkJoin, calyx, calyx-py, fud, src }:
symlinkJoin {
  name = "calyx-full-${calyx.version}";
  paths = [ calyx calyx-py fud src ];
  postBuild = ''
    # 让fud能找到源码中的配置文件
    ln -s $src/fud/config $out/share/fud-config
    fud config global.config-dir "$out/share/fud-config"
  '';
}

步骤3:顶层调用文件(default.nix)

{ pkgs ? import <nixpkgs> {} }:
let
  src = pkgs.fetchFromGitHub {
    owner = "calyxir";
    repo = "calyx";
    rev = "..."; # 替换为你使用的版本号
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:07:05