summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-10-20 12:00:31 +0200
committerDylan Baker <dylan@pnwbakers.com>2025-10-29 11:34:19 -0700
commitff0da8872cc7270e0f1a375666ccad6a52bc215f (patch)
tree9b35c603c5d296b10501d144bc42460883f3a3dc
parent53b244897037d292a8ed81405cfc51137cf3b043 (diff)
downloadmeson-ff0da8872cc7270e0f1a375666ccad6a52bc215f.tar.gz
cargo: pull feature and dependency data out of PackageState
Part of PackageState refers to the package itself, and part to the feature and dependency resolution process. Pull the latter outside, in preparation for having different features and dependencies for the build and the host machine. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/cargo/interpreter.py52
1 files changed, 33 insertions, 19 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index b219b9272..ec5a93306 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -62,15 +62,22 @@ def _extra_deps_varname() -> str:
@dataclasses.dataclass
-class PackageState:
- manifest: Manifest
- downloaded: bool = False
+class PackageConfiguration:
+ """Configuration for a package during dependency resolution."""
features: T.Set[str] = dataclasses.field(default_factory=set)
required_deps: T.Set[str] = dataclasses.field(default_factory=set)
optional_deps_features: T.Dict[str, T.Set[str]] = dataclasses.field(default_factory=lambda: collections.defaultdict(set))
+
+
+@dataclasses.dataclass
+class PackageState:
+ manifest: Manifest
+ downloaded: bool = False
# If this package is member of a workspace.
ws_subdir: T.Optional[str] = None
ws_member: T.Optional[str] = None
+ # Package configuration state
+ cfg: PackageConfiguration = dataclasses.field(default_factory=PackageConfiguration)
@dataclasses.dataclass(frozen=True)
@@ -140,8 +147,9 @@ class Interpreter:
return build.block(ast)
def _create_package(self, pkg: PackageState, build: builder.Builder, subdir: str) -> T.List[mparser.BaseNode]:
+ cfg = pkg.cfg
ast: T.List[mparser.BaseNode] = [
- build.assign(build.array([build.string(f) for f in pkg.features]), 'features'),
+ build.assign(build.array([build.string(f) for f in cfg.features]), 'features'),
build.function('message', [
build.string('Enabled features:'),
build.identifier('features'),
@@ -188,7 +196,8 @@ class Interpreter:
if member in processed_members:
return
pkg = ws.packages[member]
- for depname in pkg.required_deps:
+ cfg = pkg.cfg
+ for depname in cfg.required_deps:
dep = pkg.manifest.dependencies[depname]
if dep.path:
dep_member = os.path.normpath(os.path.join(pkg.ws_member, dep.path))
@@ -356,25 +365,27 @@ class Interpreter:
return manifest_
def _add_dependency(self, pkg: PackageState, depname: str) -> None:
- if depname in pkg.required_deps:
+ cfg = pkg.cfg
+ if depname in cfg.required_deps:
return
dep = pkg.manifest.dependencies.get(depname)
if not dep:
# It could be build/dev/target dependency. Just ignore it.
return
- pkg.required_deps.add(depname)
+ cfg.required_deps.add(depname)
dep_pkg = self._dep_package(pkg, dep)
if dep.default_features:
self._enable_feature(dep_pkg, 'default')
for f in dep.features:
self._enable_feature(dep_pkg, f)
- for f in pkg.optional_deps_features[depname]:
+ for f in cfg.optional_deps_features[depname]:
self._enable_feature(dep_pkg, f)
def _enable_feature(self, pkg: PackageState, feature: str) -> None:
- if feature in pkg.features:
+ cfg = pkg.cfg
+ if feature in cfg.features:
return
- pkg.features.add(feature)
+ cfg.features.add(feature)
# A feature can also be a dependency.
if feature in pkg.manifest.dependencies:
self._add_dependency(pkg, feature)
@@ -387,14 +398,14 @@ class Interpreter:
depname = depname[:-1]
else:
self._add_dependency(pkg, depname)
- if depname in pkg.required_deps:
+ if depname in cfg.required_deps:
dep = pkg.manifest.dependencies[depname]
dep_pkg = self._dep_package(pkg, dep)
self._enable_feature(dep_pkg, dep_f)
else:
# This feature will be enabled only if that dependency
# is later added.
- pkg.optional_deps_features[depname].add(dep_f)
+ cfg.optional_deps_features[depname].add(dep_f)
elif f.startswith('dep:'):
self._add_dependency(pkg, f[4:])
else:
@@ -477,15 +488,16 @@ class Interpreter:
return [build.function('project', args, kwargs)]
def _create_dependencies(self, pkg: PackageState, build: builder.Builder) -> T.List[mparser.BaseNode]:
+ cfg = pkg.cfg
ast: T.List[mparser.BaseNode] = []
- for depname in pkg.required_deps:
+ for depname in cfg.required_deps:
dep = pkg.manifest.dependencies[depname]
dep_pkg = self._dep_package(pkg, dep)
if dep_pkg.manifest.lib:
ast += self._create_dependency(dep_pkg, dep, build)
ast.append(build.assign(build.array([]), 'system_deps_args'))
for name, sys_dep in pkg.manifest.system_dependencies.items():
- if sys_dep.enabled(pkg.features):
+ if sys_dep.enabled(cfg.features):
ast += self._create_system_dependency(name, sys_dep, build)
return ast
@@ -517,6 +529,7 @@ class Interpreter:
]
def _create_dependency(self, pkg: PackageState, dep: Dependency, build: builder.Builder) -> T.List[mparser.BaseNode]:
+ cfg = pkg.cfg
version_ = dep.meson_version or [pkg.manifest.package.version]
kw = {
'version': build.array([build.string(s) for s in version_]),
@@ -562,7 +575,7 @@ class Interpreter:
# error()
# endif
# endforeach
- build.assign(build.array([build.string(f) for f in pkg.features]), 'needed_features'),
+ build.assign(build.array([build.string(f) for f in cfg.features]), 'needed_features'),
build.foreach(['f'], build.identifier('needed_features'), build.block([
build.if_(build.not_in(build.identifier('f'), build.identifier('actual_features')), build.block([
build.function('error', [
@@ -648,9 +661,10 @@ class Interpreter:
def _create_lib(self, pkg: PackageState, build: builder.Builder,
lib_type: Literal['rust', 'c', 'proc-macro'],
static: bool = False, shared: bool = False) -> T.List[mparser.BaseNode]:
+ cfg = pkg.cfg
dependencies: T.List[mparser.BaseNode] = []
dependency_map: T.Dict[mparser.BaseNode, mparser.BaseNode] = {}
- for name in pkg.required_deps:
+ for name in cfg.required_deps:
dep = pkg.manifest.dependencies[name]
dependencies.append(build.identifier(_dependency_varname(dep)))
if name != dep.package:
@@ -658,7 +672,7 @@ class Interpreter:
dep_lib_name = _library_name(dep_pkg.manifest.lib.name, dep_pkg.manifest.package.api)
dependency_map[build.string(dep_lib_name)] = build.string(name)
for name, sys_dep in pkg.manifest.system_dependencies.items():
- if sys_dep.enabled(pkg.features):
+ if sys_dep.enabled(cfg.features):
dependencies.append(build.identifier(f'{fixup_meson_varname(name)}_system_dep'))
rust_args: T.List[mparser.BaseNode] = [
@@ -703,7 +717,7 @@ class Interpreter:
lib = build.function(target_type, posargs, kwargs)
features_args: T.List[mparser.BaseNode] = []
- for f in pkg.features:
+ for f in cfg.features:
features_args += [build.string('--cfg'), build.string(f'feature="{f}"')]
# features_args = ['--cfg', 'feature="f1"', ...]
@@ -719,7 +733,7 @@ class Interpreter:
kw={
'link_with': build.identifier('lib'),
'variables': build.dict({
- build.string('features'): build.string(','.join(pkg.features)),
+ build.string('features'): build.string(','.join(cfg.features)),
}),
'version': build.string(pkg.manifest.package.version),
},