mirror of
https://github.com/mesonbuild/meson.git
synced 2026-06-24 08:48:03 +00:00
cargo: store machine-specific configuration
Make the PackageConfiguration a PerMachine object. This makes it possible to do dependency resolution separately for build- and/or host-side libraries. For now, all users only fill in or consume the host side, but that will change.
This commit is contained in:
committed by
Paolo Bonzini
parent
dc559de85a
commit
65ffb1d07b
@@ -26,7 +26,7 @@ from .toml import load_toml
|
||||
from .manifest import Manifest, CargoLock, CargoLockPackage, Workspace, fixup_meson_varname
|
||||
from ..mesonlib import (
|
||||
is_parent_path, lazy_property, MesonException, MachineChoice,
|
||||
unique_list, SubProject,
|
||||
PerMachine, unique_list, SubProject,
|
||||
)
|
||||
from .. import coredata, mlog
|
||||
from ..wrap.wrap import PackageDefinition
|
||||
@@ -91,8 +91,10 @@ class PackageState:
|
||||
# If this package is member of a workspace.
|
||||
ws_subdir: T.Optional[str] = None
|
||||
ws_member: T.Optional[str] = None
|
||||
# Package configuration state
|
||||
cfg: T.Optional[PackageConfiguration] = None
|
||||
# Per-machine configuration state
|
||||
cfg: PerMachine[T.Optional[PackageConfiguration]] = dataclasses.field(
|
||||
default_factory=lambda: PerMachine(None, None)
|
||||
)
|
||||
# Subproject name as known to the wrap resolver (may differ from the
|
||||
# meson dep name for git sources, where the wrap is named after the
|
||||
# git directory rather than the crate name + api version).
|
||||
@@ -185,8 +187,7 @@ class PackageState:
|
||||
machine = MachineChoice.HOST
|
||||
|
||||
rustc = T.cast('RustCompiler', environment.coredata.compilers[machine]['rust'])
|
||||
|
||||
cfg = self.cfg
|
||||
cfg = self.cfg[MachineChoice.HOST]
|
||||
|
||||
args: T.List[str] = []
|
||||
args.extend(self.get_lint_args(rustc))
|
||||
@@ -403,7 +404,7 @@ class Interpreter:
|
||||
if member in processed_members:
|
||||
return
|
||||
pkg = ws.packages[member]
|
||||
cfg = pkg.cfg
|
||||
cfg = pkg.cfg[MachineChoice.HOST]
|
||||
if not cfg:
|
||||
raise MesonException(f'Package {pkg.manifest.package.name!r} is not enabled for this build '
|
||||
'configuration. Maybe you forgot to enable a Cargo feature, or to check '
|
||||
@@ -544,10 +545,10 @@ class Interpreter:
|
||||
def _prepare_package(self, pkg: PackageState) -> None:
|
||||
key = PackageKey(pkg.manifest.package.name, pkg.manifest.package.api)
|
||||
assert key in self.packages
|
||||
if pkg.cfg:
|
||||
if pkg.cfg[MachineChoice.HOST]:
|
||||
return
|
||||
|
||||
pkg.cfg = PackageConfiguration()
|
||||
pkg.cfg[MachineChoice.HOST] = PackageConfiguration()
|
||||
# Merge target specific dependencies that are enabled
|
||||
cfgs = self._get_cfgs(MachineChoice.HOST)
|
||||
for condition, dependencies in pkg.manifest.target.items():
|
||||
@@ -572,7 +573,7 @@ class Interpreter:
|
||||
if not dep.optional:
|
||||
self._add_dependency(pkg, depname)
|
||||
|
||||
def _dep_package(self, pkg: PackageState, dep: Dependency) -> PackageState:
|
||||
def _dep_package(self, pkg: PackageState, dep: Dependency, cfg: PackageConfiguration) -> PackageState:
|
||||
if dep.path:
|
||||
ws = self.workspaces[pkg.ws_subdir]
|
||||
dep_member = os.path.normpath(os.path.join(pkg.ws_member, dep.path))
|
||||
@@ -594,8 +595,8 @@ class Interpreter:
|
||||
dep.update_version(f'={dep_pkg.manifest.package.version}')
|
||||
|
||||
dep_key = PackageKey(dep.package, dep.api)
|
||||
pkg.cfg.dep_packages.setdefault(dep_key, dep_pkg)
|
||||
assert pkg.cfg.dep_packages[dep_key] == dep_pkg
|
||||
cfg.dep_packages.setdefault(dep_key, dep_pkg)
|
||||
assert cfg.dep_packages[dep_key] == dep_pkg
|
||||
return dep_pkg
|
||||
|
||||
def _load_manifest(self, subdir: str, workspace: T.Optional[Workspace] = None, member_path: str = '') -> T.Tuple[T.Union[Manifest, Workspace], bool]:
|
||||
@@ -620,7 +621,7 @@ class Interpreter:
|
||||
return manifest_, False
|
||||
|
||||
def _add_dependency(self, pkg: PackageState, depname: str) -> None:
|
||||
cfg = pkg.cfg
|
||||
cfg = pkg.cfg[MachineChoice.HOST]
|
||||
if depname in cfg.required_deps:
|
||||
return
|
||||
dep = pkg.manifest.dependencies.get(depname)
|
||||
@@ -628,7 +629,7 @@ class Interpreter:
|
||||
# It could be build/dev/target dependency. Just ignore it.
|
||||
return
|
||||
cfg.required_deps.add(depname)
|
||||
dep_pkg = self._dep_package(pkg, dep)
|
||||
dep_pkg = self._dep_package(pkg, dep, cfg)
|
||||
self._prepare_package(dep_pkg)
|
||||
if dep.default_features:
|
||||
self._enable_feature(dep_pkg, 'default')
|
||||
@@ -638,7 +639,7 @@ class Interpreter:
|
||||
self._enable_feature(dep_pkg, f)
|
||||
|
||||
def _enable_feature(self, pkg: PackageState, feature: str) -> None:
|
||||
cfg = pkg.cfg
|
||||
cfg = pkg.cfg[MachineChoice.HOST]
|
||||
if feature in cfg.features:
|
||||
return
|
||||
cfg.features.add(feature)
|
||||
@@ -653,7 +654,7 @@ class Interpreter:
|
||||
self._add_dependency(pkg, depname)
|
||||
if depname in cfg.required_deps:
|
||||
dep = pkg.manifest.dependencies[depname]
|
||||
dep_pkg = self._dep_package(pkg, dep)
|
||||
dep_pkg = self._dep_package(pkg, dep, cfg)
|
||||
self._enable_feature(dep_pkg, dep_f)
|
||||
else:
|
||||
# This feature will be enabled only if that dependency
|
||||
|
||||
@@ -33,7 +33,7 @@ if T.TYPE_CHECKING:
|
||||
from . import ModuleState
|
||||
from .. import cargo
|
||||
from ..build import ExecutableKeywordArguments, GeneratedTypes, IncludeDirs, LinkableTargetTypes, CommandTypes
|
||||
from ..cargo.interpreter import RUST_ABI
|
||||
from ..cargo.interpreter import RUST_ABI, PackageConfiguration
|
||||
from ..compilers.compilers import Language
|
||||
from ..compilers.rust import RustCompiler
|
||||
from ..dependencies import ExternalLibrary
|
||||
@@ -162,7 +162,7 @@ class RustWorkspace(ModuleObject):
|
||||
"""Returns list of package names in workspace."""
|
||||
package_names = [pkg.manifest.package.name
|
||||
for pkg in self.ws.packages.values()
|
||||
if pkg.cfg]
|
||||
if pkg.cfg.host or pkg.cfg.build]
|
||||
return sorted(package_names)
|
||||
|
||||
@typed_pos_args('workspace.package', optargs=[str])
|
||||
@@ -232,6 +232,10 @@ class RustCrate(ModuleObject):
|
||||
'rust_dependency_map': self.rust_dependency_map_method, # type: ignore[dict-item]
|
||||
})
|
||||
|
||||
@property
|
||||
def cfg(self) -> PackageConfiguration:
|
||||
return self.package.cfg[MachineChoice.HOST]
|
||||
|
||||
@noPosargs
|
||||
@noKwargs
|
||||
def name_method(self, state: ModuleState, args: T.List, kwargs: TYPE_kwargs) -> str:
|
||||
@@ -260,7 +264,7 @@ class RustCrate(ModuleObject):
|
||||
@noKwargs
|
||||
def features_method(self, state: ModuleState, args: T.List, kwargs: TYPE_kwargs) -> T.List[str]:
|
||||
"""Returns chosen features for specific package."""
|
||||
return sorted(list(self.package.cfg.features))
|
||||
return sorted(list(self.cfg.features))
|
||||
|
||||
@noPosargs
|
||||
@noKwargs
|
||||
@@ -278,7 +282,7 @@ class RustCrate(ModuleObject):
|
||||
@noKwargs
|
||||
def rust_dependency_map_method(self, state: ModuleState, args: T.List, kwargs: TYPE_kwargs) -> T.Dict[str, str]:
|
||||
"""Returns rust dependency mapping for this package."""
|
||||
return self.package.cfg.get_dependency_map(self.package.manifest)
|
||||
return self.cfg.get_dependency_map(self.package.manifest)
|
||||
|
||||
|
||||
class RustPackage(RustCrate):
|
||||
@@ -286,7 +290,7 @@ class RustPackage(RustCrate):
|
||||
|
||||
def __init__(self, state: ModuleState, rust_ws: RustWorkspace, package: cargo.PackageState, for_machine: MachineChoice) -> None:
|
||||
super().__init__(state, rust_ws, package, for_machine)
|
||||
if not package.cfg:
|
||||
if not package.cfg[MachineChoice.HOST]:
|
||||
raise MesonException(f"package {self.package.manifest.package.name}-{self.package.manifest.package.version} not configured")
|
||||
self.methods.update({
|
||||
'dependencies': self.dependencies_method,
|
||||
@@ -300,10 +304,8 @@ class RustPackage(RustCrate):
|
||||
def _dependencies_method(self, state: ModuleState, kwargs: RustPackageDependencies,
|
||||
for_machine: MachineChoice) -> T.List[Dependency]:
|
||||
dependencies: T.List[Dependency] = []
|
||||
cfg = self.package.cfg
|
||||
|
||||
if kwargs['dependencies']:
|
||||
for dep_key, dep_pkg in cfg.dep_packages.items():
|
||||
for dep_key, dep_pkg in self.cfg.dep_packages.items():
|
||||
if dep_pkg.manifest.lib:
|
||||
if dep_pkg.ws_subdir != self.rust_ws.subdir or \
|
||||
is_parent_path(os.path.join(self.rust_ws.subdir, state.subproject_dir),
|
||||
@@ -319,7 +321,7 @@ class RustPackage(RustCrate):
|
||||
|
||||
if kwargs['system_dependencies']:
|
||||
for name, sys_dep in self.package.manifest.system_dependencies.items():
|
||||
if sys_dep.enabled(cfg.features):
|
||||
if sys_dep.enabled(self.cfg.features):
|
||||
# System dependencies use the original dependency name from Cargo.toml
|
||||
dependency = state.dependency(sys_dep.name, native=(for_machine == MachineChoice.BUILD),
|
||||
required=not sys_dep.optional,
|
||||
@@ -359,8 +361,7 @@ class RustPackage(RustCrate):
|
||||
kwargs['dependencies'].extend(deps)
|
||||
|
||||
depmap = kwargs['rust_dependency_map']
|
||||
kwargs['rust_dependency_map'] = \
|
||||
self.package.cfg.get_dependency_map(self.package.manifest)
|
||||
kwargs['rust_dependency_map'] = self.cfg.get_dependency_map(self.package.manifest)
|
||||
kwargs['rust_dependency_map'].update(depmap)
|
||||
|
||||
rust_args = kwargs['rust_args']
|
||||
|
||||
Reference in New Issue
Block a user