Why should I use overlay for Rust devShell?

Hi everybody,

I started learning Rust and of course, I started by writing devShell for it. I looked at github and most of Rust devShell examples I found use rust-overlay.url = "github:oxalica/rust-overlay".

I always prefer simplicity so I copy/wrote:

devShells =
...
  pkgs.mkShell
    rec {
      buildInputs = with pkgs; [
        cargo
        cargo-nextest
        cargo-watch
        clippy
        gcc
        lldb
        llvmPackages.bintools
        rust-analyzer
        rustc
        rustfmt
      ];

      shellHook =
        ''
          export CARGO_HOME="$PWD/.cargo"
          export PATH="$CARGO_HOME/bin:$PATH"
          export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${nixpkgs.lib.makeLibraryPath buildInputs}";
          mkdir -p .cargo
          echo '*' > .cargo/.gitignore
        '';
    };

But I’m not sure if I’m missing something by not using overlay. Obviously, I looked at oxalica/rust-overlay but it’s a lot of code to understand the differences. Could you please explain the differences?

Thank you.

1 Like

Fenix should probably be preferred over that project these days, oxalica/rust-overlay was just first on the scene and is therefore still in lots of abandonware.

The difference between these and just using the nixpkgs package is that the nixpkgs package is pinned to one specific version of Rust used to build the packages available in nixpkgs. These other projects allow you to use pretty much any version of Rust, and modify the toolchain with way more granularity.

This ends up being important for some Rust projects, but much less so these days - before all the async stuff stabilized there was a lot more use of nightly Rust, which necessitated using non-nixpkgs versions. IME nixpkgs’ Rust is enough for most projects nowadays.

Fenix is still useful if e.g. you have a build server where you want a really specific toolchain that is hard to express with nixpkgs, but I’d imagine the average developer (especially learning ones) won’t have to touch that.

3 Likes

Thank you very much @TLATER !

Btw. for people copying the shell above, I made a few changes and now everything works with rust-analyzer in VSCode.

  default =
    pkgs.mkShell
      rec {
        buildInputs = with pkgs; [
          cargo
          cargo-nextest
          cargo-watch
          clippy
          gcc
          lldb
          llvmPackages.bintools
          rust-analyzer
          rustc
          rustfmt
          rustup
        ];
        RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc;
        shellHook = ''
          export CARGO_HOME="$PWD/.cargo"
          export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${nixpkgs.lib.makeLibraryPath buildInputs}";
          export PATH="$CARGO_HOME/bin:$PATH"
          export RUST_SRC_PATH="${pkgs.rustPlatform.rustLibSrc}";
          export RUSTUP_HOME="$PWD/.rustup"
          export RUSTUP_TOOLCHAIN="nightly";
          mkdir -p .cargo .rustup
          echo '*' > .cargo/.gitignore
          echo '*' > .rustup/.gitignore
        '';
      };

Why do you set LD_LIBRARY_PATH then?

1 Like

I assume the ld env var is leftover from experimentation, mkShell makes that superfluous.

Honestly, you only need the rustup package with that setup, I assume vscode calls into rustup directly to set up your rust toolchain; you’re not using the nixpkgs-provided rust tooling at all with that devshell.

1 Like

That was me copying stuff from github ;-). Thx!

Right! Thank you.

I had a problem with rust-analyzer (from marketplace, not from nixpkgs) in VSCodium (from nixpkgs). When I started VSCodium I got message 2024-12-07T07:08:04.310690402Z ERROR can't load standard library, try installing rust-src sysroot_path=/nix/store/wi84ms5hw85w3frljv2spmdl8768dw97-rustc-1.82.0. I thought rustup fixed it by after simplifying the devShell:

  default =
    pkgs.mkShell
      rec {
        buildInputs = with pkgs; [
        cargo
        cargo-nextest
        cargo-watch
        clippy
        gcc
        lldb
        llvmPackages.bintools
        rust-analyzer
        rustc
        rustfmt
        # rustup
        ];
        RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc; # FIX!!!
        shellHook = ''
          export CARGO_HOME="$PWD/.cargo"
          export PATH="$CARGO_HOME/bin:$PATH"
        '';
    };

I noticed that RUST_SRC_PATH was what was needed.

1 Like