summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Wrap-dependency-system-manual.md41
-rw-r--r--docs/markdown/snippets/cargo_dep_name.md19
-rw-r--r--mesonbuild/cargo/interpreter.py40
-rw-r--r--test cases/rust/22 cargo subproject/meson.build2
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs.wrap (renamed from test cases/rust/22 cargo subproject/subprojects/bar-rs.wrap)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs/Cargo.toml (renamed from test cases/rust/22 cargo subproject/subprojects/bar-rs/Cargo.toml)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs/src/lib.rs (renamed from test cases/rust/22 cargo subproject/subprojects/bar-rs/src/lib.rs)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/lib.c (renamed from test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/lib.c)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/meson.build (renamed from test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/meson.build)2
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/meson_options.txt (renamed from test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/meson_options.txt)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap (renamed from test cases/rust/22 cargo subproject/subprojects/foo-rs.wrap)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml (renamed from test cases/rust/22 cargo subproject/subprojects/foo-rs/Cargo.toml)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs (renamed from test cases/rust/22 cargo subproject/subprojects/foo-rs/lib.rs)0
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/foo-0-rs/meson/meson.build (renamed from test cases/rust/22 cargo subproject/subprojects/foo-rs/meson/meson.build)0
14 files changed, 82 insertions, 22 deletions
diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md
index bba1971c4..5f0b473e7 100644
--- a/docs/markdown/Wrap-dependency-system-manual.md
+++ b/docs/markdown/Wrap-dependency-system-manual.md
@@ -316,11 +316,24 @@ foo-bar-1.0 = foo_bar_dep
```
### Cargo wraps
-Cargo subprojects automatically override the `<package_name>-rs` dependency name.
-`package_name` is defined in `[package] name = ...` section of the `Cargo.toml`
-and `-rs` suffix is added. That means the `.wrap` file should have
-`dependency_names = foo-rs` in their `[provide]` section when `Cargo.toml` has
-package name `foo`.
+Cargo subprojects automatically override the `<package_name>-<version>-rs` dependency
+name:
+- `package_name` is defined in `[package] name = ...` section of the `Cargo.toml`.
+- `version` is the API version deduced from `[package] version = ...` as follow:
+ * `x.y.z` -> 'x'
+ * `0.x.y` -> '0.x'
+ * `0.0.x` -> '0'
+ It allows to make different dependencies for uncompatible versions of the same
+ crate.
+- `-rs` suffix is added to distinguish from regular system dependencies, for
+ example `gstreamer-1.0` is a system pkg-config dependency and `gstreamer-0.22-rs`
+ is a Cargo dependency.
+
+That means the `.wrap` file should have `dependency_names = foo-1-rs` in their
+`[provide]` section when `Cargo.toml` has package name `foo` and version `1.2`.
+
+Note that the version component was added in Meson 1.4, previous versions were
+using `<package_name>-rs` format.
Cargo subprojects require a toml parser. Python >= 3.11 have one built-in, older
Python versions require either the external `tomli` module or `toml2json` program.
@@ -332,26 +345,26 @@ file like that:
...
method = cargo
[provide]
-dependency_names = foo-bar-rs
+dependency_names = foo-bar-0.1-rs
```
Cargo features are exposed as Meson boolean options, with the `feature-` prefix.
For example the `default` feature is named `feature-default` and can be set from
-the command line with `-Dfoo-rs:feature-default=false`. When a cargo subproject
+the command line with `-Dfoo-1-rs:feature-default=false`. When a cargo subproject
depends on another cargo subproject, it will automatically enable features it
-needs using the `dependency('foo-rs', default_options: ...)` mechanism. However,
+needs using the `dependency('foo-1-rs', default_options: ...)` mechanism. However,
unlike Cargo, the set of enabled features is not managed globally. Let's assume
-the main project depends on `foo-rs` and `bar-rs`, and they both depend on
-`common-rs`. The main project will first look up `foo-rs` which itself will
-configure `common-rs` with a set of features. Later, when `bar-rs` does a lookup
-for `common-rs` it has already been configured and the set of features cannot be
-changed. If `bar-rs` wants extra features from `common-rs`, Meson will error out.
+the main project depends on `foo-1-rs` and `bar-1-rs`, and they both depend on
+`common-1-rs`. The main project will first look up `foo-1-rs` which itself will
+configure `common-rs` with a set of features. Later, when `bar-1-rs` does a lookup
+for `common-1-rs` it has already been configured and the set of features cannot be
+changed. If `bar-1-rs` wants extra features from `common-1-rs`, Meson will error out.
It is currently the responsability of the main project to resolve those
issues by enabling extra features on each subproject:
```meson
project(...,
default_options: {
- 'common-rs:feature-something': true,
+ 'common-1-rs:feature-something': true,
},
)
```
diff --git a/docs/markdown/snippets/cargo_dep_name.md b/docs/markdown/snippets/cargo_dep_name.md
new file mode 100644
index 000000000..b769f2b90
--- /dev/null
+++ b/docs/markdown/snippets/cargo_dep_name.md
@@ -0,0 +1,19 @@
+## Cargo dependencies names now include the API version
+
+Cargo dependencies names are now in the format `<package_name>-<version>-rs`:
+- `package_name` is defined in `[package] name = ...` section of the `Cargo.toml`.
+- `version` is the API version deduced from `[package] version = ...` as follow:
+ * `x.y.z` -> 'x'
+ * `0.x.y` -> '0.x'
+ * `0.0.x` -> '0'
+ It allows to make different dependencies for uncompatible versions of the same
+ crate.
+- `-rs` suffix is added to distinguish from regular system dependencies, for
+ example `gstreamer-1.0` is a system pkg-config dependency and `gstreamer-0.22-rs`
+ is a Cargo dependency.
+
+That means the `.wrap` file should have `dependency_names = foo-1-rs` in their
+`[provide]` section when `Cargo.toml` has package name `foo` and version `1.2`.
+
+This is a breaking change (Cargo subprojects are still experimental), previous
+versions were using `<package_name>-rs` format.
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index a919563e0..f1ed23953 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -162,9 +162,23 @@ class Dependency:
package: str = ''
default_features: bool = True
features: T.List[str] = dataclasses.field(default_factory=list)
+ api: str = dataclasses.field(init=False)
def __post_init__(self, name: str) -> None:
self.package = self.package or name
+ # Extract wanted API version from version constraints.
+ api = set()
+ for v in self.version:
+ if v.startswith(('>=', '==')):
+ api.add(_version_to_api(v[2:].strip()))
+ elif v.startswith('='):
+ api.add(_version_to_api(v[1:].strip()))
+ if not api:
+ self.api = '0'
+ elif len(api) == 1:
+ self.api = api.pop()
+ else:
+ raise MesonException(f'Cannot determine minimum API version from {self.version}.')
@classmethod
def from_raw(cls, name: str, raw: manifest.DependencyV) -> Dependency:
@@ -351,8 +365,21 @@ def _load_manifests(subdir: str) -> T.Dict[str, Manifest]:
return manifests
-def _dependency_name(package_name: str) -> str:
- return package_name if package_name.endswith('-rs') else f'{package_name}-rs'
+def _version_to_api(version: str) -> str:
+ # x.y.z -> x
+ # 0.x.y -> 0.x
+ # 0.0.x -> 0
+ vers = version.split('.')
+ if int(vers[0]) != 0:
+ return vers[0]
+ elif len(vers) >= 2 and int(vers[1]) != 0:
+ return f'0.{vers[1]}'
+ return '0'
+
+
+def _dependency_name(package_name: str, api: str) -> str:
+ basename = package_name[:-3] if package_name.endswith('-rs') else package_name
+ return f'{basename}-{api}-rs'
def _dependency_varname(package_name: str) -> str:
@@ -517,7 +544,7 @@ def _create_dependencies(cargo: Manifest, build: builder.Builder) -> T.List[mpar
build.assign(
build.function(
'dependency',
- [build.string(_dependency_name(dep.package))],
+ [build.string(_dependency_name(dep.package, dep.api))],
kw,
),
_dependency_varname(dep.package),
@@ -559,7 +586,7 @@ def _create_dependencies(cargo: Manifest, build: builder.Builder) -> T.List[mpar
build.if_(build.not_in(build.identifier('f'), build.identifier('actual_features')), build.block([
build.function('error', [
build.string('Dependency'),
- build.string(_dependency_name(dep.package)),
+ build.string(_dependency_name(dep.package, dep.api)),
build.string('previously configured with features'),
build.identifier('actual_features'),
build.string('but need'),
@@ -666,7 +693,7 @@ def _create_lib(cargo: Manifest, build: builder.Builder, crate_type: manifest.CR
'override_dependency',
build.identifier('meson'),
[
- build.string(_dependency_name(cargo.package.name)),
+ build.string(_dependency_name(cargo.package.name, _version_to_api(cargo.package.version))),
build.identifier('dep'),
],
),
@@ -674,7 +701,8 @@ def _create_lib(cargo: Manifest, build: builder.Builder, crate_type: manifest.CR
def interpret(subp_name: str, subdir: str, env: Environment) -> T.Tuple[mparser.CodeBlockNode, KeyedOptionDictType]:
- package_name = subp_name[:-3] if subp_name.endswith('-rs') else subp_name
+ # subp_name should be in the form "foo-0.1-rs"
+ package_name = subp_name.rsplit('-', 2)[0]
manifests = _load_manifests(os.path.join(env.source_dir, subdir))
cargo = manifests.get(package_name)
if not cargo:
diff --git a/test cases/rust/22 cargo subproject/meson.build b/test cases/rust/22 cargo subproject/meson.build
index 420e6e3b9..1b60014c5 100644
--- a/test cases/rust/22 cargo subproject/meson.build
+++ b/test cases/rust/22 cargo subproject/meson.build
@@ -1,6 +1,6 @@
project('cargo subproject', 'c')
-foo_dep = dependency('foo-rs')
+foo_dep = dependency('foo-0-rs')
exe = executable('app', 'main.c',
dependencies: foo_dep,
)
diff --git a/test cases/rust/22 cargo subproject/subprojects/bar-rs.wrap b/test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs.wrap
index 99686e90e..99686e90e 100644
--- a/test cases/rust/22 cargo subproject/subprojects/bar-rs.wrap
+++ b/test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs.wrap
diff --git a/test cases/rust/22 cargo subproject/subprojects/bar-rs/Cargo.toml b/test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs/Cargo.toml
index d60a5d8f1..d60a5d8f1 100644
--- a/test cases/rust/22 cargo subproject/subprojects/bar-rs/Cargo.toml
+++ b/test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs/Cargo.toml
diff --git a/test cases/rust/22 cargo subproject/subprojects/bar-rs/src/lib.rs b/test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs/src/lib.rs
index 5b64db8cc..5b64db8cc 100644
--- a/test cases/rust/22 cargo subproject/subprojects/bar-rs/src/lib.rs
+++ b/test cases/rust/22 cargo subproject/subprojects/bar-0.1-rs/src/lib.rs
diff --git a/test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/lib.c b/test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/lib.c
index c2a0777ce..c2a0777ce 100644
--- a/test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/lib.c
+++ b/test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/lib.c
diff --git a/test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/meson.build b/test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/meson.build
index 3ba7852cf..40d109b2d 100644
--- a/test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/meson.build
+++ b/test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/meson.build
@@ -7,4 +7,4 @@ d = declare_dependency(link_with: l,
variables: {
'features': 'default',
})
-meson.override_dependency('extra-dep-rs', d)
+meson.override_dependency('extra-dep-1-rs', d)
diff --git a/test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/meson_options.txt b/test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/meson_options.txt
index 9311d9e8f..9311d9e8f 100644
--- a/test cases/rust/22 cargo subproject/subprojects/extra-dep-rs/meson_options.txt
+++ b/test cases/rust/22 cargo subproject/subprojects/extra-dep-1-rs/meson_options.txt
diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-rs.wrap b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap
index 99686e90e..99686e90e 100644
--- a/test cases/rust/22 cargo subproject/subprojects/foo-rs.wrap
+++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap
diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-rs/Cargo.toml b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml
index 0f0225d06..0f0225d06 100644
--- a/test cases/rust/22 cargo subproject/subprojects/foo-rs/Cargo.toml
+++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml
diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-rs/lib.rs b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs
index 1c8cbc9d3..1c8cbc9d3 100644
--- a/test cases/rust/22 cargo subproject/subprojects/foo-rs/lib.rs
+++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs
diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-rs/meson/meson.build b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/meson/meson.build
index 67c7b82f9..67c7b82f9 100644
--- a/test cases/rust/22 cargo subproject/subprojects/foo-rs/meson/meson.build
+++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/meson/meson.build