---
short-description: Rust language integration module
authors:
    - name: Dylan Baker
      email: dylan@pnwbakers.com
      years: [2020, 2021, 2022, 2024]
    - name: Paolo Bonzini
      email: bonzini@gnu.org
      years: [2025]
...

# Rust module

*(new in 0.57.0)*
*(Stable since 1.0.0)*

The rust module provides helper to integrate rust code into Meson. The
goal is to make using rust in Meson more pleasant, while still
remaining mesonic. Rust conventions are adopted in order to help the
Meson user and Rust developer, rather than to make Meson work more like rust.

## Functions

### test()

```meson
rustmod.test(name, target, ...)
```

This function creates a new rust unittest target from an existing rust
based target, which may be a library or executable. It does this by
copying the sources and arguments passed to the original target and
adding the `--test` argument to the compilation, then creates a new
test target which calls that executable, using the rust test protocol.

This function takes two positional arguments, the first is the name of the
test and the second is the library or executable that is the rust based target.
It also takes the following keyword arguments:

- `dependencies`: a list of test-only Dependencies
- `link_with`: a list of additional build Targets to link with (*since 1.2.0*)
- `link_whole`: a list of additional build Targets to link with in their entirety (*since 1.8.0*)
- `rust_args`: a list of extra arguments passed to the Rust compiler (*since 1.2.0*)

This function  also accepts all of the keyword arguments accepted by the
[[test]] function except `protocol`, it will set that automatically.

### doctest()

```meson
rustmod.doctest(name, target, ...)
```

*Since 1.8.0*

This function creates a new `test()` target from an existing rust
based library target. The test will use `rustdoc` to extract and run
the doctests that are included in `target`'s sources.

This function takes two positional arguments, the first is the name of the
test and the second is the library or executable that is the rust based target.
It also takes the following keyword arguments:

- `dependencies`: a list of test-only Dependencies
- `link_with`: a list of additional build Targets to link with
- `link_whole`: a list of additional build Targets to link with in their entirety
- `rust_args`: a list of extra arguments passed to the Rust compiler

The target is linked automatically into the doctests.

This function  also accepts all of the keyword arguments accepted by the
[[test]] function except `protocol`, it will set that automatically.
However, arguments are limited to strings that do not contain spaces
due to limitations of `rustdoc`.

### bindgen()

This function wraps bindgen to simplify creating rust bindings around C
libraries. This has two advantages over invoking bindgen with a
`generator` or `custom_target`:

- It handles `include_directories`, so one doesn't have to manually convert them to `-I...`
- It automatically sets up a depfile, making the results more reliable
- It automatically handles assertions, synchronizing Rust and C/C++ to have the same behavior


It takes the following keyword arguments

- `input`: a list of Files, Strings, or CustomTargets. The first element is
  the header bindgen will parse, additional elements are dependencies.
- `output`: the name of the output rust file
- `output_inline_wrapper`: the name of the optional output c file containing
  wrappers for static inline function. This requires `bindgen-0.65` or
  newer (*since 1.3.0*).
- `include_directories`: A list of `include_directories` or `string` objects,
  these are passed to clang as `-I` arguments *(string since 1.0.0)*
- `c_args`: a list of string arguments to pass to clang untouched
- `args`: a list of string arguments to pass to `bindgen` untouched.
- `dependencies`: a list of `Dependency` objects to pass to the underlying clang call (*since 1.0.0*)
- `language`: A literal string value of `c` or `cpp`. When set this will force bindgen to treat a source as the given language. Defaults to checking based on the input file extension. *(since 1.4.0)*
- `bindgen_version`: a list of string version values. When set the found bindgen binary must conform to these constraints. *(since 1.4.0)*

```meson
rust = import('unstable-rust')

inc = include_directories('..'¸ '../../foo')

generated = rust.bindgen(
    input : 'myheader.h',
    output : 'generated.rs',
    include_directories : [inc, include_directories('foo')],
    args : ['--no-rustfmt-bindings'],
    c_args : ['-DFOO=1'],
)
```

If the header depends on generated headers, those headers must be passed to
`bindgen` as well to ensure proper dependency ordering, static headers do not
need to be passed, as a proper depfile is generated:

```meson
h1 = custom_target(...)
h2 = custom_target(...)

r1 = rust.bindgen(
  input : [h1, h2],  # h1 includes h2,
  output : 'out.rs',
)
```

*Since 1.1.0* Meson will synchronize assertions for Rust and C/C++  when the
`b_ndebug` option is set (via `-DNDEBUG` for C/C++, and `-C
debug-assertions=on` for Rust), and will pass `-DNDEBUG` as an extra argument
to clang. This allows for reliable wrapping of `-DNDEBUG` controlled behavior
with `#[cfg(debug_asserions)]` and or `cfg!()`. Before 1.1.0, assertions for Rust
were never turned on by Meson.

