Nix-shell, rustBuildPackage, and cargo install

Hey all,

Just getting started with Nix the past few weeks and I’m running into an uncertainty in how specifically tools like cargo install are meant to play with Nix.

Currently, I have a shell.nix that is very simple:

{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-23.11.tar.gz") {}}:

let
  fenix = import (fetchTarball "https://github.com/nix-community/fenix/archive/main.tar.gz") {};
in
pkgs.mkShell {
  packages = [
    fenix.stable.toolchain
    pkgs.openssl
  ];
}

Firing this up with nix-shell, I have access to cargo build and all of the other goodies that I’d expect. I can build my application and everything works.

This application uses cargo-aoc, which is normally installed via cargo install. I can install the package in this way, and everything “works”, but it doesn’t sit well with me that this installation is performed into my home directory and using my system paths rather than being something that is included along with the Nix shell environment.

I’ve attempted building the package directly and including it as a package dependency like so:

{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-23.11.tar.gz") {}}:

let
  fenix = import (fetchTarball "https://github.com/nix-community/fenix/archive/main.tar.gz") {};
  aoc = pkgs.rustPlatform.buildRustPackage rec {
    pname = "cargo-aoc";
    version = "0.3.5";

    src = pkgs.fetchFromGitHub {
      owner = "gobanos";
      repo = pname;
      rev = version;
      hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
    };
    cargoHash = "sha256-gsE9qHigEm5R1+lJU9uazWJ/8yZZjE0eVJDtZlX0SmM=";
    doCheck = false;
  };
in
pkgs.mkShell {
  packages = [
    fenix.stable.toolchain
    pkgs.openssl
    aoc
  ];
}

This builds and runs without issue, but the cargo-aoc binary is not available in the environment.

I feel like I’m probably missing something obvious. Any ideas?

That’s nearly identical to how I packaged it last year so you’re most likely in the right ballpark! I’m out of pocket for a bit but I may take a look at your code later to see if I spot anything.

1 Like

Youre example contains the hashes of ripgrep.

1 Like

Yep, this was it. Must’ve copied it from somewhere. Do you know how this would’ve built even with the wrong hash/GitHub combination in there?

The working version in case someone searches for this in the future somehow!

{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-23.11.tar.gz") {}}:

let
  fenix = import (fetchTarball "https://github.com/nix-community/fenix/archive/main.tar.gz") {};
  aoc = pkgs.rustPlatform.buildRustPackage rec {
    pname = "cargo-aoc";
    version = "0.3.5";

    buildInputs = with pkgs; [ openssl ];

    nativeBuildInputs = with pkgs; [ pkg-config ];

    src = pkgs.fetchFromGitHub {
      owner = "gobanos";
      repo = pname;
      rev = version;
      hash = "sha256-tHuT/dsiyliXdl34bFraYp3T3FUgxFnhEUQfc8O197I=";
    };

    cargoHash = "sha256-lUQwwGJLHLI9bfJiLUUE8j1svBAgbvr+8hKB/bRzwNA=";
  };
in
pkgs.mkShell {
  packages = [
    fenix.stable.toolchain
    aoc
  ];
}

The FOD is never invalidated. Maybe checking if the Cargo.toml matches pname could be done but I am not sure if that in practice is always true.

I see. Thanks for the explanation!