Home Explore Blog Models CI



nixpkgs

9th chunk of `doc/languages-frameworks/rust.section.md`
03f35fd44a5bd4ef386fc4cf86428d6e4f1c769bb606b8390000000100000ff1
patches the derivation:

```nix
with import <nixpkgs> { };
((import ./hello.nix).hello { }).override {
  crateOverrides = defaultCrateOverrides // {
    hello =
      attrs:
      lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0") {
        postPatch = ''
          substituteInPlace lib/zoneinfo.rs \
            --replace-fail "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo"
        '';
      };
  };
}
```

Another situation is when we want to override a nested
dependency. This actually works in the exact same way, since the
`crateOverrides` parameter is forwarded to the crate's
dependencies. For instance, to override the build inputs for crate
`libc` in the example above, where `libc` is a dependency of the main
crate, we could do:

```nix
with import <nixpkgs> { };
((import hello.nix).hello { }).override {
  crateOverrides = defaultCrateOverrides // {
    libc = attrs: { buildInputs = [ ]; };
  };
}
```

### Options and phases configuration {#options-and-phases-configuration}

Actually, the overrides introduced in the previous section are more
general. A number of other parameters can be overridden:

- The version of `rustc` used to compile the crate:

  ```nix
  (hello { }).override { rust = pkgs.rust; }
  ```

- Whether to build in release mode or debug mode (release mode by
  default):

  ```nix
  (hello { }).override { release = false; }
  ```

- Whether to print the commands sent to `rustc` when building
  (equivalent to `--verbose` in cargo:

  ```nix
  (hello { }).override { verbose = false; }
  ```

- Extra arguments to be passed to `rustc`:

  ```nix
  (hello { }).override { extraRustcOpts = "-Z debuginfo=2"; }
  ```

- Phases, just like in any other derivation, can be specified using
  the following attributes: `preUnpack`, `postUnpack`, `prePatch`,
  `patches`, `postPatch`, `preConfigure` (in the case of a Rust crate,
  this is run before calling the "build" script), `postConfigure`
  (after the "build" script),`preBuild`, `postBuild`, `preInstall` and
  `postInstall`. As an example, here is how to create a new module
  before running the build script:

  ```nix
  (hello { }).override {
    preConfigure = ''
      echo "pub const PATH=\"${hi.out}\";" >> src/path.rs"
    '';
  }
  ```

### Setting Up `nix-shell` {#setting-up-nix-shell}

Oftentimes you want to develop code from within `nix-shell`. Unfortunately
`buildRustCrate` does not support common `nix-shell` operations directly
(see [this issue](https://github.com/NixOS/nixpkgs/issues/37945))
so we will use `stdenv.mkDerivation` instead.

Using the example `hello` project above, we want to do the following:

- Have access to `cargo` and `rustc`
- Have the `openssl` library available to a crate through it's _normal_
  compilation mechanism (`pkg-config`).

A typical `shell.nix` might look like:

```nix
with import <nixpkgs> { };

stdenv.mkDerivation {
  name = "rust-env";
  nativeBuildInputs = [
    rustc
    cargo

    # Example Build-time Additional Dependencies
    pkg-config
  ];
  buildInputs = [
    # Example Run-time Additional Dependencies
    openssl
  ];

  # Set Environment Variables
  RUST_BACKTRACE = 1;
}
```

You should now be able to run the following:

```ShellSession
$ nix-shell --pure
$ cargo build
$ cargo test
```

## Using community maintained Rust toolchains {#using-community-maintained-rust-toolchains}

::: {.note}
The following projects cannot be used within Nixpkgs, since [Import From Derivation](https://nixos.org/manual/nix/unstable/language/import-from-derivation) (IFD) is disallowed in Nixpkgs.
To package things that require Rust nightly, `RUSTC_BOOTSTRAP = true;` can sometimes be used as a hack.
:::

There are two community maintained approaches to Rust toolchain management:
- [oxalica's Rust overlay](https://github.com/oxalica/rust-overlay)
- [fenix](https://github.com/nix-community/fenix)

Despite their names, both projects provides a similar set of packages and overlays under different APIs.

Oxalica's overlay allows you to select a particular Rust version without you providing a hash or a flake input,

Title: Nixpkgs Rust Builds: Advanced `buildRustCrate` Configuration, `nix-shell` Setup, and External Toolchains
Summary
This section expands on `buildRustCrate`, detailing `crateOverrides` for conditional patching and nested dependency overrides. It also covers various configuration options like `rustc` version, build mode, verbosity, extra `rustc` arguments, and standard derivation phases. It then explains how to set up a `nix-shell` for Rust development, recommending `stdenv.mkDerivation` over `buildRustCrate` to provide `cargo`, `rustc`, build-time (e.g., `pkg-config`), run-time (e.g., `openssl`) dependencies, and environment variables. Lastly, it introduces community-maintained Rust toolchain projects (`oxalica's Rust overlay`, `fenix`) for managing Rust versions, including nightly builds. It notes their incompatibility with Nixpkgs due to IFD restrictions, offering `RUSTC_BOOTSTRAP = true;` as a potential workaround for nightly.