*Since 1.2.0* Additional arguments to pass to clang may be specified in a
*machine file in the properties section:

```ini
[properties]
bindgen_clang_arguments = ['--target', 'x86_64-linux-gnu']
```

### compiler_target()

*Since 1.11.0*

```meson
rustmod.compiler_target()
rustmod.compiler_target(native: true)
```

Returns the Rust target triple (e.g. `x86_64-unknown-linux-gnu`) for the
Rust compiler.  By default, or with `native: false`, this returns the
target for the host machine.  If `native: true` is passed, it returns
the target for the build machine instead.

This is useful when converting build scripts to Meson, because it
matches the value of Cargo's `TARGET` and `HOST` environment variables.

### proc_macro()

```meson
rustmod.proc_macro(name, sources, ...)
```

*Since 1.3.0*

This function creates a Rust `proc-macro` crate, similar to:
```meson
[[shared_library]](name, sources,
  rust_crate_type: 'proc-macro',
  native: true)
```

`proc-macro` targets can be passed to `link_with` keyword argument of other Rust
targets.

Only a subset of [[shared_library]] keyword arguments are allowed:
- rust_args
- rust_dependency_map
- sources
- dependencies
- extra_files
- link_args
- link_depends
- link_with
- override_options

### to_system_dependency()

*Since 1.11.0*

```meson
rustmod.to_system_dependency(dep[, name])
```

Create and return an internal dependency that wraps `dep` and
defines `cfg(system_deps_have_NAME)`.  This is compatible with
how the `system-deps` crate reports the availability of a system
dependency to Rust code.

If omitted, the name defaults to the name of the dependency.

### workspace()

Basic usage:

```
cargo_ws = rustmod.workspace()
```

With custom features:

```
feature_list = get_feature('f1') ? ['feature1'] : []
feature_list += get_feature('f2') ? ['feature2'] : []
cargo_ws = rustmod.workspace(features: feature_list)
```

*Since 1.11.0*

Create and return a `workspace` object for managing the project's Cargo
workspace.

Keyword arguments:
- `default_features`: (`bool`, optional) Whether to enable default features.
- `features`: (`array[str]`, optional) List of additional features to enable globally.

A project that wishes to use Cargo subprojects should have `Cargo.lock` and `Cargo.toml`
files in the root source directory, and should call this function before using
Cargo subprojects.

The first invocation of `workspace()` establishes the *Cargo interpreter*
that resolves dependencies and features for both the toplevel project (the one
containing `Cargo.lock`) and all subprojects that are invoked with the `cargo` method,

You can optionally customize the feature set, by providing `default_features`
and `features` when the Cargo interpreter is established.  If any of these
arguments is not specified, `default_features` is taken as `true` and
`features` as the empty list.

Once established, the Cargo interpreter's configuration is locked. Later calls to
`workspace()` must either omit all arguments (accepting the existing configuration)
or provide the same set of features as the first call. Mismatched arguments will cause
a build error.

The recommendation is to not specify any keyword arguments in a subproject, so
that they simply inherit the parent's configuration.  Be careful about the
difference between specifying arguments and not doing so:

```
# always works regardless of parent configuration
cargo_ws = rustmod.workspace()

# fails if parent configured different features
cargo_ws = rustmod.workspace(default_features: true)
cargo_ws = rustmod.workspace(features: [])
```

The first form says "use whatever features are configured," while the latter forms
say "require this specific configuration," which may conflict with the parent project.

## Workspace object

### workspace.packages()

```meson
packages = ws.packages()
```

Returns a list of package names in the workspace.

### workspace.package()

```meson
pkg = ws.package([package_name])
```

Returns a package object for the given package member.  If empty, returns
the object for the root package.

Arguments:
- `package_name`: (str, optional) Name of the package; not needed for the
  root package of a workspace

Example usage:
```meson
rustmod = import('rust')
cargo_ws = rustmod.workspace()
pkg = cargo_ws.package()
pkg.executable(install: true)
```

### workspace.subproject()

```meson
package = ws.subproject(package_name, api)
```

Returns a `package` object for managing a specific package within the workspace.

Positional arguments:
- `package_name`: (`str`) The name of the package to retrieve
- `api`: (`str`, optional) The version constraints for the package in Cargo format

## Package object

The package object returned by `workspace.subproject()` provides methods
for working with individual packages in a Cargo workspace.

### package.name(), subproject.name()

```meson
name = pkg.name()
```

Returns the name of a package or subproject.

### package.version(), subproject.version()

```meson
version = pkg.version()
```

Returns the normalized version number of the subproject.

### package.api(), subproject.api()

```meson
api = pkg.api()
```

