1# Rust {#rust}
2
3To install the rust compiler and cargo put
4
5```nix
6environment.systemPackages = [
7 rustc
8 cargo
9];
10```
11
12into your `configuration.nix` or bring them into scope with `nix-shell -p rustc cargo`.
13
14For other versions such as daily builds (beta and nightly),
15use either `rustup` from nixpkgs (which will manage the rust installation in your home directory),
16or use a community maintained [Rust overlay](#using-community-rust-overlays).
17
18## `buildRustPackage`: Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo}
19
20Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
21
22```nix
23{ lib, fetchFromGitHub, rustPlatform }:
24
25rustPlatform.buildRustPackage rec {
26 pname = "ripgrep";
27 version = "12.1.1";
28
29 src = fetchFromGitHub {
30 owner = "BurntSushi";
31 repo = pname;
32 rev = version;
33 hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
34 };
35
36 cargoHash = "sha256-jtBw4ahSl88L0iuCXxQgZVm1EcboWRJMNtjxLVTtzts=";
37
38 meta = with lib; {
39 description = "A fast line-oriented regex search tool, similar to ag and ack";
40 homepage = "https://github.com/BurntSushi/ripgrep";
41 license = licenses.unlicense;
42 maintainers = [ maintainers.tailhook ];
43 };
44}
45```
46
47`buildRustPackage` requires either the `cargoSha256` or the
48`cargoHash` attribute which is computed over all crate sources of this
49package. `cargoHash256` is used for traditional Nix SHA-256 hashes,
50such as the one in the example above. `cargoHash` should instead be
51used for [SRI](https://www.w3.org/TR/SRI/) hashes. For example:
52
53```nix
54 cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
55```
56
57Both types of hashes are permitted when contributing to nixpkgs. The
58Cargo hash is obtained by inserting a fake checksum into the
59expression and building the package once. The correct checksum can
60then be taken from the failed build. A fake hash can be used for
61`cargoSha256` as follows:
62
63```nix
64 cargoSha256 = lib.fakeSha256;
65```
66
67For `cargoHash` you can use:
68
69```nix
70 cargoHash = lib.fakeHash;
71```
72
73Per the instructions in the [Cargo Book](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html)
74best practices guide, Rust applications should always commit the `Cargo.lock`
75file in git to ensure a reproducible build. However, a few packages do not, and
76Nix depends on this file, so if it is missing you can use `cargoPatches` to
77apply it in the `patchPhase`. Consider sending a PR upstream with a note to the
78maintainer describing why it's important to include in the application.
79
80The fetcher will verify that the `Cargo.lock` file is in sync with the `src`
81attribute, and fail the build if not. It will also will compress the vendor
82directory into a tar.gz archive.
83
84The tarball with vendored dependencies contains a directory with the
85package's `name`, which is normally composed of `pname` and
86`version`. This means that the vendored dependencies hash
87(`cargoSha256`/`cargoHash`) is dependent on the package name and
88version. The `cargoDepsName` attribute can be used to use another name
89for the directory of vendored dependencies. For example, the hash can
90be made invariant to the version by setting `cargoDepsName` to
91`pname`:
92
93```nix
94rustPlatform.buildRustPackage rec {
95 pname = "broot";
96 version = "1.2.0";
97
98 src = fetchCrate {
99 inherit pname version;
100 sha256 = "sha256-aDQA4A5mScX9or3Lyiv/5GyAehidnpKKE0grhbP1Ctc=";
101 };
102
103 cargoHash = "sha256-tbrTbutUs5aPSV+yE0IBUZAAytgmZV7Eqxia7g+9zRs=";
104 cargoDepsName = pname;
105
106 # ...
107}
108```
109
110### Importing a `Cargo.lock` file {#importing-a-cargo.lock-file}
111
112Using `cargoSha256` or `cargoHash` is tedious when using
113`buildRustPackage` within a project, since it requires that the hash
114is updated after every change to `Cargo.lock`. Therefore,
115`buildRustPackage` also supports vendoring dependencies directly from
116a `Cargo.lock` file using the `cargoLock` argument. For example:
117
118```nix
119rustPlatform.buildRustPackage {
120 pname = "myproject";
121 version = "1.0.0";
122
123 cargoLock = {
124 lockFile = ./Cargo.lock;
125 };
126
127 # ...
128}
129```
130
131This will retrieve the dependencies using fixed-output derivations from
132the specified lockfile.
133
134One caveat is that `Cargo.lock` cannot be patched in the `patchPhase`
135because it runs after the dependencies have already been fetched. If
136you need to patch or generate the lockfile you can alternatively set
137`cargoLock.lockFileContents` to a string of its contents:
138
139```nix
140rustPlatform.buildRustPackage {
141 pname = "myproject";
142 version = "1.0.0";
143
144 cargoLock = let
145 fixupLockFile = path: f (builtins.readFile path);
146 in {
147 lockFileContents = fixupLockFile ./Cargo.lock;
148 };
149
150 # ...
151}
152```
153
154Note that setting `cargoLock.lockFile` or `cargoLock.lockFileContents`
155doesn't add a `Cargo.lock` to your `src`, and a `Cargo.lock` is still
156required to build a rust package. A simple fix is to use:
157
158```nix
159postPatch = ''
160 cp ${./Cargo.lock} Cargo.lock
161'';
162```
163
164The output hash of each dependency that uses a git source must be
165specified in the `outputHashes` attribute. For example:
166
167```nix
168rustPlatform.buildRustPackage rec {
169 pname = "myproject";
170 version = "1.0.0";
171
172 cargoLock = {
173 lockFile = ./Cargo.lock;
174 outputHashes = {
175 "finalfusion-0.14.0" = "17f4bsdzpcshwh74w5z119xjy2if6l2wgyjy56v621skr2r8y904";
176 };
177 };
178
179 # ...
180}
181```
182
183If you do not specify an output hash for a git dependency, building
184the package will fail and inform you of which crate needs to be
185added. To find the correct hash, you can first use `lib.fakeSha256` or
186`lib.fakeHash` as a stub hash. Building the package (and thus the
187vendored dependencies) will then inform you of the correct hash.
188
189For usage outside nixpkgs, `allowBuiltinFetchGit` could be used to
190avoid having to specify `outputHashes`. For example:
191
192```nix
193rustPlatform.buildRustPackage rec {
194 pname = "myproject";
195 version = "1.0.0";
196
197 cargoLock = {
198 lockFile = ./Cargo.lock;
199 allowBuiltinFetchGit = true;
200 };
201
202 # ...
203}
204```
205
206### Cargo features {#cargo-features}
207
208You can disable default features using `buildNoDefaultFeatures`, and
209extra features can be added with `buildFeatures`.
210
211If you want to use different features for check phase, you can use
212`checkNoDefaultFeatures` and `checkFeatures`. They are only passed to
213`cargo test` and not `cargo build`. If left unset, they default to
214`buildNoDefaultFeatures` and `buildFeatures`.
215
216For example:
217
218```nix
219rustPlatform.buildRustPackage rec {
220 pname = "myproject";
221 version = "1.0.0";
222
223 buildNoDefaultFeatures = true;
224 buildFeatures = [ "color" "net" ];
225
226 # disable network features in tests
227 checkFeatures = [ "color" ];
228
229 # ...
230}
231```
232
233### Cross compilation {#cross-compilation}
234
235By default, Rust packages are compiled for the host platform, just like any
236other package is. The `--target` passed to rust tools is computed from this.
237By default, it takes the `stdenv.hostPlatform.config` and replaces components
238where they are known to differ. But there are ways to customize the argument:
239
240 - To choose a different target by name, define
241 `stdenv.hostPlatform.rustc.config` as that name (a string), and that
242 name will be used instead.
243
244 For example:
245
246 ```nix
247 import <nixpkgs> {
248 crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
249 rustc.config = "thumbv7em-none-eabi";
250 };
251 }
252 ```
253
254 will result in:
255
256 ```shell
257 --target thumbv7em-none-eabi
258 ```
259
260 - To pass a completely custom target, define
261 `stdenv.hostPlatform.rustc.config` with its name, and
262 `stdenv.hostPlatform.rustc.platform` with the value. The value will be
263 serialized to JSON in a file called
264 `${stdenv.hostPlatform.rustc.config}.json`, and the path of that file
265 will be used instead.
266
267 For example:
268
269 ```nix
270 import <nixpkgs> {
271 crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
272 rustc.config = "thumb-crazy";
273 rustc.platform = { foo = ""; bar = ""; };
274 };
275 }
276 ```
277
278 will result in:
279
280 ```shell
281 --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""}
282 ```
283
284Note that currently custom targets aren't compiled with `std`, so `cargo test`
285will fail. This can be ignored by adding `doCheck = false;` to your derivation.
286
287### Running package tests {#running-package-tests}
288
289When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
290`cargo test` on the package to build. To make sure that we don't compile the
291sources twice and to actually test the artifacts that will be used at runtime,
292the tests will be ran in the `release` mode by default.
293
294However, in some cases the test-suite of a package doesn't work properly in the
295`release` mode. For these situations, the mode for `checkPhase` can be changed like
296so:
297
298```nix
299rustPlatform.buildRustPackage {
300 /* ... */
301 checkType = "debug";
302}
303```
304
305Please note that the code will be compiled twice here: once in `release` mode
306for the `buildPhase`, and again in `debug` mode for the `checkPhase`.
307
308Test flags, e.g., `--package foo`, can be passed to `cargo test` via the
309`cargoTestFlags` attribute.
310
311Another attribute, called `checkFlags`, is used to pass arguments to the test
312binary itself, as stated
313[here](https://doc.rust-lang.org/cargo/commands/cargo-test.html).
314
315#### Tests relying on the structure of the `target/` directory {#tests-relying-on-the-structure-of-the-target-directory}
316
317Some tests may rely on the structure of the `target/` directory. Those tests
318are likely to fail because we use `cargo --target` during the build. This means that
319the artifacts
320[are stored in `target/<architecture>/release/`](https://doc.rust-lang.org/cargo/guide/build-cache.html),
321rather than in `target/release/`.
322
323This can only be worked around by patching the affected tests accordingly.
324
325#### Disabling package-tests {#disabling-package-tests}
326
327In some instances, it may be necessary to disable testing altogether (with `doCheck = false;`):
328
329* If no tests exist -- the `checkPhase` should be explicitly disabled to skip
330 unnecessary build steps to speed up the build.
331* If tests are highly impure (e.g. due to network usage).
332
333There will obviously be some corner-cases not listed above where it's sensible to disable tests.
334The above are just guidelines, and exceptions may be granted on a case-by-case basis.
335
336However, please check if it's possible to disable a problematic subset of the
337test suite and leave a comment explaining your reasoning.
338
339This can be achieved with `--skip` in `checkFlags`:
340
341```nix
342rustPlatform.buildRustPackage {
343 /* ... */
344 checkFlags = [
345 # reason for disabling test
346 "--skip=example::tests:example_test"
347 ];
348}
349```
350
351#### Using `cargo-nextest` {#using-cargo-nextest}
352
353Tests can be run with [cargo-nextest](https://github.com/nextest-rs/nextest)
354by setting `useNextest = true`. The same options still apply, but nextest
355accepts a different set of arguments and the settings might need to be
356adapted to be compatible with cargo-nextest.
357
358```nix
359rustPlatform.buildRustPackage {
360 /* ... */
361 useNextest = true;
362}
363```
364
365#### Setting `test-threads` {#setting-test-threads}
366
367`buildRustPackage` will use parallel test threads by default,
368sometimes it may be necessary to disable this so the tests run consecutively.
369
370```nix
371rustPlatform.buildRustPackage {
372 /* ... */
373 dontUseCargoParallelTests = true;
374}
375```
376
377### Building a package in `debug` mode {#building-a-package-in-debug-mode}
378
379By default, `buildRustPackage` will use `release` mode for builds. If a package
380should be built in `debug` mode, it can be configured like so:
381
382```nix
383rustPlatform.buildRustPackage {
384 /* ... */
385 buildType = "debug";
386}
387```
388
389In this scenario, the `checkPhase` will be ran in `debug` mode as well.
390
391### Custom `build`/`install`-procedures {#custom-buildinstall-procedures}
392
393Some packages may use custom scripts for building/installing, e.g. with a `Makefile`.
394In these cases, it's recommended to override the `buildPhase`/`installPhase`/`checkPhase`.
395
396Otherwise, some steps may fail because of the modified directory structure of `target/`.
397
398### Building a crate with an absent or out-of-date Cargo.lock file {#building-a-crate-with-an-absent-or-out-of-date-cargo.lock-file}
399
400`buildRustPackage` needs a `Cargo.lock` file to get all dependencies in the
401source code in a reproducible way. If it is missing or out-of-date one can use
402the `cargoPatches` attribute to update or add it.
403
404```nix
405rustPlatform.buildRustPackage rec {
406 (...)
407 cargoPatches = [
408 # a patch file to add/update Cargo.lock in the source code
409 ./add-Cargo.lock.patch
410 ];
411}
412```
413
414## Compiling non-Rust packages that include Rust code {#compiling-non-rust-packages-that-include-rust-code}
415
416Several non-Rust packages incorporate Rust code for performance- or
417security-sensitive parts. `rustPlatform` exposes several functions and
418hooks that can be used to integrate Cargo in non-Rust packages.
419
420### Vendoring of dependencies {#vendoring-of-dependencies}
421
422Since network access is not allowed in sandboxed builds, Rust crate
423dependencies need to be retrieved using a fetcher. `rustPlatform`
424provides the `fetchCargoTarball` fetcher, which vendors all
425dependencies of a crate. For example, given a source path `src`
426containing `Cargo.toml` and `Cargo.lock`, `fetchCargoTarball`
427can be used as follows:
428
429```nix
430cargoDeps = rustPlatform.fetchCargoTarball {
431 inherit src;
432 hash = "sha256-BoHIN/519Top1NUBjpB/oEMqi86Omt3zTQcXFWqrek0=";
433};
434```
435
436The `src` attribute is required, as well as a hash specified through
437one of the `hash` attribute. The following optional attributes can
438also be used:
439
440* `name`: the name that is used for the dependencies tarball. If
441 `name` is not specified, then the name `cargo-deps` will be used.
442* `sourceRoot`: when the `Cargo.lock`/`Cargo.toml` are in a
443 subdirectory, `sourceRoot` specifies the relative path to these
444 files.
445* `patches`: patches to apply before vendoring. This is useful when
446 the `Cargo.lock`/`Cargo.toml` files need to be patched before
447 vendoring.
448
449If a `Cargo.lock` file is available, you can alternatively use the
450`importCargoLock` function. In contrast to `fetchCargoTarball`, this
451function does not require a hash (unless git dependencies are used)
452and fetches every dependency as a separate fixed-output derivation.
453`importCargoLock` can be used as follows:
454
455```
456cargoDeps = rustPlatform.importCargoLock {
457 lockFile = ./Cargo.lock;
458};
459```
460
461If the `Cargo.lock` file includes git dependencies, then their output
462hashes need to be specified since they are not available through the
463lock file. For example:
464
465```
466cargoDeps = rustPlatform.importCargoLock {
467 lockFile = ./Cargo.lock;
468 outputHashes = {
469 "rand-0.8.3" = "0ya2hia3cn31qa8894s3av2s8j5bjwb6yq92k0jsnlx7jid0jwqa";
470 };
471};
472```
473
474If you do not specify an output hash for a git dependency, building
475`cargoDeps` will fail and inform you of which crate needs to be
476added. To find the correct hash, you can first use `lib.fakeSha256` or
477`lib.fakeHash` as a stub hash. Building `cargoDeps` will then inform
478you of the correct hash.
479
480### Hooks {#hooks}
481
482`rustPlatform` provides the following hooks to automate Cargo builds:
483
484* `cargoSetupHook`: configure Cargo to use dependencies vendored
485 through `fetchCargoTarball`. This hook uses the `cargoDeps`
486 environment variable to find the vendored dependencies. If a project
487 already vendors its dependencies, the variable `cargoVendorDir` can
488 be used instead. When the `Cargo.toml`/`Cargo.lock` files are not in
489 `sourceRoot`, then the optional `cargoRoot` is used to specify the
490 Cargo root directory relative to `sourceRoot`.
491* `cargoBuildHook`: use Cargo to build a crate. If the crate to be
492 built is a crate in e.g. a Cargo workspace, the relative path to the
493 crate to build can be set through the optional `buildAndTestSubdir`
494 environment variable. Features can be specified with
495 `cargoBuildNoDefaultFeatures` and `cargoBuildFeatures`. Additional
496 Cargo build flags can be passed through `cargoBuildFlags`.
497* `maturinBuildHook`: use [Maturin](https://github.com/PyO3/maturin)
498 to build a Python wheel. Similar to `cargoBuildHook`, the optional
499 variable `buildAndTestSubdir` can be used to build a crate in a
500 Cargo workspace. Additional Maturin flags can be passed through
501 `maturinBuildFlags`.
502* `cargoCheckHook`: run tests using Cargo. The build type for checks
503 can be set using `cargoCheckType`. Features can be specified with
504 `cargoCheckNoDefaultFeatures` and `cargoCheckFeatures`. Additional
505 flags can be passed to the tests using `checkFlags` and
506 `checkFlagsArray`. By default, tests are run in parallel. This can
507 be disabled by setting `dontUseCargoParallelTests`.
508* `cargoNextestHook`: run tests using
509 [cargo-nextest](https://github.com/nextest-rs/nextest). The same
510 options for `cargoCheckHook` also applies to `cargoNextestHook`.
511* `cargoInstallHook`: install binaries and static/shared libraries
512 that were built using `cargoBuildHook`.
513* `bindgenHook`: for crates which use `bindgen` as a build dependency, lets
514 `bindgen` find `libclang` and `libclang` find the libraries in `buildInputs`.
515
516### Examples {#examples}
517
518#### Python package using `setuptools-rust` {#python-package-using-setuptools-rust}
519
520For Python packages using `setuptools-rust`, you can use
521`fetchCargoTarball` and `cargoSetupHook` to retrieve and set up Cargo
522dependencies. The build itself is then performed by
523`buildPythonPackage`.
524
525The following example outlines how the `tokenizers` Python package is
526built. Since the Python package is in the `source/bindings/python`
527directory of the `tokenizers` project's source archive, we use
528`sourceRoot` to point the tooling to this directory:
529
530```nix
531{ fetchFromGitHub
532, buildPythonPackage
533, rustPlatform
534, setuptools-rust
535}:
536
537buildPythonPackage rec {
538 pname = "tokenizers";
539 version = "0.10.0";
540
541 src = fetchFromGitHub {
542 owner = "huggingface";
543 repo = pname;
544 rev = "python-v${version}";
545 hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw=";
546 };
547
548 cargoDeps = rustPlatform.fetchCargoTarball {
549 inherit src sourceRoot;
550 name = "${pname}-${version}";
551 hash = "sha256-miW//pnOmww2i6SOGbkrAIdc/JMDT4FJLqdMFojZeoY=";
552 };
553
554 sourceRoot = "source/bindings/python";
555
556 nativeBuildInputs = [ setuptools-rust ] ++ (with rustPlatform; [
557 cargoSetupHook
558 rust.cargo
559 rust.rustc
560 ]);
561
562 # ...
563}
564```
565
566In some projects, the Rust crate is not in the main Python source
567directory. In such cases, the `cargoRoot` attribute can be used to
568specify the crate's directory relative to `sourceRoot`. In the
569following example, the crate is in `src/rust`, as specified in the
570`cargoRoot` attribute. Note that we also need to specify the correct
571path for `fetchCargoTarball`.
572
573```nix
574
575{ buildPythonPackage
576, fetchPypi
577, rustPlatform
578, setuptools-rust
579, openssl
580}:
581
582buildPythonPackage rec {
583 pname = "cryptography";
584 version = "3.4.2"; # Also update the hash in vectors.nix
585
586 src = fetchPypi {
587 inherit pname version;
588 hash = "sha256-xGDilsjLOnls3MfVbGKnj80KCUCczZxlis5PmHzpNcQ=";
589 };
590
591 cargoDeps = rustPlatform.fetchCargoTarball {
592 inherit src;
593 sourceRoot = "${pname}-${version}/${cargoRoot}";
594 name = "${pname}-${version}";
595 hash = "sha256-PS562W4L1NimqDV2H0jl5vYhL08H9est/pbIxSdYVfo=";
596 };
597
598 cargoRoot = "src/rust";
599
600 # ...
601}
602```
603
604#### Python package using `maturin` {#python-package-using-maturin}
605
606Python packages that use [Maturin](https://github.com/PyO3/maturin)
607can be built with `fetchCargoTarball`, `cargoSetupHook`, and
608`maturinBuildHook`. For example, the following (partial) derivation
609builds the `retworkx` Python package. `fetchCargoTarball` and
610`cargoSetupHook` are used to fetch and set up the crate dependencies.
611`maturinBuildHook` is used to perform the build.
612
613```nix
614{ lib
615, buildPythonPackage
616, rustPlatform
617, fetchFromGitHub
618}:
619
620buildPythonPackage rec {
621 pname = "retworkx";
622 version = "0.6.0";
623
624 src = fetchFromGitHub {
625 owner = "Qiskit";
626 repo = "retworkx";
627 rev = version;
628 hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
629 };
630
631 cargoDeps = rustPlatform.fetchCargoTarball {
632 inherit src;
633 name = "${pname}-${version}";
634 hash = "sha256-heOBK8qi2nuc/Ib+I/vLzZ1fUUD/G/KTw9d7M4Hz5O0=";
635 };
636
637 format = "pyproject";
638
639 nativeBuildInputs = with rustPlatform; [ cargoSetupHook maturinBuildHook ];
640
641 # ...
642}
643```
644
645## Setting Up `nix-shell` {#setting-up-nix-shell}
646
647Oftentimes you want to develop code from within `nix-shell`. Unfortunately
648`buildRustCrate` does not support common `nix-shell` operations directly
649(see [this issue](https://github.com/NixOS/nixpkgs/issues/37945))
650so we will use `stdenv.mkDerivation` instead.
651
652Using the example `hello` project above, we want to do the following:
653
654- Have access to `cargo` and `rustc`
655- Have the `openssl` library available to a crate through it's _normal_
656 compilation mechanism (`pkg-config`).
657
658A typical `shell.nix` might look like:
659
660```nix
661with import <nixpkgs> {};
662
663stdenv.mkDerivation {
664 name = "rust-env";
665 nativeBuildInputs = [
666 rustc cargo
667
668 # Example Build-time Additional Dependencies
669 pkg-config
670 ];
671 buildInputs = [
672 # Example Run-time Additional Dependencies
673 openssl
674 ];
675
676 # Set Environment Variables
677 RUST_BACKTRACE = 1;
678}
679```
680
681You should now be able to run the following:
682
683```ShellSession
684$ nix-shell --pure
685$ cargo build
686$ cargo test
687```
688
689### Controlling Rust Version Inside `nix-shell` {#controlling-rust-version-inside-nix-shell}
690
691To control your rust version (i.e. use nightly) from within `shell.nix` (or
692other nix expressions) you can use the following `shell.nix`
693
694```nix
695# Latest Nightly
696with import <nixpkgs> {};
697let src = fetchFromGitHub {
698 owner = "mozilla";
699 repo = "nixpkgs-mozilla";
700 # commit from: 2019-05-15
701 rev = "9f35c4b09fd44a77227e79ff0c1b4b6a69dff533";
702 hash = "sha256-18h0nvh55b5an4gmlgfbvwbyqj91bklf1zymis6lbdh75571qaz0=";
703 };
704in
705with import "${src.out}/rust-overlay.nix" pkgs pkgs;
706stdenv.mkDerivation {
707 name = "rust-env";
708 buildInputs = [
709 # Note: to use stable, just replace `nightly` with `stable`
710 latest.rustChannels.nightly.rust
711
712 # Add some extra dependencies from `pkgs`
713 pkg-config openssl
714 ];
715
716 # Set Environment Variables
717 RUST_BACKTRACE = 1;
718}
719```
720
721Now run:
722
723```ShellSession
724$ rustc --version
725rustc 1.26.0-nightly (188e693b3 2018-03-26)
726```
727
728To see that you are using nightly.
729
730## Using community Rust overlays {#using-community-rust-overlays}
731
732There are two community maintained approaches to Rust toolchain management:
733- [oxalica's Rust overlay](https://github.com/oxalica/rust-overlay)
734- [fenix](https://github.com/nix-community/fenix)
735
736Oxalica's overlay allows you to select a particular Rust version and components.
737See [their documentation](https://github.com/oxalica/rust-overlay#rust-overlay) for more
738detailed usage.
739
740Fenix is an alternative to `rustup` and can also be used as an overlay.
741
742Both oxalica's overlay and fenix better integrate with nix and cache optimizations.
743Because of this and ergonomics, either of those community projects
744should be preferred to the Mozilla's Rust overlay (`nixpkgs-mozilla`).
745
746### How to select a specific `rustc` and toolchain version {#how-to-select-a-specific-rustc-and-toolchain-version}
747
748You can consume the oxalica overlay and use it to grab a specific Rust toolchain version.
749Here is an example `shell.nix` showing how to grab the current stable toolchain:
750```nix
751{ pkgs ? import <nixpkgs> {
752 overlays = [
753 (import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
754 ];
755 }
756}:
757pkgs.mkShell {
758 nativeBuildInputs = with pkgs; [
759 pkg-config
760 rust-bin.stable.latest.minimal
761 ];
762}
763```
764
765You can try this out by:
7661. Saving that to `shell.nix`
7672. Executing `nix-shell --pure --command 'rustc --version'`
768
769As of writing, this prints out `rustc 1.56.0 (09c42c458 2021-10-18)`.
770
771### How to use an overlay toolchain in a derivation {#how-to-use-an-overlay-toolchain-in-a-derivation}
772
773You can also use an overlay's Rust toolchain with `buildRustPackage`.
774The below snippet demonstrates invoking `buildRustPackage` with an oxalica overlay selected Rust toolchain:
775```nix
776with import <nixpkgs> {
777 overlays = [
778 (import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
779 ];
780};
781
782rustPlatform.buildRustPackage rec {
783 pname = "ripgrep";
784 version = "12.1.1";
785 nativeBuildInputs = [
786 rust-bin.stable.latest.minimal
787 ];
788
789 src = fetchFromGitHub {
790 owner = "BurntSushi";
791 repo = "ripgrep";
792 rev = version;
793 hash = "sha256-1hqps7l5qrjh9f914r5i6kmcz6f1yb951nv4lby0cjnp5l253kps=";
794 };
795
796 cargoSha256 = "03wf9r2csi6jpa7v5sw5lpxkrk4wfzwmzx7k3991q3bdjzcwnnwp";
797
798 meta = with lib; {
799 description = "A fast line-oriented regex search tool, similar to ag and ack";
800 homepage = "https://github.com/BurntSushi/ripgrep";
801 license = licenses.unlicense;
802 maintainers = [ maintainers.tailhook ];
803 };
804}
805```
806
807Follow the below steps to try that snippet.
8081. create a new directory
8091. save the above snippet as `default.nix` in that directory
8101. cd into that directory and run `nix-build`
811
812### Rust overlay installation {#rust-overlay-installation}
813
814You can use this overlay by either changing your local nixpkgs configuration,
815or by adding the overlay declaratively in a nix expression, e.g. in `configuration.nix`.
816For more information see [the manual on installing overlays](#sec-overlays-install).
817
818### Declarative Rust overlay installation {#declarative-rust-overlay-installation}
819
820This snippet shows how to use oxalica's Rust overlay.
821Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.nix`, or similar:
822
823```nix
824{ pkgs ? import <nixpkgs> {
825 overlays = [
826 (import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
827 # Further overlays go here
828 ];
829 };
830};
831```
832
833Note that this will fetch the latest overlay version when rebuilding your system.