diff options
Diffstat (limited to 'doc/languages-frameworks')
-rw-r--r-- | doc/languages-frameworks/python.section.md | 2 | ||||
-rw-r--r-- | doc/languages-frameworks/rust.section.md | 194 |
2 files changed, 194 insertions, 2 deletions
diff --git a/doc/languages-frameworks/python.section.md b/doc/languages-frameworks/python.section.md index 71193ed0cc0..f36f5cf0cbb 100644 --- a/doc/languages-frameworks/python.section.md +++ b/doc/languages-frameworks/python.section.md @@ -611,7 +611,7 @@ Using the example above, the analagous pytestCheckHook usage would be: "update" ]; - disabledTestFiles = [ + disabledTestPaths = [ "tests/test_failing.py" ]; ``` diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 18d3cd9c926..94f94aaffe3 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -223,7 +223,7 @@ sometimes it may be necessary to disable this so the tests run consecutively. ```nix rustPlatform.buildRustPackage { /* ... */ - cargoParallelTestThreads = false; + dontUseCargoParallelTests = true; } ``` @@ -264,6 +264,198 @@ rustPlatform.buildRustPackage rec { } ``` +## 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 + +Since network access is not allowed in sandboxed builds, Rust crate +dependencies need to be retrieved using a fetcher. `rustPlatform` +provides the `fetchCargoTarball` fetcher, which vendors all +dependencies of a crate. For example, given a source path `src` +containing `Cargo.toml` and `Cargo.lock`, `fetchCargoTarball` +can be used as follows: + +```nix +cargoDeps = rustPlatform.fetchCargoTarball { + inherit src; + hash = "sha256-BoHIN/519Top1NUBjpB/oEMqi86Omt3zTQcXFWqrek0="; +}; +``` + +The `src` attribute is required, as well as a hash specified through +one of the `sha256` or `hash` attributes. The following optional +attributes can also be used: + +* `name`: the name that is used for the dependencies tarball. If + `name` is not specified, then the name `cargo-deps` will be used. +* `sourceRoot`: when the `Cargo.lock`/`Cargo.toml` are in a + subdirectory, `sourceRoot` specifies the relative path to these + files. +* `patches`: patches to apply before vendoring. This is useful when + the `Cargo.lock`/`Cargo.toml` files need to be patched before + vendoring. + +### Hooks + +`rustPlatform` provides the following hooks to automate Cargo builds: + +* `cargoSetupHook`: configure Cargo to use depenencies vendored + through `fetchCargoTarball`. This hook uses the `cargoDeps` + environment variable to find the vendored dependencies. If a project + already vendors its dependencies, the variable `cargoVendorDir` can + be used instead. When the `Cargo.toml`/`Cargo.lock` files are not in + `sourceRoot`, then the optional `cargoRoot` is used to specify the + Cargo root directory relative to `sourceRoot`. +* `cargoBuildHook`: use Cargo to build a crate. If the crate to be + built is a crate in e.g. a Cargo workspace, the relative path to the + crate to build can be set through the optional `buildAndTestSubdir` + environment variable. Additional Cargo build flags can be passed + through `cargoBuildFlags`. +* `maturinBuildHook`: use [Maturin](https://github.com/PyO3/maturin) + to build a Python wheel. Similar to `cargoBuildHook`, the optional + variable `buildAndTestSubdir` can be used to build a crate in a + Cargo workspace. Additional maturin flags can be passed through + `maturinBuildFlags`. +* `cargoCheckHook`: run tests using Cargo. Additional flags can be + passed to Cargo using `checkFlags` and `checkFlagsArray`. By + default, tests are run in parallel. This can be disabled by setting + `dontUseCargoParallelTests`. +* `cargoInstallHook`: install binaries and static/shared libraries + that were built using `cargoBuildHook`. + +### Examples + +#### Python package using `setuptools-rust` + +For Python packages using `setuptools-rust`, you can use +`fetchCargoTarball` and `cargoSetupHook` to retrieve and set up Cargo +dependencies. The build itself is then performed by +`buildPythonPackage`. + +The following example outlines how the `tokenizers` Python package is +built. Since the Python package is in the `source/bindings/python` +directory of the *tokenizers* project's source archive, we use +`sourceRoot` to point the tooling to this directory: + +```nix +{ fetchFromGitHub +, buildPythonPackage +, rustPlatform +, setuptools-rust +}: + +buildPythonPackage rec { + pname = "tokenizers"; + version = "0.10.0"; + + src = fetchFromGitHub { + owner = "huggingface"; + repo = pname; + rev = "python-v${version}"; + hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw="; + }; + + cargoDeps = rustPlatform.fetchCargoTarball { + inherit src sourceRoot; + name = "${pname}-${version}"; + hash = "sha256-BoHIN/519Top1NUBjpB/oEMqi86Omt3zTQcXFWqrek0="; + }; + + sourceRoot = "source/bindings/python"; + + nativeBuildInputs = [ setuptools-rust ] ++ (with rustPlatform; [ + cargoSetupHook + rust.cargo + rust.rustc + ]); + + # ... +} +``` + +In some projects, the Rust crate is not in the main Python source +directory. In such cases, the `cargoRoot` attribute can be used to +specify the crate's directory relative to `sourceRoot`. In the +following example, the crate is in `src/rust`, as specified in the +`cargoRoot` attribute. Note that we also need to specify the correct +path for `fetchCargoTarball`. + +```nix + +{ buildPythonPackage +, fetchPypi +, rustPlatform +, setuptools-rust +, openssl +}: + +buildPythonPackage rec { + pname = "cryptography"; + version = "3.4.2"; # Also update the hash in vectors.nix + + src = fetchPypi { + inherit pname version; + sha256 = "1i1mx5y9hkyfi9jrrkcw804hmkcglxi6rmf7vin7jfnbr2bf4q64"; + }; + + cargoDeps = rustPlatform.fetchCargoTarball { + inherit src; + sourceRoot = "${pname}-${version}/${cargoRoot}"; + name = "${pname}-${version}"; + hash = "sha256-PS562W4L1NimqDV2H0jl5vYhL08H9est/pbIxSdYVfo="; + }; + + cargoRoot = "src/rust"; + + # ... +} +``` + +#### Python package using `maturin` + +Python packages that use [Maturin](https://github.com/PyO3/maturin) +can be built with `fetchCargoTarball`, `cargoSetupHook`, and +`maturinBuildHook`. For example, the following (partial) derivation +builds the `retworkx` Python package. `fetchCargoTarball` and +`cargoSetupHook` are used to fetch and set up the crate dependencies. +`maturinBuildHook` is used to perform the build. + +```nix +{ lib +, buildPythonPackage +, rustPlatform +, fetchFromGitHub +}: + +buildPythonPackage rec { + pname = "retworkx"; + version = "0.6.0"; + + src = fetchFromGitHub { + owner = "Qiskit"; + repo = "retworkx"; + rev = version; + sha256 = "11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20"; + }; + + cargoDeps = rustPlatform.fetchCargoTarball { + inherit src; + name = "${pname}-${version}"; + hash = "sha256-heOBK8qi2nuc/Ib+I/vLzZ1fUUD/G/KTw9d7M4Hz5O0="; + }; + + format = "pyproject"; + + nativeBuildInputs = with rustPlatform; [ cargoSetupHook maturinBuildHook ]; + + # ... +} +``` + ## Compiling Rust crates using Nix instead of Cargo ### Simple operation |