diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2025-11-28 18:25:24 +0100 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-12-15 13:26:55 -0800 |
| commit | 90b40b5de4d267cb3fdb59fe4fac3e438a18ee8d (patch) | |
| tree | 281ac2db1b712260491fd2790f5922a3801186f5 /mesonbuild/cargo | |
| parent | 5cd09bcabcf4845274cf19b9d796517bd4f8fc72 (diff) | |
| download | meson-90b40b5de4d267cb3fdb59fe4fac3e438a18ee8d.tar.gz | |
cargo: include the implicit feature for dependencies in the manifest
Make the implicit `xyz = ["dep:xyz"]` declaration explicit in the Manifest.
This also makes it possible to implement correctly the part of the spec where
"If you specify the optional dependency with the dep: prefix anywhere in
the [features] table, that disables the implicit feature."
Unfortunately, this can only be done after target-specific configurations
are resolved, which makes it hard to write a unit test for this. Rustix
requires it, though; without this patch, something like
[package]
name = "rustix"
edition = "2021"
rust-version = "1.63"
version = "0.38.34"
[dependencies]
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
libc = { version = "0.2.0", optional = true, package = "libc" }
libc_errno = { version = "0.3.8", optional = true, package = "errno" }
[features]
alloc = []
default = ["std"]
rustc-dep-of-std = ["dep:alloc"]
std = ["alloc"]
use-libc = ["libc_errno", "libc"]
would incorrectly request the rustc-std-workspace-alloc crate via the
chain default->std->alloc. The patch blocks it because it finds the
"dep:alloc" dependency of feature rustc-dep-of-std.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'mesonbuild/cargo')
| -rw-r--r-- | mesonbuild/cargo/interpreter.py | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index ccde33d5e..921355f35 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -12,6 +12,7 @@ port will be required. from __future__ import annotations import dataclasses import functools +import itertools import os import pathlib import collections @@ -428,6 +429,20 @@ class Interpreter: for condition, dependencies in pkg.manifest.target.items(): if eval_cfg(condition, cfgs): pkg.manifest.dependencies.update(dependencies) + + # If you specify the optional dependency with the dep: prefix anywhere in the [features] + # table, that disables the implicit feature. + deps = set(feature[4:] + for feature in itertools.chain.from_iterable(pkg.manifest.features.values()) + if feature.startswith('dep:')) + for name, dep in itertools.chain(pkg.manifest.dependencies.items(), + pkg.manifest.dev_dependencies.items(), + pkg.manifest.build_dependencies.items()): + if dep.optional and name not in deps: + pkg.manifest.features.setdefault(name, []) + pkg.manifest.features[name].append(f'dep:{name}') + deps.add(name) + # Fetch required dependencies recursively. for depname, dep in pkg.manifest.dependencies.items(): if not dep.optional: @@ -499,9 +514,6 @@ class Interpreter: if feature in cfg.features: return cfg.features.add(feature) - # A feature can also be a dependency. - if feature in pkg.manifest.dependencies: - self._add_dependency(pkg, feature) # Recurse on extra features and dependencies this feature pulls. # https://doc.rust-lang.org/cargo/reference/features.html#the-features-section for f in pkg.manifest.features.get(feature, []): |
