Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at domenkozar-patch-1 833 lines 26 kB view raw view rendered
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.