Help packaging Rover (CLI written in Rust)

I’m trying to package Rover, a CLI written in Rust. I’m fairly experienced with Nix, but not with Rust, and I’ve run into a build failure that I don’t know how to address.

My initial default.nix file:

let
  pkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/0ecf7d414811f831060cf55707c374d54fbb1dec.tar.gz";
    sha256 = "00xbm9lrivsj2w1jks2cnk5brbg5kvxjfj23kq0qyr8nvh57wln9";
  }) { };
in
  with pkgs; rustPlatform.buildRustPackage rec {
    pname = "rover";
    version = "v0.4.1";

    src = fetchFromGitHub {
      owner = "apollographql";
      repo = pname;
      rev = version;
      sha256 = "1i0l3h8ylqpzlsvk2l9krjhwvqr2d62fvx5kdxdyznm8mgp14p3g";
    };

    cargoSha256 = "1j8r5pknh5law1c1gwh5xbaqw2xjwql3sk29qdaqwaih6i18hq62";

    meta = with lib; {
      description = "A tool for working with the Apollo GraphQL Registry";
      homepage = "https://github.com/apollographql/rover";
      license = licenses.mit;
      maintainers = [ maintainers.ivanbrennan ];
    };
  }

When I run nix-build, the unpack, patch, and configure phases go smoothly, but the build phase eventually fails with:

error: failed to run custom build command for `rusty_v8 v0.22.3`

Here are the (abbreviated) logs from the build phase:

@nix { "action": "setPhase", "phase": "buildPhase" }
building
Executing cargoBuildHook
++ env CC_x86_64-unknown-linux-gnu=/nix/store/68kch2wwp5hnbfvmvzxbb33v8smw6ixk-gcc-wrapper-10.3.0/bin/cc CXX_x86_64-unknown-linux-gnu=/nix/store/68kch2wwp5hnbfvmvzxbb33v8smw6ixk-gcc-wrapper-10.3.0/bin/c++ CC_x86_64-unknown-linux-gnu=/nix/store/68kch2wwp5hnbfvmvzxbb33v8smw6ixk-gcc-wrapper-10.3.0/bin/cc CXX_x86_64-unknown-linux-gnu=/nix/store/68kch2wwp5hnbfvmvzxbb33v8smw6ixk-gcc-wrapper-10.3.0/bin/c++ cargo build -j 8 --target x86_64-unknown-linux-gnu --frozen --release
   Compiling libc v0.2.107
   Compiling autocfg v1.0.1
   ...
   Compiling ansi_colours v1.0.4
error: failed to run custom build command for `rusty_v8 v0.22.3`

Caused by:
  process didn't exit successfully: `/build/source/target/release/build/rusty_v8-1c2a1954c28f190d/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-changed=src/binding.cc
  download lockfile: "/build/source/target/x86_64-unknown-linux-gnu/release/build/lib_download.fslock"
  static lib URL: https://github.com/denoland/rusty_v8/releases/download/v0.22.3/librusty_v8_release_x86_64-unknown-linux-gnu.a
  cargo:rustc-link-search=/build/source/target/x86_64-unknown-linux-gnu/release/gn_out/obj
  Downloading https://github.com/denoland/rusty_v8/releases/download/v0.22.3/librusty_v8_release_x86_64-unknown-linux-gnu.a
  Python downloader failed, trying with curl.

  --- stderr
  thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', /build/rover-v0.4.1-vendor.tar.gz/rusty_v8/build.rs:281:10
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: build failed

The error’s immediate cause is an attempt to run curl (which I haven’t provided in the build inputs), in part of the build for rusty_v8, specifically here. This stems from an attempt to download static lib binaries rather than building V8 from source.

I found a Nix derivation for a different Rust package (Deno) that uses a RUSTY_V8_ARCHIVE environment variable to tell the rusty build script to use a Nix-provided package of the librusty_v8 library (as documented here), so I tried to do the same in my derivation, ending up with the following default.nix file:

let
  pkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/0ecf7d414811f831060cf55707c374d54fbb1dec.tar.gz";
    sha256 = "00xbm9lrivsj2w1jks2cnk5brbg5kvxjfj23kq0qyr8nvh57wln9";
  }) { };

  arch = pkgs.rust.toRustTarget pkgs.stdenv.hostPlatform;
  fetch_librusty_v8 = args: pkgs.fetchurl {
    name = "librusty_v8-${args.version}";
    url = "https://github.com/denoland/rusty_v8/releases/download/v${args.version}/librusty_v8_release_${arch}.a";
    sha256 = args.sha256;
    meta = { inherit (args) version; };
  };

  librusty_v8 = fetch_librusty_v8 {
    version = "0.22.3";
    sha256 = "07qavwvppywyn1a3v2ladj26gpwaj979xnmfkxjkisz6wi95yba5";
  };
in
  with pkgs; rustPlatform.buildRustPackage rec {
    pname = "rover";
    version = "v0.4.1";

    src = fetchFromGitHub {
      owner = "apollographql";
      repo = pname;
      rev = version;
      sha256 = "1i0l3h8ylqpzlsvk2l9krjhwvqr2d62fvx5kdxdyznm8mgp14p3g";
    };

    cargoSha256 = "1j8r5pknh5law1c1gwh5xbaqw2xjwql3sk29qdaqwaih6i18hq62";

    # The v8 package will try to download a `librusty_v8.a` release at build time to our read-only filesystem
    # To avoid this we pre-download the file and export it via RUSTY_V8_ARCHIVE
    RUSTY_V8_ARCHIVE = librusty_v8;

    meta = with lib; {
      description = "A tool for working with the Apollo GraphQL Registry";
      homepage = "https://github.com/apollographql/rover";
      license = licenses.mit;
      maintainers = [ maintainers.ivanbrennan ];
      platforms = [ "x86_64-linux" ];
    };
  }

But this didn’t make any difference (it’s still attempting to download v8).

It looks like the name of the appropriate environment variable may have changed, and was RUSTY_V8_MIRROR in rusty_v8 version 0.22.3, so I renamed my env var accordingly, but it made no difference.

Any pointers toward solving this problem (or finding a different approach)?

I got things ironed out, and put up a PR to provide this package: rover: init at 0.4.8 by ivanbrennan · Pull Request #164986 · NixOS/nixpkgs · GitHub

3 Likes