Returns the API version of the subproject, that is the version up to the first
nonzero element.

### package.features(), subproject.features()

```meson
features = pkg.features()
```

Returns selected features for a specific package or subproject.

### package.all_features(), subproject.all_features()

```meson
all_features = pkg.all_features()
```

Returns all defined features for a specific package or subproject.

### Packages only

Package objects are able to extract information from `Cargo.toml` files,
and provide methods to query how Cargo would build this package.  They
also contain convenience wrappers for non-Rust-specific functions
(`executable`, `library`, `meson.override_dependency`, etc.), that
automatically add dependencies and compiler arguments from `Cargo.toml`
information.

#### package.rust_args()

```meson
args = pkg.rustc_args()
```

Returns rustc arguments for this package.

#### package.env()

```meson
env_vars = pkg.env()
```

Returns environment variables for this package.

#### package.rust_dependency_map()

```meson
dep_map = pkg.rust_dependency_map()
```

Returns rust dependency mapping for this package.

#### package.dependencies()

```meson
deps = pkg.dependencies(...)
```

Returns a list of dependency objects for all the dependencies required by this
Rust package, including both Rust crate dependencies and system dependencies.
The returned dependencies can be used directly in build target declarations.

Keyword arguments:
- `dependencies`: (`bool`, default: true) Whether to include regular Rust crate dependencies
- `dev_dependencies`: (`bool`, default: false) Whether to include development dependencies (not yet implemented)
- `system_dependencies`: (`bool`, default: true) Whether to include system dependencies

#### package.library()

```meson
lib = pkg.library(...)
```

Builds library targets for a workspace package.  The method requires that
the package's `Cargo.toml` file contains the `[lib]` section or that it
is discovered from the contents of the file system.  Static vs. shared library is
decided based on the crate types in `Cargo.toml`

Positional arguments:
- `target_name`: (`str`, optional) Name of the binary target to build.
- `sources`: (`StructuredSources`, optional) Source files for the executable.  If omitted,
  uses the path specified in the `[lib]` section of `Cargo.toml`.

Accepts all keyword arguments from [[shared_library]] and [[static_library]].
`rust_abi` must match the crate types and is mandatory if more than one
ABI is exposed by the crate.

#### package.shared_module()

```meson
lib = pkg.shared_module(...)
```

Builds the `cdylib` for a workspace package as a shared module.

Accepts all keyword arguments from [[shared_module]].

#### package.proc_macro()

```meson
lib = pkg.proc_macro(...)
```

Builds a proc-macro crate for a workspace package.

Accepts all keyword arguments from [[shared_library]].

#### package.override_dependency()

```meson
pkg.override_dependency(dep[, rust_abi: abi])
```

Keyword arguments:
- `rust_abi`: (`str`, optional) The ABI to use for the dependency. Valid values are
  `'rust'`, `'c'`, or `'proc-macro'`; the value must match the crate types and is
  mandatory if more than one ABI is exposed by the crate.

Make the crate available as a dependency to other crates.  This is the same
as calling `meson.override_dependency`, but it computes the correct dependency
name from `pkg`'s name, API version and ABI (Rust vs. C).

It is typically used with `library() or `proc_macro()`, for example:

```meson
lib_pkg = cargo_ws.package('myproject-lib')
lib = lib_pkg.library(install: false)
lib_pkg.override_dependency(declare_dependency(link_with: lib))

# Declares myproject-lib as a dependency in Cargo.toml
exe_pkg = cargo_ws.package()
exe_pkg.executable(install: true)
```

#### package.executable()

```meson
exe = pkg.executable([target_name], [sources], ...)
```

Builds an executable target for a workspace package.  The method requires that the
package has at least one `bin` section defined in its `Cargo.toml` file,
or one binary discovered from the contents of the file system.

Positional arguments:
- `target_name`: (`str`, optional) Name of the binary target to build. If the package
  has multiple `bin` sections in `Cargo.toml`, this argument is required and must
  match one of the binary names. If omitted and there's only one binary, that binary
  will be built automatically.
- `sources`: (`StructuredSources`, optional) Source files for the executable.  If omitted,
  uses the path specified in the corresponding `bin` section of `Cargo.toml`.

Accepts all keyword arguments from [[executable]].

### Subprojects only

#### subproject.dependency()

```meson
dep = subproject.dependency(...)
```

Returns a dependency object for the subproject that can be used with other Meson targets.

*Note*: right now, this method is implemented on top of the normal Meson function
[[dependency]]; this is subject to change in future releases.  It is recommended
to always retrieve a Cargo subproject's dependency object via this method.

Keyword arguments:
- `rust_abi`: (`str`, optional) The ABI to use for the dependency. Valid values are
  `'rust'`, `'c'`, or `'proc-macro'`. The package must support the specified ABI.
