3 To install the rust compiler and cargo put
7 environment.systemPackages = [
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`:
25 { lib, fetchFromGitHub, rustPlatform }:
27 rustPlatform.buildRustPackage rec {
31 src = fetchFromGitHub {
35 hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
38 cargoHash = "sha256-jtBw4ahSl88L0iuCXxQgZVm1EcboWRJMNtjxLVTtzts=";
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;
49 `buildRustPackage` requires a `cargoHash` attribute, computed over all crate sources of this package.
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>"`.
62 cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
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.
72 useFetchCargoVendor = true;
73 cargoHash = "sha256-RqPVFovDaD2rW31HyETJfQ0qVwFxoGEvqkIgag3H6KU=";
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:
88 cargoHash = lib.fakeHash;
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
113 rustPlatform.buildRustPackage rec {
118 inherit pname version;
119 hash = "sha256-aDQA4A5mScX9or3Lyiv/5GyAehidnpKKE0grhbP1Ctc=";
122 cargoHash = "sha256-tbrTbutUs5aPSV+yE0IBUZAAytgmZV7Eqxia7g+9zRs=";
123 cargoDepsName = pname;
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:
138 rustPlatform.buildRustPackage {
143 lockFile = ./Cargo.lock;
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:
159 rustPlatform.buildRustPackage {
164 fixupLockFile = path: f (builtins.readFile path);
166 lockFileContents = fixupLockFile ./Cargo.lock;
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:
181 ln -s ${./Cargo.lock} Cargo.lock
186 The output hash of each dependency that uses a git source must be
187 specified in the `outputHashes` attribute. For example:
190 rustPlatform.buildRustPackage rec {
195 lockFile = ./Cargo.lock;
197 "finalfusion-0.14.0" = "17f4bsdzpcshwh74w5z119xjy2if6l2wgyjy56v621skr2r8y904";
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:
215 rustPlatform.buildRustPackage rec {
220 lockFile = ./Cargo.lock;
221 allowBuiltinFetchGit = true;
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`.
241 rustPlatform.buildRustPackage rec {
245 buildNoDefaultFeatures = true;
246 buildFeatures = [ "color" "net" ];
248 # disable network features in tests
249 checkFeatures = [ "color" ];
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.
270 crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
271 rust.rustcTarget = "thumbv7em-none-eabi";
279 --target thumbv7em-none-eabi
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.
293 crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
294 rust.rustcTarget = "thumb-crazy";
295 rust.platform = { foo = ""; bar = ""; };
303 --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""}
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
321 rustPlatform.buildRustPackage {
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
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`:
364 rustPlatform.buildRustPackage {
367 # reason for disabling test
368 "--skip=example::tests:example_test"
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.
381 rustPlatform.buildRustPackage {
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.
393 rustPlatform.buildRustPackage {
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:
405 rustPlatform.buildRustPackage {
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.
427 rustPlatform.buildRustPackage rec {
430 # a patch file to add/update Cargo.lock in the source code
431 ./add-Cargo.lock.patch
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:
453 cargoDeps = rustPlatform.fetchCargoTarball {
455 hash = "sha256-BoHIN/519Top1NUBjpB/oEMqi86Omt3zTQcXFWqrek0=";
460 The `src` attribute is required, as well as a hash specified through
461 one of the `hash` attribute. The following optional attributes can
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
469 * `patches`: patches to apply before vendoring. This is useful when
470 the `Cargo.lock`/`Cargo.toml` files need to be patched before
473 In case the lockfile contains cargo `git` dependencies, you can use
474 `fetchCargoVendor` instead.
477 cargoDeps = rustPlatform.fetchCargoVendor {
479 hash = "sha256-RqPVFovDaD2rW31HyETJfQ0qVwFxoGEvqkIgag3H6KU=";
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:
492 cargoDeps = rustPlatform.importCargoLock {
493 lockFile = ./Cargo.lock;
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:
504 cargoDeps = rustPlatform.importCargoLock {
505 lockFile = ./Cargo.lock;
507 "rand-0.8.3" = "0ya2hia3cn31qa8894s3av2s8j5bjwb6yq92k0jsnlx7jid0jwqa";
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.
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
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:
578 buildPythonPackage rec {
579 pname = "tokenizers";
582 src = fetchFromGitHub {
583 owner = "huggingface";
585 rev = "python-v${version}";
586 hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw=";
589 cargoDeps = rustPlatform.fetchCargoTarball {
590 inherit pname version src sourceRoot;
591 hash = "sha256-miW//pnOmww2i6SOGbkrAIdc/JMDT4FJLqdMFojZeoY=";
594 sourceRoot = "${src.name}/bindings/python";
596 nativeBuildInputs = [
598 rustPlatform.cargoSetupHook
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`.
623 buildPythonPackage rec {
624 pname = "cryptography";
625 version = "3.4.2"; # Also update the hash in vectors.nix
628 inherit pname version;
629 hash = "sha256-xGDilsjLOnls3MfVbGKnj80KCUCczZxlis5PmHzpNcQ=";
632 cargoDeps = rustPlatform.fetchCargoTarball {
633 inherit pname version src;
634 sourceRoot = "${pname}-${version}/${cargoRoot}";
635 hash = "sha256-PS562W4L1NimqDV2H0jl5vYhL08H9est/pbIxSdYVfo=";
638 cargoRoot = "src/rust";
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.
660 buildPythonPackage rec {
665 src = fetchFromGitHub {
669 hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
672 cargoDeps = rustPlatform.fetchCargoTarball {
673 inherit pname version src;
674 hash = "sha256-heOBK8qi2nuc/Ib+I/vLzZ1fUUD/G/KTw9d7M4Hz5O0=";
677 nativeBuildInputs = with rustPlatform; [ cargoSetupHook maturinBuildHook ];
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.
704 stdenv.mkDerivation rec {
708 src = fetchFromGitLab {
709 domain = "gitlab.gnome.org";
713 hash = "sha256-PrNPprSS98yN8b8yw2G6hzTSaoE65VbsM3q7FVB4mds=";
716 cargoDeps = rustPlatform.fetchCargoTarball {
717 inherit pname version src;
718 hash = "sha256-8fa3fa+sFi5H+49B5sr2vYPkp9C9s6CcE0zv4xB8gww=";
721 nativeBuildInputs = [
725 rustPlatform.cargoSetupHook
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.
766 with import <nixpkgs> {};
767 ((import ./hello.nix).hello {}).override {
768 crateOverrides = defaultCrateOverrides // {
769 hello = attrs: { buildInputs = [ openssl ]; };
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
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:
786 with import <nixpkgs> {};
787 ((import ./hello.nix).hello {}).override {
788 crateOverrides = defaultCrateOverrides // {
789 hello = attrs: lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0") {
791 substituteInPlace lib/zoneinfo.rs \
792 --replace-fail "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo"
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
807 with import <nixpkgs> {};
808 ((import hello.nix).hello {}).override {
809 crateOverrides = defaultCrateOverrides // {
810 libc = attrs: { buildInputs = []; };
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:
823 (hello {}).override { rust = pkgs.rust; }
826 - Whether to build in release mode or debug mode (release mode by
830 (hello {}).override { release = false; }
833 - Whether to print the commands sent to `rustc` when building
834 (equivalent to `--verbose` in cargo:
837 (hello {}).override { verbose = false; }
840 - Extra arguments to be passed to `rustc`:
843 (hello {}).override { extraRustcOpts = "-Z debuginfo=2"; }
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:
855 (hello {}).override {
857 echo "pub const PATH=\"${hi.out}\";" >> src/path.rs"
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:
878 with import <nixpkgs> {};
880 stdenv.mkDerivation {
882 nativeBuildInputs = [
885 # Example Build-time Additional Dependencies
889 # Example Run-time Additional Dependencies
893 # Set Environment Variables
898 You should now be able to run the following:
906 ## Using community maintained Rust toolchains {#using-community-maintained-rust-toolchains}
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:
937 with import <nixpkgs> { };
941 owner = "nix-community";
943 # commit from: 2023-03-03
944 rev = "e2ea04982b892263c4d939f1cc3bf60a9c4deaa1";
945 hash = "sha256-AsOim1A8KKtMWIxG+lXh5Q4P2bhOZjoUhFWJ1EuZNNk=";
951 nativeBuildInputs = [
952 # Note: to use stable, just replace `default` with `stable`
953 fenix.default.toolchain
955 # Example Build-time Additional Dependencies
959 # Example Run-time Additional Dependencies
963 # Set Environment Variables
968 Save this to `shell.nix`, then run:
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:
986 with import <nixpkgs>
989 (import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
993 rustPlatform = makeRustPlatform {
994 cargo = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
995 rustc = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
999 rustPlatform.buildRustPackage rec {
1003 src = fetchFromGitHub {
1004 owner = "BurntSushi";
1007 hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
1010 cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
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; [];
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
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
1050 (final: prev: /*lib.optionalAttrs prev.stdenv.targetPlatform.isAarch64*/ {
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
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:
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.