Home Explore Blog CI



nixpkgs

7th chunk of `doc/languages-frameworks/rust.section.md`
f3a47dbe5af5da55c10a0443557f5476b0495d4a80d9da670000000100000faf
directory of the `tokenizers` project's source archive, we use
`sourceRoot` to point the tooling to this directory:

```nix
{
  fetchFromGitHub,
  buildPythonPackage,
  cargo,
  rustPlatform,
  rustc,
  setuptools-rust,
}:

buildPythonPackage rec {
  pname = "tokenizers";
  version = "0.10.0";

  src = fetchFromGitHub {
    owner = "huggingface";
    repo = "tokenizers";
    tag = "python-v${version}";
    hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw=";
  };

  cargoDeps = rustPlatform.fetchCargoVendor {
    inherit
      pname
      version
      src
      sourceRoot
      ;
    hash = "sha256-RO1m8wEd5Ic2M9q+zFHeCJWhCr4Sv3CEWd08mkxsBec=";
  };

  sourceRoot = "${src.name}/bindings/python";

  nativeBuildInputs = [
    cargo
    rustPlatform.cargoSetupHook
    rustc
    setuptools-rust
  ];

  # ...
}
```

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 pass in `cargoRoot`
to `fetchCargoVendor`.

```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;
    hash = "sha256-xGDilsjLOnls3MfVbGKnj80KCUCczZxlis5PmHzpNcQ=";
  };

  cargoDeps = rustPlatform.fetchCargoVendor {
    inherit
      pname
      version
      src
      cargoRoot
      ;
    hash = "sha256-ctUt8maCjnGddKPf+Ii++wKsAXA1h+JM6zKQNXXwJqQ=";
  };

  cargoRoot = "src/rust";

  # ...
}
```

#### Python package using `maturin` {#python-package-using-maturin}

Python packages that use [Maturin](https://github.com/PyO3/maturin)
can be built with `fetchCargoVendor`, `cargoSetupHook`, and
`maturinBuildHook`. For example, the following (partial) derivation
builds the `retworkx` Python package. `fetchCargoVendor` 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";
  pyproject = true;

  src = fetchFromGitHub {
    owner = "Qiskit";
    repo = "retworkx";
    tag = version;
    hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
  };

  cargoDeps = rustPlatform.fetchCargoVendor {
    inherit pname version src;
    hash = "sha256-QsPCQhNZKYCAogQriQX6pBYQUDAIUsEdRX/63dAqTzg=";
  };

  nativeBuildInputs = with rustPlatform; [
    cargoSetupHook
    maturinBuildHook
  ];

  # ...
}
```

#### Rust package built with `meson` {#rust-package-built-with-meson}

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 `fetchCargoVendor` and `cargoSetupHook` and leave the rest to Meson. `rust` and `cargo` are still needed in `nativeBuildInputs` for Meson to use.

```nix
{
  lib,
  stdenv,
  fetchFromGitLab,
  meson,
  ninja,
  pkg-config,
  rustPlatform,
  rustc,
  cargo,
  wrapGAppsHook4,
  blueprint-compiler,
  libadwaita,
  libsecret,
  tinysparql,
}:

stdenv.mkDerivation (finalAttrs: {
  pname = "health";
  version = "0.95.0";

  src = fetchFromGitLab {
    domain = "gitlab.gnome.org";
    owner = "World";
    repo = "health";
    tag = finalAttrs.version;
    hash = "sha256-PrNPprSS98yN8b8yw2G6hzTSaoE65VbsM3q7FVB4mds=";
  };

  cargoDeps = rustPlatform.fetchCargoVendor {
    inherit (finalAttrs) pname version src;
    hash = "sha256-eR1ZGtTZQNhofFUEjI7IX16sMKPJmAl7aIFfPJukecg=";
  };

  nativeBuildInputs = [
    meson
    ninja
    pkg-config
    rustPlatform.cargoSetupHook

Title: More examples on integrating Rust in Non-Rust Packages
Summary
This section provides more examples of integrating Rust into non-Rust packages. First, it demonstrates using `cargoRoot` with `fetchCargoVendor` to specify the location of the Rust crate when it is not in the main source directory. Next, it shows how to build Python packages using `maturin` with `fetchCargoVendor`, `cargoSetupHook`, and `maturinBuildHook`. Finally, it describes building Rust packages with `meson`, where `fetchCargoVendor` and `cargoSetupHook` are used to set up Cargo dependencies and Meson handles the rest.