diff options
Diffstat (limited to 'doc/languages-frameworks/rust.section.md')
-rw-r--r-- | doc/languages-frameworks/rust.section.md | 102 |
1 files changed, 59 insertions, 43 deletions
diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 5ff7a5edefd..f5c664bec20 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -15,7 +15,7 @@ For other versions such as daily builds (beta and nightly), use either `rustup` from nixpkgs (which will manage the rust installation in your home directory), or use Mozilla's [Rust nightlies overlay](#using-the-rust-nightlies-overlay). -## Compiling Rust applications with Cargo +## Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo} Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`: @@ -107,7 +107,7 @@ rustPlatform.buildRustPackage rec { } ``` -### Importing a `Cargo.lock` file +### Importing a `Cargo.lock` file {#importing-a-cargo.lock-file} Using `cargoSha256` or `cargoHash` is tedious when using `buildRustPackage` within a project, since it requires that the hash @@ -156,7 +156,7 @@ added. To find the correct hash, you can first use `lib.fakeSha256` or `lib.fakeHash` as a stub hash. Building the package (and thus the vendored dependencies) will then inform you of the correct hash. -### Cross compilation +### Cross compilation {#cross-compilation} By default, Rust packages are compiled for the host platform, just like any other package is. The `--target` passed to rust tools is computed from this. @@ -168,6 +168,7 @@ where they are known to differ. But there are ways to customize the argument: name will be used instead. For example: + ```nix import <nixpkgs> { crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // { @@ -175,7 +176,9 @@ where they are known to differ. But there are ways to customize the argument: }; } ``` + will result in: + ```shell --target thumbv7em-none-eabi ``` @@ -188,6 +191,7 @@ where they are known to differ. But there are ways to customize the argument: will be used instead. For example: + ```nix import <nixpkgs> { crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // { @@ -196,7 +200,9 @@ where they are known to differ. But there are ways to customize the argument: }; } ``` + will result in: + ```shell --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""} ``` @@ -220,7 +226,7 @@ ad-hoc escape hatch to `buildRustPackage` can be removed. Note that currently custom targets aren't compiled with `std`, so `cargo test` will fail. This can be ignored by adding `doCheck = false;` to your derivation. -### Running package tests +### Running package tests {#running-package-tests} When using `buildRustPackage`, the `checkPhase` is enabled by default and runs `cargo test` on the package to build. To make sure that we don't compile the @@ -248,7 +254,7 @@ Another attribute, called `checkFlags`, is used to pass arguments to the test binary itself, as stated (here)[https://doc.rust-lang.org/cargo/commands/cargo-test.html]. -#### Tests relying on the structure of the `target/` directory +#### Tests relying on the structure of the `target/` directory {#tests-relying-on-the-structure-of-the-target-directory} Some tests may rely on the structure of the `target/` directory. Those tests are likely to fail because we use `cargo --target` during the build. This means that @@ -258,7 +264,7 @@ rather than in `target/release/`. This can only be worked around by patching the affected tests accordingly. -#### Disabling package-tests +#### Disabling package-tests {#disabling-package-tests} In some instances, it may be necessary to disable testing altogether (with `doCheck = false;`): @@ -272,7 +278,7 @@ The above are just guidelines, and exceptions may be granted on a case-by-case b However, please check if it's possible to disable a problematic subset of the test suite and leave a comment explaining your reasoning. -#### Setting `test-threads` +#### Setting `test-threads` {#setting-test-threads} `buildRustPackage` will use parallel test threads by default, sometimes it may be necessary to disable this so the tests run consecutively. @@ -284,7 +290,7 @@ rustPlatform.buildRustPackage { } ``` -### Building a package in `debug` mode +### Building a package in `debug` mode {#building-a-package-in-debug-mode} By default, `buildRustPackage` will use `release` mode for builds. If a package should be built in `debug` mode, it can be configured like so: @@ -298,14 +304,14 @@ rustPlatform.buildRustPackage { In this scenario, the `checkPhase` will be ran in `debug` mode as well. -### Custom `build`/`install`-procedures +### Custom `build`/`install`-procedures {#custom-buildinstall-procedures} Some packages may use custom scripts for building/installing, e.g. with a `Makefile`. In these cases, it's recommended to override the `buildPhase`/`installPhase`/`checkPhase`. Otherwise, some steps may fail because of the modified directory structure of `target/`. -### 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 {#building-a-crate-with-an-absent-or-out-of-date-cargo.lock-file} `buildRustPackage` needs a `Cargo.lock` file to get all dependencies in the source code in a reproducible way. If it is missing or out-of-date one can use @@ -321,13 +327,13 @@ rustPlatform.buildRustPackage rec { } ``` -## Compiling non-Rust packages that include Rust code +## Compiling non-Rust packages that include Rust code {#compiling-non-rust-packages-that-include-rust-code} Several non-Rust packages incorporate Rust code for performance- or security-sensitive parts. `rustPlatform` exposes several functions and hooks that can be used to integrate Cargo in non-Rust packages. -### Vendoring of dependencies +### Vendoring of dependencies {#vendoring-of-dependencies} Since network access is not allowed in sandboxed builds, Rust crate dependencies need to be retrieved using a fetcher. `rustPlatform` @@ -387,7 +393,7 @@ added. To find the correct hash, you can first use `lib.fakeSha256` or `lib.fakeHash` as a stub hash. Building `cargoDeps` will then inform you of the correct hash. -### Hooks +### Hooks {#hooks} `rustPlatform` provides the following hooks to automate Cargo builds: @@ -416,9 +422,9 @@ you of the correct hash. * `cargoInstallHook`: install binaries and static/shared libraries that were built using `cargoBuildHook`. -### Examples +### Examples {#examples} -#### Python package using `setuptools-rust` +#### Python package using `setuptools-rust` {#python-package-using-setuptools-rust} For Python packages using `setuptools-rust`, you can use `fetchCargoTarball` and `cargoSetupHook` to retrieve and set up Cargo @@ -504,7 +510,7 @@ buildPythonPackage rec { } ``` -#### Python package using `maturin` +#### Python package using `maturin` {#python-package-using-maturin} Python packages that use [Maturin](https://github.com/PyO3/maturin) can be built with `fetchCargoTarball`, `cargoSetupHook`, and @@ -545,9 +551,9 @@ buildPythonPackage rec { } ``` -## Compiling Rust crates using Nix instead of Cargo +## Compiling Rust crates using Nix instead of Cargo {#compiling-rust-crates-using-nix-instead-of-cargo} -### Simple operation +### Simple operation {#simple-operation} When run, `cargo build` produces a file called `Cargo.lock`, containing pinned versions of all dependencies. Nixpkgs contains a @@ -558,14 +564,15 @@ That Nix expression calls `rustc` directly (hence bypassing Cargo), and can be used to compile a crate and all its dependencies. Here is an example for a minimal `hello` crate: - - $ cargo new hello - $ cd hello - $ cargo build +```ShellSession +$ cargo new hello +$ cd hello +$ cargo build Compiling hello v0.1.0 (file:///tmp/hello) - Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs - $ carnix -o hello.nix --src ./. Cargo.lock --standalone - $ nix-build hello.nix -A hello_0_1_0 + Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs +$ carnix -o hello.nix --src ./. Cargo.lock --standalone +$ nix-build hello.nix -A hello_0_1_0 +``` Now, the file produced by the call to `carnix`, called `hello.nix`, looks like: @@ -644,7 +651,7 @@ Here, the `libc` crate has no `src` attribute, so `buildRustCrate` will fetch it from [crates.io](https://crates.io). A `sha256` attribute is still needed for Nix purity. -### Handling external dependencies +### Handling external dependencies {#handling-external-dependencies} Some crates require external libraries. For crates from [crates.io](https://crates.io), such libraries can be specified in @@ -703,7 +710,7 @@ with import <nixpkgs> {}; } ``` -### Options and phases configuration +### Options and phases configuration {#options-and-phases-configuration} Actually, the overrides introduced in the previous section are more general. A number of other parameters can be overridden: @@ -750,7 +757,7 @@ general. A number of other parameters can be overridden: }; ``` -### Features +### Features {#features} One can also supply features switches. For example, if we want to compile `diesel_cli` only with the `postgres` feature, and no default @@ -765,14 +772,15 @@ features, we would write: Where `diesel.nix` is the file generated by Carnix, as explained above. +## Setting Up `nix-shell` {#setting-up-nix-shell} -## Setting Up `nix-shell` Oftentimes you want to develop code from within `nix-shell`. Unfortunately `buildRustCrate` does not support common `nix-shell` operations directly (see [this issue](https://github.com/NixOS/nixpkgs/issues/37945)) so we will use `stdenv.mkDerivation` instead. Using the example `hello` project above, we want to do the following: + - Have access to `cargo` and `rustc` - Have the `openssl` library available to a crate through it's _normal_ compilation mechanism (`pkg-config`). @@ -801,13 +809,15 @@ stdenv.mkDerivation { ``` You should now be able to run the following: -```ShellSesssion + +```ShellSession $ nix-shell --pure $ cargo build $ cargo test ``` -### Controlling Rust Version Inside `nix-shell` +### Controlling Rust Version Inside `nix-shell` {#controlling-rust-version-inside-nix-shell} + To control your rust version (i.e. use nightly) from within `shell.nix` (or other nix expressions) you can use the following `shell.nix` @@ -839,6 +849,7 @@ stdenv.mkDerivation { ``` Now run: + ```ShellSession $ rustc --version rustc 1.26.0-nightly (188e693b3 2018-03-26) @@ -846,31 +857,32 @@ rustc 1.26.0-nightly (188e693b3 2018-03-26) To see that you are using nightly. - -## Using the Rust nightlies overlay +## Using the Rust nightlies overlay {#using-the-rust-nightlies-overlay} Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope. This overlay can _also_ be used to install recent unstable or stable versions of Rust, if desired. -### Rust overlay installation +### Rust overlay installation {#rust-overlay-installation} You can use this overlay by either changing your local nixpkgs configuration, or by adding the overlay declaratively in a nix expression, e.g. in `configuration.nix`. -For more information see [#sec-overlays-install](the manual on installing overlays). +For more information see [the manual on installing overlays](#sec-overlays-install). -#### Imperative rust overlay installation +#### Imperative rust overlay installation {#imperative-rust-overlay-installation} Clone [nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla), and create a symbolic link to the file [rust-overlay.nix](https://github.com/mozilla/nixpkgs-mozilla/blob/master/rust-overlay.nix) in the `~/.config/nixpkgs/overlays` directory. - $ git clone https://github.com/mozilla/nixpkgs-mozilla.git - $ mkdir -p ~/.config/nixpkgs/overlays - $ ln -s $(pwd)/nixpkgs-mozilla/rust-overlay.nix ~/.config/nixpkgs/overlays/rust-overlay.nix +```ShellSession +$ git clone https://github.com/mozilla/nixpkgs-mozilla.git +$ mkdir -p ~/.config/nixpkgs/overlays +$ ln -s $(pwd)/nixpkgs-mozilla/rust-overlay.nix ~/.config/nixpkgs/overlays/rust-overlay.nix +``` -### Declarative rust overlay installation +### Declarative rust overlay installation {#declarative-rust-overlay-installation} Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.nix`, or similar: @@ -886,7 +898,7 @@ Add the following to your `configuration.nix`, `home-configuration.nix`, `shell. Note that this will fetch the latest overlay version when rebuilding your system. -### Rust overlay usage +### Rust overlay usage {#rust-overlay-usage} The overlay contains attribute sets corresponding to different versions of the rust toolchain, such as: @@ -900,11 +912,15 @@ For example, you might want to add `latest.rustChannels.stable.rust` to the list Imperatively, the latest stable version can be installed with the following command: - $ nix-env -Ai nixpkgs.latest.rustChannels.stable.rust +```ShellSession +$ nix-env -Ai nixpkgs.latest.rustChannels.stable.rust +``` Or using the attribute with nix-shell: - $ nix-shell -p nixpkgs.latest.rustChannels.stable.rust +```ShellSession +$ nix-shell -p nixpkgs.latest.rustChannels.stable.rust +``` Substitute the `nixpkgs` prefix with `nixos` on NixOS. To install the beta or nightly channel, "stable" should be substituted by |