python312Packages.stable-baselines3: 2.4.0 -> 2.4.1-unstable-2025-01-07 (#373253)
[NixPkgs.git] / doc / languages-frameworks / rust.section.md
blobf1f951b9650fd6fff8cc8b8c1f22cdeb944a05f2
1 # Rust {#rust}
3 To install the rust compiler and cargo put
5 ```nix
7   environment.systemPackages = [
8     rustc
9     cargo
10   ];
12 ```
14 into your `configuration.nix` or bring them into scope with `nix-shell -p rustc cargo`.
16 For other versions such as daily builds (beta and nightly),
17 use either `rustup` from nixpkgs (which will manage the rust installation in your home directory),
18 or use [community maintained Rust toolchains](#using-community-maintained-rust-toolchains).
20 ## `buildRustPackage`: Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo}
22 Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
24 ```nix
25 { lib, fetchFromGitHub, rustPlatform }:
27 rustPlatform.buildRustPackage rec {
28   pname = "ripgrep";
29   version = "12.1.1";
31   src = fetchFromGitHub {
32     owner = "BurntSushi";
33     repo = pname;
34     rev = version;
35     hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
36   };
38   cargoHash = "sha256-jtBw4ahSl88L0iuCXxQgZVm1EcboWRJMNtjxLVTtzts=";
40   meta = {
41     description = "Fast line-oriented regex search tool, similar to ag and ack";
42     homepage = "https://github.com/BurntSushi/ripgrep";
43     license = lib.licenses.unlicense;
44     maintainers = [ ];
45   };
47 ```
49 `buildRustPackage` requires a `cargoHash` attribute, computed over all crate sources of this package.
51 ::: {.warning}
52 `cargoSha256` is already deprecated, and is subject to removal in favor of
53 `cargoHash` which supports [SRI](https://www.w3.org/TR/SRI/) hashes.
55 If you are still using `cargoSha256`, you can simply replace it with
56 `cargoHash` and recompute the hash, or convert the original sha256 to SRI
57 hash using `nix-hash --to-sri --type sha256 "<original sha256>"`.
58 :::
60 ```nix
62   cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
64 ```
66 Exception: If the application has cargo `git` dependencies, the `cargoHash`
67 approach will not work by default. In this case, you can set `useFetchCargoVendor = true`
68 to use an improved fetcher that supports handling `git` dependencies.
70 ```nix
72   useFetchCargoVendor = true;
73   cargoHash = "sha256-RqPVFovDaD2rW31HyETJfQ0qVwFxoGEvqkIgag3H6KU=";
75 ```
77 If this method still does not work, you can resort to copying the `Cargo.lock` file into nixpkgs
78 and importing it as described in the [next section](#importing-a-cargo.lock-file).
80 Both types of hashes are permitted when contributing to nixpkgs. The
81 Cargo hash is obtained by inserting a fake checksum into the
82 expression and building the package once. The correct checksum can
83 then be taken from the failed build. A fake hash can be used for
84 `cargoHash` as follows:
86 ```nix
88   cargoHash = lib.fakeHash;
90 ```
92 Per the instructions in the [Cargo Book](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html)
93 best practices guide, Rust applications should always commit the `Cargo.lock`
94 file in git to ensure a reproducible build. However, a few packages do not, and
95 Nix depends on this file, so if it is missing you can use `cargoPatches` to
96 apply it in the `patchPhase`. Consider sending a PR upstream with a note to the
97 maintainer describing why it's important to include in the application.
99 The fetcher will verify that the `Cargo.lock` file is in sync with the `src`
100 attribute, and fail the build if not. It will also will compress the vendor
101 directory into a tar.gz archive.
103 The tarball with vendored dependencies contains a directory with the
104 package's `name`, which is normally composed of `pname` and
105 `version`. This means that the vendored dependencies hash
106 (`cargoHash`) is dependent on the package name and
107 version. The `cargoDepsName` attribute can be used to use another name
108 for the directory of vendored dependencies. For example, the hash can
109 be made invariant to the version by setting `cargoDepsName` to
110 `pname`:
112 ```nix
113 rustPlatform.buildRustPackage rec {
114   pname = "broot";
115   version = "1.2.0";
117   src = fetchCrate {
118     inherit pname version;
119     hash = "sha256-aDQA4A5mScX9or3Lyiv/5GyAehidnpKKE0grhbP1Ctc=";
120   };
122   cargoHash = "sha256-tbrTbutUs5aPSV+yE0IBUZAAytgmZV7Eqxia7g+9zRs=";
123   cargoDepsName = pname;
125   # ...
129 ### Importing a `Cargo.lock` file {#importing-a-cargo.lock-file}
131 Using a vendored hash (`cargoHash`) is tedious when using
132 `buildRustPackage` within a project, since it requires that the hash
133 is updated after every change to `Cargo.lock`. Therefore,
134 `buildRustPackage` also supports vendoring dependencies directly from
135 a `Cargo.lock` file using the `cargoLock` argument. For example:
137 ```nix
138 rustPlatform.buildRustPackage {
139   pname = "myproject";
140   version = "1.0.0";
142   cargoLock = {
143     lockFile = ./Cargo.lock;
144   };
146   # ...
150 This will retrieve the dependencies using fixed-output derivations from
151 the specified lockfile.
153 One caveat is that `Cargo.lock` cannot be patched in the `patchPhase`
154 because it runs after the dependencies have already been fetched. If
155 you need to patch or generate the lockfile you can alternatively set
156 `cargoLock.lockFileContents` to a string of its contents:
158 ```nix
159 rustPlatform.buildRustPackage {
160   pname = "myproject";
161   version = "1.0.0";
163   cargoLock = let
164     fixupLockFile = path: f (builtins.readFile path);
165   in {
166     lockFileContents = fixupLockFile ./Cargo.lock;
167   };
169   # ...
173 If the upstream source repository lacks a `Cargo.lock` file, you must add one
174 to `src`, as it is essential for building a Rust package. Setting
175 `cargoLock.lockFile` or `cargoLock.lockFileContents` will not automatically add
176 a `Cargo.lock` file to `src`. A straightforward solution is to use:
178 ```nix
180   postPatch = ''
181     ln -s ${./Cargo.lock} Cargo.lock
182   '';
186 The output hash of each dependency that uses a git source must be
187 specified in the `outputHashes` attribute. For example:
189 ```nix
190 rustPlatform.buildRustPackage rec {
191   pname = "myproject";
192   version = "1.0.0";
194   cargoLock = {
195     lockFile = ./Cargo.lock;
196     outputHashes = {
197       "finalfusion-0.14.0" = "17f4bsdzpcshwh74w5z119xjy2if6l2wgyjy56v621skr2r8y904";
198     };
199   };
201   # ...
205 If you do not specify an output hash for a git dependency, building
206 the package will fail and inform you of which crate needs to be
207 added. To find the correct hash, you can first use `lib.fakeSha256` or
208 `lib.fakeHash` as a stub hash. Building the package (and thus the
209 vendored dependencies) will then inform you of the correct hash.
211 For usage outside nixpkgs, `allowBuiltinFetchGit` could be used to
212 avoid having to specify `outputHashes`. For example:
214 ```nix
215 rustPlatform.buildRustPackage rec {
216   pname = "myproject";
217   version = "1.0.0";
219   cargoLock = {
220     lockFile = ./Cargo.lock;
221     allowBuiltinFetchGit = true;
222   };
224   # ...
228 ### Cargo features {#cargo-features}
230 You can disable default features using `buildNoDefaultFeatures`, and
231 extra features can be added with `buildFeatures`.
233 If you want to use different features for check phase, you can use
234 `checkNoDefaultFeatures` and `checkFeatures`. They are only passed to
235 `cargo test` and not `cargo build`. If left unset, they default to
236 `buildNoDefaultFeatures` and `buildFeatures`.
238 For example:
240 ```nix
241 rustPlatform.buildRustPackage rec {
242   pname = "myproject";
243   version = "1.0.0";
245   buildNoDefaultFeatures = true;
246   buildFeatures = [ "color" "net" ];
248   # disable network features in tests
249   checkFeatures = [ "color" ];
251   # ...
255 ### Cross compilation {#cross-compilation}
257 By default, Rust packages are compiled for the host platform, just like any
258 other package is.  The `--target` passed to rust tools is computed from this.
259 By default, it takes the `stdenv.hostPlatform.config` and replaces components
260 where they are known to differ. But there are ways to customize the argument:
262  - To choose a different target by name, define
263    `stdenv.hostPlatform.rust.rustcTarget` as that name (a string), and that
264    name will be used instead.
266    For example:
268    ```nix
269    import <nixpkgs> {
270      crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
271        rust.rustcTarget = "thumbv7em-none-eabi";
272      };
273    }
274    ```
276    will result in:
278    ```shell
279    --target thumbv7em-none-eabi
280    ```
282  - To pass a completely custom target, define
283    `stdenv.hostPlatform.rust.rustcTarget` with its name, and
284    `stdenv.hostPlatform.rust.platform` with the value.  The value will be
285    serialized to JSON in a file called
286    `${stdenv.hostPlatform.rust.rustcTarget}.json`, and the path of that file
287    will be used instead.
289    For example:
291    ```nix
292    import <nixpkgs> {
293      crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
294        rust.rustcTarget = "thumb-crazy";
295        rust.platform = { foo = ""; bar = ""; };
296      };
297    }
298    ```
300    will result in:
302    ```shell
303    --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""}
304    ```
306 Note that currently custom targets aren't compiled with `std`, so `cargo test`
307 will fail. This can be ignored by adding `doCheck = false;` to your derivation.
309 ### Running package tests {#running-package-tests}
311 When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
312 `cargo test` on the package to build. To make sure that we don't compile the
313 sources twice and to actually test the artifacts that will be used at runtime,
314 the tests will be ran in the `release` mode by default.
316 However, in some cases the test-suite of a package doesn't work properly in the
317 `release` mode. For these situations, the mode for `checkPhase` can be changed like
320 ```nix
321 rustPlatform.buildRustPackage {
322   /* ... */
323   checkType = "debug";
327 Please note that the code will be compiled twice here: once in `release` mode
328 for the `buildPhase`, and again in `debug` mode for the `checkPhase`.
330 Test flags, e.g., `--package foo`, can be passed to `cargo test` via the
331 `cargoTestFlags` attribute.
333 Another attribute, called `checkFlags`, is used to pass arguments to the test
334 binary itself, as stated
335 [here](https://doc.rust-lang.org/cargo/commands/cargo-test.html).
337 #### Tests relying on the structure of the `target/` directory {#tests-relying-on-the-structure-of-the-target-directory}
339 Some tests may rely on the structure of the `target/` directory. Those tests
340 are likely to fail because we use `cargo --target` during the build. This means that
341 the artifacts
342 [are stored in `target/<architecture>/release/`](https://doc.rust-lang.org/cargo/guide/build-cache.html),
343 rather than in `target/release/`.
345 This can only be worked around by patching the affected tests accordingly.
347 #### Disabling package-tests {#disabling-package-tests}
349 In some instances, it may be necessary to disable testing altogether (with `doCheck = false;`):
351 * If no tests exist -- the `checkPhase` should be explicitly disabled to skip
352   unnecessary build steps to speed up the build.
353 * If tests are highly impure (e.g. due to network usage).
355 There will obviously be some corner-cases not listed above where it's sensible to disable tests.
356 The above are just guidelines, and exceptions may be granted on a case-by-case basis.
358 However, please check if it's possible to disable a problematic subset of the
359 test suite and leave a comment explaining your reasoning.
361 This can be achieved with `--skip` in `checkFlags`:
363 ```nix
364 rustPlatform.buildRustPackage {
365   /* ... */
366   checkFlags = [
367     # reason for disabling test
368     "--skip=example::tests:example_test"
369   ];
373 #### Using `cargo-nextest` {#using-cargo-nextest}
375 Tests can be run with [cargo-nextest](https://github.com/nextest-rs/nextest)
376 by setting `useNextest = true`. The same options still apply, but nextest
377 accepts a different set of arguments and the settings might need to be
378 adapted to be compatible with cargo-nextest.
380 ```nix
381 rustPlatform.buildRustPackage {
382   /* ... */
383   useNextest = true;
387 #### Setting `test-threads` {#setting-test-threads}
389 `buildRustPackage` will use parallel test threads by default,
390 sometimes it may be necessary to disable this so the tests run consecutively.
392 ```nix
393 rustPlatform.buildRustPackage {
394   /* ... */
395   dontUseCargoParallelTests = true;
399 ### Building a package in `debug` mode {#building-a-package-in-debug-mode}
401 By default, `buildRustPackage` will use `release` mode for builds. If a package
402 should be built in `debug` mode, it can be configured like so:
404 ```nix
405 rustPlatform.buildRustPackage {
406   /* ... */
407   buildType = "debug";
411 In this scenario, the `checkPhase` will be ran in `debug` mode as well.
413 ### Custom `build`/`install`-procedures {#custom-buildinstall-procedures}
415 Some packages may use custom scripts for building/installing, e.g. with a `Makefile`.
416 In these cases, it's recommended to override the `buildPhase`/`installPhase`/`checkPhase`.
418 Otherwise, some steps may fail because of the modified directory structure of `target/`.
420 ### 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}
422 `buildRustPackage` needs a `Cargo.lock` file to get all dependencies in the
423 source code in a reproducible way. If it is missing or out-of-date one can use
424 the `cargoPatches` attribute to update or add it.
426 ```nix
427 rustPlatform.buildRustPackage rec {
428   # ...
429   cargoPatches = [
430     # a patch file to add/update Cargo.lock in the source code
431     ./add-Cargo.lock.patch
432   ];
436 ### Compiling non-Rust packages that include Rust code {#compiling-non-rust-packages-that-include-rust-code}
438 Several non-Rust packages incorporate Rust code for performance- or
439 security-sensitive parts. `rustPlatform` exposes several functions and
440 hooks that can be used to integrate Cargo in non-Rust packages.
442 #### Vendoring of dependencies {#vendoring-of-dependencies}
444 Since network access is not allowed in sandboxed builds, Rust crate
445 dependencies need to be retrieved using a fetcher. `rustPlatform`
446 provides the `fetchCargoTarball` fetcher, which vendors all
447 dependencies of a crate. For example, given a source path `src`
448 containing `Cargo.toml` and `Cargo.lock`, `fetchCargoTarball`
449 can be used as follows:
451 ```nix
453   cargoDeps = rustPlatform.fetchCargoTarball {
454     inherit src;
455     hash = "sha256-BoHIN/519Top1NUBjpB/oEMqi86Omt3zTQcXFWqrek0=";
456   };
460 The `src` attribute is required, as well as a hash specified through
461 one of the `hash` attribute. The following optional attributes can
462 also be used:
464 * `name`: the name that is used for the dependencies tarball.  If
465   `name` is not specified, then the name `cargo-deps` will be used.
466 * `sourceRoot`: when the `Cargo.lock`/`Cargo.toml` are in a
467   subdirectory, `sourceRoot` specifies the relative path to these
468   files.
469 * `patches`: patches to apply before vendoring. This is useful when
470   the `Cargo.lock`/`Cargo.toml` files need to be patched before
471   vendoring.
473 In case the lockfile contains cargo `git` dependencies, you can use
474 `fetchCargoVendor` instead.
475 ```nix
477   cargoDeps = rustPlatform.fetchCargoVendor {
478     inherit src;
479     hash = "sha256-RqPVFovDaD2rW31HyETJfQ0qVwFxoGEvqkIgag3H6KU=";
480   };
484 If a `Cargo.lock` file is available, you can alternatively use the
485 `importCargoLock` function. In contrast to `fetchCargoTarball`, this
486 function does not require a hash (unless git dependencies are used)
487 and fetches every dependency as a separate fixed-output derivation.
488 `importCargoLock` can be used as follows:
490 ```nix
492   cargoDeps = rustPlatform.importCargoLock {
493     lockFile = ./Cargo.lock;
494   };
498 If the `Cargo.lock` file includes git dependencies, then their output
499 hashes need to be specified since they are not available through the
500 lock file. For example:
502 ```nix
504   cargoDeps = rustPlatform.importCargoLock {
505     lockFile = ./Cargo.lock;
506     outputHashes = {
507       "rand-0.8.3" = "0ya2hia3cn31qa8894s3av2s8j5bjwb6yq92k0jsnlx7jid0jwqa";
508     };
509   };
513 If you do not specify an output hash for a git dependency, building
514 `cargoDeps` will fail and inform you of which crate needs to be
515 added. To find the correct hash, you can first use `lib.fakeSha256` or
516 `lib.fakeHash` as a stub hash. Building `cargoDeps` will then inform
517 you of the correct hash.
519 #### Hooks {#hooks}
521 `rustPlatform` provides the following hooks to automate Cargo builds:
523 * `cargoSetupHook`: configure Cargo to use dependencies vendored
524   through `fetchCargoTarball`. This hook uses the `cargoDeps`
525   environment variable to find the vendored dependencies. If a project
526   already vendors its dependencies, the variable `cargoVendorDir` can
527   be used instead. When the `Cargo.toml`/`Cargo.lock` files are not in
528   `sourceRoot`, then the optional `cargoRoot` is used to specify the
529   Cargo root directory relative to `sourceRoot`.
530 * `cargoBuildHook`: use Cargo to build a crate. If the crate to be
531   built is a crate in e.g. a Cargo workspace, the relative path to the
532   crate to build can be set through the optional `buildAndTestSubdir`
533   environment variable. Features can be specified with
534   `cargoBuildNoDefaultFeatures` and `cargoBuildFeatures`. Additional
535   Cargo build flags can be passed through `cargoBuildFlags`.
536 * `maturinBuildHook`: use [Maturin](https://github.com/PyO3/maturin)
537   to build a Python wheel. Similar to `cargoBuildHook`, the optional
538   variable `buildAndTestSubdir` can be used to build a crate in a
539   Cargo workspace. Additional Maturin flags can be passed through
540   `maturinBuildFlags`.
541 * `cargoCheckHook`: run tests using Cargo. The build type for checks
542   can be set using `cargoCheckType`. Features can be specified with
543   `cargoCheckNoDefaultFeatures` and `cargoCheckFeatures`. Additional
544   flags can be passed to the tests using `checkFlags` and
545   `checkFlagsArray`. By default, tests are run in parallel. This can
546   be disabled by setting `dontUseCargoParallelTests`.
547 * `cargoNextestHook`: run tests using
548   [cargo-nextest](https://github.com/nextest-rs/nextest). The same
549   options for `cargoCheckHook` also applies to `cargoNextestHook`.
550 * `cargoInstallHook`: install binaries and static/shared libraries
551   that were built using `cargoBuildHook`.
552 * `bindgenHook`: for crates which use `bindgen` as a build dependency, lets
553   `bindgen` find `libclang` and `libclang` find the libraries in `buildInputs`.
555 #### Examples {#examples}
557 #### Python package using `setuptools-rust` {#python-package-using-setuptools-rust}
559 For Python packages using `setuptools-rust`, you can use
560 `fetchCargoTarball` and `cargoSetupHook` to retrieve and set up Cargo
561 dependencies. The build itself is then performed by
562 `buildPythonPackage`.
564 The following example outlines how the `tokenizers` Python package is
565 built. Since the Python package is in the `source/bindings/python`
566 directory of the `tokenizers` project's source archive, we use
567 `sourceRoot` to point the tooling to this directory:
569 ```nix
570 { fetchFromGitHub
571 , buildPythonPackage
572 , cargo
573 , rustPlatform
574 , rustc
575 , setuptools-rust
578 buildPythonPackage rec {
579   pname = "tokenizers";
580   version = "0.10.0";
582   src = fetchFromGitHub {
583     owner = "huggingface";
584     repo = pname;
585     rev = "python-v${version}";
586     hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw=";
587   };
589   cargoDeps = rustPlatform.fetchCargoTarball {
590     inherit pname version src sourceRoot;
591     hash = "sha256-miW//pnOmww2i6SOGbkrAIdc/JMDT4FJLqdMFojZeoY=";
592   };
594   sourceRoot = "${src.name}/bindings/python";
596   nativeBuildInputs = [
597     cargo
598     rustPlatform.cargoSetupHook
599     rustc
600     setuptools-rust
601   ];
603   # ...
607 In some projects, the Rust crate is not in the main Python source
608 directory.  In such cases, the `cargoRoot` attribute can be used to
609 specify the crate's directory relative to `sourceRoot`. In the
610 following example, the crate is in `src/rust`, as specified in the
611 `cargoRoot` attribute. Note that we also need to specify the correct
612 path for `fetchCargoTarball`.
614 ```nix
616 { buildPythonPackage
617 , fetchPypi
618 , rustPlatform
619 , setuptools-rust
620 , openssl
623 buildPythonPackage rec {
624   pname = "cryptography";
625   version = "3.4.2"; # Also update the hash in vectors.nix
627   src = fetchPypi {
628     inherit pname version;
629     hash = "sha256-xGDilsjLOnls3MfVbGKnj80KCUCczZxlis5PmHzpNcQ=";
630   };
632   cargoDeps = rustPlatform.fetchCargoTarball {
633     inherit pname version src;
634     sourceRoot = "${pname}-${version}/${cargoRoot}";
635     hash = "sha256-PS562W4L1NimqDV2H0jl5vYhL08H9est/pbIxSdYVfo=";
636   };
638   cargoRoot = "src/rust";
640   # ...
644 #### Python package using `maturin` {#python-package-using-maturin}
646 Python packages that use [Maturin](https://github.com/PyO3/maturin)
647 can be built with `fetchCargoTarball`, `cargoSetupHook`, and
648 `maturinBuildHook`. For example, the following (partial) derivation
649 builds the `retworkx` Python package. `fetchCargoTarball` and
650 `cargoSetupHook` are used to fetch and set up the crate dependencies.
651 `maturinBuildHook` is used to perform the build.
653 ```nix
654 { lib
655 , buildPythonPackage
656 , rustPlatform
657 , fetchFromGitHub
660 buildPythonPackage rec {
661   pname = "retworkx";
662   version = "0.6.0";
663   pyproject = true;
665   src = fetchFromGitHub {
666     owner = "Qiskit";
667     repo = "retworkx";
668     rev = version;
669     hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
670   };
672   cargoDeps = rustPlatform.fetchCargoTarball {
673     inherit pname version src;
674     hash = "sha256-heOBK8qi2nuc/Ib+I/vLzZ1fUUD/G/KTw9d7M4Hz5O0=";
675   };
677   nativeBuildInputs = with rustPlatform; [ cargoSetupHook maturinBuildHook ];
679   # ...
683 #### Rust package built with `meson` {#rust-package-built-with-meson}
685 Some projects, especially GNOME applications, are built with the Meson Build System instead of calling Cargo directly. Using `rustPlatform.buildRustPackage` may successfully build the main program, but related files will be missing. Instead, you need to set up Cargo dependencies with `fetchCargoTarball` and `cargoSetupHook` and leave the rest to Meson. `rust` and `cargo` are still needed in `nativeBuildInputs` for Meson to use.
687 ```nix
688 { lib
689 , stdenv
690 , fetchFromGitLab
691 , meson
692 , ninja
693 , pkg-config
694 , rustPlatform
695 , rustc
696 , cargo
697 , wrapGAppsHook4
698 , blueprint-compiler
699 , libadwaita
700 , libsecret
701 , tinysparql
704 stdenv.mkDerivation rec {
705   pname = "health";
706   version = "0.95.0";
708   src = fetchFromGitLab {
709     domain = "gitlab.gnome.org";
710     owner = "World";
711     repo = "health";
712     rev = version;
713     hash = "sha256-PrNPprSS98yN8b8yw2G6hzTSaoE65VbsM3q7FVB4mds=";
714   };
716   cargoDeps = rustPlatform.fetchCargoTarball {
717     inherit pname version src;
718     hash = "sha256-8fa3fa+sFi5H+49B5sr2vYPkp9C9s6CcE0zv4xB8gww=";
719   };
721   nativeBuildInputs = [
722     meson
723     ninja
724     pkg-config
725     rustPlatform.cargoSetupHook
726     rustc
727     cargo
728     wrapGAppsHook4
729     blueprint-compiler
730   ];
732   buildInputs = [
733     libadwaita
734     libsecret
735     tinysparql
736   ];
738   # ...
742 ## `buildRustCrate`: Compiling Rust crates using Nix instead of Cargo {#compiling-rust-crates-using-nix-instead-of-cargo}
744 ### Simple operation {#simple-operation}
746 When run, `cargo build` produces a file called `Cargo.lock`,
747 containing pinned versions of all dependencies. Nixpkgs contains a
748 tool called `crate2Nix` (`nix-shell -p crate2nix`), which can be
749 used to turn a `Cargo.lock` into a Nix expression.  That Nix
750 expression calls `rustc` directly (hence bypassing Cargo), and can
751 be used to compile a crate and all its dependencies.
753 See [`crate2nix`'s documentation](https://github.com/kolloch/crate2nix#known-restrictions)
754 for instructions on how to use it.
756 ### Handling external dependencies {#handling-external-dependencies}
758 Some crates require external libraries. For crates from
759 [crates.io](https://crates.io), such libraries can be specified in
760 `defaultCrateOverrides` package in nixpkgs itself.
762 Starting from that file, one can add more overrides, to add features
763 or build inputs by overriding the hello crate in a separate file.
765 ```nix
766 with import <nixpkgs> {};
767 ((import ./hello.nix).hello {}).override {
768   crateOverrides = defaultCrateOverrides // {
769     hello = attrs: { buildInputs = [ openssl ]; };
770   };
774 Here, `crateOverrides` is expected to be a attribute set, where the
775 key is the crate name without version number and the value a function.
776 The function gets all attributes passed to `buildRustCrate` as first
777 argument and returns a set that contains all attribute that should be
778 overwritten.
780 For more complicated cases, such as when parts of the crate's
781 derivation depend on the crate's version, the `attrs` argument of
782 the override above can be read, as in the following example, which
783 patches the derivation:
785 ```nix
786 with import <nixpkgs> {};
787 ((import ./hello.nix).hello {}).override {
788   crateOverrides = defaultCrateOverrides // {
789     hello = attrs: lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0")  {
790       postPatch = ''
791         substituteInPlace lib/zoneinfo.rs \
792           --replace-fail "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo"
793       '';
794     };
795   };
799 Another situation is when we want to override a nested
800 dependency. This actually works in the exact same way, since the
801 `crateOverrides` parameter is forwarded to the crate's
802 dependencies. For instance, to override the build inputs for crate
803 `libc` in the example above, where `libc` is a dependency of the main
804 crate, we could do:
806 ```nix
807 with import <nixpkgs> {};
808 ((import hello.nix).hello {}).override {
809   crateOverrides = defaultCrateOverrides // {
810     libc = attrs: { buildInputs = []; };
811   };
815 ### Options and phases configuration {#options-and-phases-configuration}
817 Actually, the overrides introduced in the previous section are more
818 general. A number of other parameters can be overridden:
820 - The version of `rustc` used to compile the crate:
822   ```nix
823   (hello {}).override { rust = pkgs.rust; }
824   ```
826 - Whether to build in release mode or debug mode (release mode by
827   default):
829   ```nix
830   (hello {}).override { release = false; }
831   ```
833 - Whether to print the commands sent to `rustc` when building
834   (equivalent to `--verbose` in cargo:
836   ```nix
837   (hello {}).override { verbose = false; }
838   ```
840 - Extra arguments to be passed to `rustc`:
842   ```nix
843   (hello {}).override { extraRustcOpts = "-Z debuginfo=2"; }
844   ```
846 - Phases, just like in any other derivation, can be specified using
847   the following attributes: `preUnpack`, `postUnpack`, `prePatch`,
848   `patches`, `postPatch`, `preConfigure` (in the case of a Rust crate,
849   this is run before calling the "build" script), `postConfigure`
850   (after the "build" script),`preBuild`, `postBuild`, `preInstall` and
851   `postInstall`. As an example, here is how to create a new module
852   before running the build script:
854   ```nix
855   (hello {}).override {
856     preConfigure = ''
857        echo "pub const PATH=\"${hi.out}\";" >> src/path.rs"
858     '';
859   }
860   ```
862 ### Setting Up `nix-shell` {#setting-up-nix-shell}
864 Oftentimes you want to develop code from within `nix-shell`. Unfortunately
865 `buildRustCrate` does not support common `nix-shell` operations directly
866 (see [this issue](https://github.com/NixOS/nixpkgs/issues/37945))
867 so we will use `stdenv.mkDerivation` instead.
869 Using the example `hello` project above, we want to do the following:
871 - Have access to `cargo` and `rustc`
872 - Have the `openssl` library available to a crate through it's _normal_
873   compilation mechanism (`pkg-config`).
875 A typical `shell.nix` might look like:
877 ```nix
878 with import <nixpkgs> {};
880 stdenv.mkDerivation {
881   name = "rust-env";
882   nativeBuildInputs = [
883     rustc cargo
885     # Example Build-time Additional Dependencies
886     pkg-config
887   ];
888   buildInputs = [
889     # Example Run-time Additional Dependencies
890     openssl
891   ];
893   # Set Environment Variables
894   RUST_BACKTRACE = 1;
898 You should now be able to run the following:
900 ```ShellSession
901 $ nix-shell --pure
902 $ cargo build
903 $ cargo test
906 ## Using community maintained Rust toolchains {#using-community-maintained-rust-toolchains}
908 ::: {.note}
909 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.
910 To package things that require Rust nightly, `RUSTC_BOOTSTRAP = true;` can sometimes be used as a hack.
913 There are two community maintained approaches to Rust toolchain management:
914 - [oxalica's Rust overlay](https://github.com/oxalica/rust-overlay)
915 - [fenix](https://github.com/nix-community/fenix)
917 Despite their names, both projects provides a similar set of packages and overlays under different APIs.
919 Oxalica's overlay allows you to select a particular Rust version without you providing a hash or a flake input,
920 but comes with a larger git repository than fenix.
922 Fenix also provides rust-analyzer nightly in addition to the Rust toolchains.
924 Both oxalica's overlay and fenix better integrate with nix and cache optimizations.
925 Because of this and ergonomics, either of those community projects
926 should be preferred to the Mozilla's Rust overlay ([nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla)).
928 The following documentation demonstrates examples using fenix and oxalica's Rust overlay
929 with `nix-shell` and building derivations. More advanced usages like flake usage
930 are documented in their own repositories.
932 ### Using Rust nightly with `nix-shell` {#using-rust-nightly-with-nix-shell}
934 Here is a simple `shell.nix` that provides Rust nightly (default profile) using fenix:
936 ```nix
937 with import <nixpkgs> { };
939   fenix = callPackage
940     (fetchFromGitHub {
941       owner = "nix-community";
942       repo = "fenix";
943       # commit from: 2023-03-03
944       rev = "e2ea04982b892263c4d939f1cc3bf60a9c4deaa1";
945       hash = "sha256-AsOim1A8KKtMWIxG+lXh5Q4P2bhOZjoUhFWJ1EuZNNk=";
946     })
947     { };
949 mkShell {
950   name = "rust-env";
951   nativeBuildInputs = [
952     # Note: to use stable, just replace `default` with `stable`
953     fenix.default.toolchain
955     # Example Build-time Additional Dependencies
956     pkg-config
957   ];
958   buildInputs = [
959     # Example Run-time Additional Dependencies
960     openssl
961   ];
963   # Set Environment Variables
964   RUST_BACKTRACE = 1;
968 Save this to `shell.nix`, then run:
970 ```ShellSession
971 $ rustc --version
972 rustc 1.69.0-nightly (13471d3b2 2023-03-02)
975 To see that you are using nightly.
977 Oxalica's Rust overlay has more complete examples of `shell.nix` (and cross compilation) under its
978 [`examples` directory](https://github.com/oxalica/rust-overlay/tree/e53e8853aa7b0688bc270e9e6a681d22e01cf299/examples).
980 ### Using Rust nightly in a derivation with `buildRustPackage` {#using-rust-nightly-in-a-derivation-with-buildrustpackage}
982 You can also use Rust nightly to build rust packages using `makeRustPlatform`.
983 The below snippet demonstrates invoking `buildRustPackage` with a Rust toolchain from oxalica's overlay:
985 ```nix
986 with import <nixpkgs>
988   overlays = [
989     (import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
990   ];
993   rustPlatform = makeRustPlatform {
994     cargo = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
995     rustc = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
996   };
999 rustPlatform.buildRustPackage rec {
1000   pname = "ripgrep";
1001   version = "12.1.1";
1003   src = fetchFromGitHub {
1004     owner = "BurntSushi";
1005     repo = "ripgrep";
1006     rev = version;
1007     hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
1008   };
1010   cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
1012   doCheck = false;
1014   meta = {
1015     description = "Fast line-oriented regex search tool, similar to ag and ack";
1016     homepage = "https://github.com/BurntSushi/ripgrep";
1017     license = with lib.licenses; [ mit unlicense ];
1018     maintainers = with lib.maintainers; [];
1019   };
1023 Follow the below steps to try that snippet.
1024 1. save the above snippet as `default.nix` in that directory
1025 2. cd into that directory and run `nix-build`
1027 Fenix also has examples with `buildRustPackage`,
1028 [crane](https://github.com/ipetkov/crane),
1029 [naersk](https://github.com/nix-community/naersk),
1030 and cross compilation in its [Examples](https://github.com/nix-community/fenix#examples) section.
1032 ## Using `git bisect` on the Rust compiler {#using-git-bisect-on-the-rust-compiler}
1034 Sometimes an upgrade of the Rust compiler (`rustc`) will break a
1035 downstream package.  In these situations, being able to `git bisect`
1036 the `rustc` version history to find the offending commit is quite
1037 useful.  Nixpkgs makes it easy to do this.
1039 First, roll back your nixpkgs to a commit in which its `rustc` used
1040 *the most recent one which doesn't have the problem.*  You'll need
1041 to do this because of `rustc`'s extremely aggressive
1042 version-pinning.
1044 Next, add the following overlay, updating the Rust version to the
1045 one in your rolled-back nixpkgs, and replacing `/git/scratch/rust`
1046 with the path into which you have `git clone`d the `rustc` git
1047 repository:
1049 ```nix
1050  (final: prev: /*lib.optionalAttrs prev.stdenv.targetPlatform.isAarch64*/ {
1051    rust_1_72 =
1052      lib.updateManyAttrsByPath [{
1053        path = [ "packages" "stable" ];
1054        update = old: old.overrideScope(final: prev: {
1055          rustc-unwrapped = prev.rustc-unwrapped.overrideAttrs (_: {
1056            src = lib.cleanSource /git/scratch/rust;
1057            # do *not* put passthru.isReleaseTarball=true here
1058          });
1059        });
1060      }]
1061        prev.rust_1_72;
1062  })
1065 If the problem you're troubleshooting only manifests when
1066 cross-compiling you can uncomment the `lib.optionalAttrs` in the
1067 example above, and replace `isAarch64` with the target that is
1068 having problems.  This will speed up your bisect quite a bit, since
1069 the host compiler won't need to be rebuilt.
1071 Now, you can start a `git bisect` in the directory where you checked
1072 out the `rustc` source code.  It is recommended to select the
1073 endpoint commits by searching backwards from `origin/master` for the
1074 *commits which added the release notes for the versions in
1075 question.*  If you set the endpoints to commits on the release
1076 branches (i.e. the release tags), git-bisect will often get confused
1077 by the complex merge-commit structures it will need to traverse.
1079 The command loop you'll want to use for bisecting looks like this:
1081 ```bash
1082 git bisect {good,bad}  # depending on result of last build
1083 git submodule update --init
1084 CARGO_NET_OFFLINE=false cargo vendor \
1085   --sync ./src/tools/cargo/Cargo.toml \
1086   --sync ./src/tools/rust-analyzer/Cargo.toml \
1087   --sync ./compiler/rustc_codegen_cranelift/Cargo.toml \
1088   --sync ./src/bootstrap/Cargo.toml
1089 nix-build $NIXPKGS -A package-broken-by-rust-changes
1092 The `git submodule update --init` and `cargo vendor` commands above
1093 require network access, so they can't be performed from within the
1094 `rustc` derivation, unfortunately.