Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions docs/markdown/Rust-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ authors:
- name: Dylan Baker
email: dylan@pnwbakers.com
years: [2020, 2021, 2022, 2024]
- name: Paolo Bonzini
email: bonzini@gnu.org
years: [2025]
...

# Rust module
Expand Down Expand Up @@ -168,3 +171,117 @@ Only a subset of [[shared_library]] keyword arguments are allowed:
- link_depends
- link_with
- override_options

### workspace()

```meson
rustmod.workspace(...)
```

*Since 1.10.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.
If not specified and `features` is provided, defaults to true.
- `features`: (`list[str]`, optional) List of additional features to enable globally

The function must be called in a project with `Cargo.lock` and `Cargo.toml`
files in the root source directory. While the object currently has
no methods, upon its creation Meson analyzes the `Cargo.toml` file and
computes the full set of dependencies and features needed to build the
package in `Cargo.toml`. Therefore, this function should be invoked before
using Cargo subprojects.

If either argument is provided, the build will use a custom set of features.
Features can only be set once - subsequent calls will fail if different features
are specified.

When `features` is provided without `default_features: false`, the 'default' feature is
automatically included.

## Workspace object

### workspace.packages()

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

Returns a list of package names in the workspace.

### 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.

### subproject.name()

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

Returns the name of the subproject.

### subproject.version()

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

Returns the normalized version number of the subproject.

### subproject.api()

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

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

### subproject.features()

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

Returns selected features for a specific subproject.

### subproject.all_features()

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

Returns all defined features for a specific subproject.

### 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.
37 changes: 37 additions & 0 deletions docs/markdown/Rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,40 @@ target name. First, dashes, spaces and dots are replaced with underscores. Sec
*since 1.10.0* anything after the first `+` is dropped. This allows creating multiple
targets for the same crate name, for example when the same crate is built multiple
times with different features, or for both the build and the host machine.

## Cargo interaction

*Since 1.10.0*

In most cases, a Rust program will use Cargo to download crates. Meson is able
to build Rust library crates based on a `Cargo.toml` file; each external crate
corresponds to a subproject. Rust module's ` that do not need a `build.rs` file
need no intervention, whereas if a `build.rs` file is present it needs to be
converted manually to Meson code.

To enable automatic configuration of Cargo dependencies, your project must
have `Cargo.toml` and `Cargo.lock` files in the root source directory;
this enables proper feature resolution across crates. You can then
create a workspace object using the Rust module, and retrieve specific
packages from the workspace:

```meson
rust = import('rust')
cargo = rust.workspace()
anyhow_dep = ws.subproject('anyhow').dependency()
```

The workspace object also enables configuration of Cargo features, for example
from Meson options:

```meson
ws = rust.workspace(
features: ['feature1', 'feature2'])
```

### Limitations

All your own crates must be built using the usual Meson functions such as
[[static_library]] or [[executable]]. In the future, workspace object
functionality will be extended to help building rustc command lines
based on features, dependency names, and so on.
5 changes: 1 addition & 4 deletions docs/markdown/Wrap-dependency-system-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,7 @@ Since *1.5.0* Cargo wraps can also be provided with `Cargo.lock` file at the roo
of (sub)project source tree. Meson will automatically load that file and convert
it into a series of wraps definitions.

Since *1.10.0* Workspace Cargo.toml are supported. For the time being it is
recommended to regroup all Cargo dependencies inside a single workspace invoked
from the main Meson project. When invoking multiple different Cargo subprojects
from Meson, feature resolution of common dependencies might be wrong.
Since *1.10.0* Workspace Cargo.toml are supported.

## Using wrapped projects

Expand Down
13 changes: 13 additions & 0 deletions docs/markdown/snippets/cargo-workspace-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Cargo workspace object

Meson now is able to parse the toplevel `Cargo.toml` file of the
project when the `workspace()` method of the Rust module is called.
This guarantees that features are resolved according to what is
in the `Cargo.toml` file, and in fact enables configuration of
features for the build.

The returned object also allows retrieving features and dependencies
for Cargo subprojects.

While Cargo subprojects remain experimental, the Meson project will
try to keep the workspace object reasonably backwards-compatible.
2 changes: 1 addition & 1 deletion mesonbuild/ast/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def precedence_level(node: mparser.BaseNode) -> int:
return 6
elif isinstance(node, (mparser.NotNode, mparser.UMinusNode)):
return 7
elif isinstance(node, mparser.FunctionNode):
elif isinstance(node, (mparser.FunctionNode, mparser.IndexNode, mparser.MethodNode)):
return 8
elif isinstance(node, (mparser.ArrayNode, mparser.DictNode)):
return 9
Expand Down
4 changes: 3 additions & 1 deletion mesonbuild/cargo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
__all__ = [
'Interpreter',
'PackageState',
'TomlImplementationMissing',
'WorkspaceState',
]

from .interpreter import Interpreter
from .interpreter import Interpreter, PackageState, WorkspaceState
from .toml import TomlImplementationMissing
Loading
Loading