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,