How to use cargo applications in Nix builds

In my case it’s about cargo-component to create WebAssembly components, typically installed via cargo install component and then used like this

cargo component build --target wasm32-wasip2 --release

This also works via

nix-shell --pure -p rustup cargo-component
cargo-component build --target wasm32-wasip2 --release

but it will fail in Nix builds because rustup doesn’t work:

my-build.nix

let
  pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-24.11.tar.gz") { };
in
pkgs.stdenv.mkDerivation {
  name = "my-wasm-component";
  src = ./my-wasm-component;
  buildInputs = [
    pkgs.rustup
    pkgs.cargo-component
  ];
  buildPhase = ''
    cargo-component build --target wasm32-wasip2 --release
  '';
  installPhase = ''
    cp target/wasm32-wasip2/release/my-wasm-component.wasm $out
  '';
}
➜ nix-build my-build.nix
this derivation will be built:
  /nix/store/m772j16rganmnikgzr2drvrk9p7vzl7c-my-wasm-component.drv
building '/nix/store/m772j16rganmnikgzr2drvrk9p7vzl7c-my-wasm-component.drv'...
Running phase: unpackPhase
unpacking source archive /nix/store/fx6igfd7pgr0g4vjhz4p42l11i5cxqag-my-wasm-component
source root is my-wasm-component
Running phase: patchPhase
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
Error: failed to load cargo metadata

Caused by:
    `cargo metadata` exited with an error: error: could not create home directory: '/homeless-shelter/.rustup': Permission denied (os error 13)

Without rustup it will run into other erros. Is there a general way to use cargo apps in Nix builds?

export HOME=$(mktemp -d) in the Nix build might help a bit, but the main thing you should worry about is the fact you don’t have internet connection in Nix builds. I am not experienced with actual Rust development, but I had an interesting experience solving this issue:

Which was basically solved in the end with:

postUnpack = ''
  export CARGO_HOME=$PWD/.cargo
'';

While you use rustPlatform.cargoSetupHook and a cargoDeps = rustPlatform.fetchCargoTarball { ... };. With this you should be able to run any cargo install command before any other build /install phase.

Hope this helps!

1 Like

This article (Accessing Network from a Nix Derivation (via Fixed output derivations)) seems to provide another alternative to solve this class of problems.

1 Like