summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-10-28 13:33:09 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2025-12-22 12:01:05 +0100
commitdcf3af6b4e755a5da76eeea91332ca3dce17810f (patch)
treec631924f7eafc241806c9d8eb713f1df29f2fd95
parent013121d3dda42b2bf70cb53675e3f3fe432b1d97 (diff)
downloadmeson-dcf3af6b4e755a5da76eeea91332ca3dce17810f.tar.gz
modules: rust: invoke subprojects automatically from dependencies()
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/cargo/interpreter.py10
-rw-r--r--mesonbuild/modules/__init__.py1
-rw-r--r--mesonbuild/modules/rust.py10
-rw-r--r--test cases/rust/31 rust.workspace package/meson.build14
-rw-r--r--test cases/rust/32 rust.workspace workspace/meson.build14
5 files changed, 33 insertions, 16 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index d7d4a7733..fc3465a0f 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -24,7 +24,9 @@ from . import builder, version
from .cfg import eval_cfg
from .toml import load_toml
from .manifest import Manifest, CargoLock, CargoLockPackage, Workspace, fixup_meson_varname
-from ..mesonlib import is_parent_path, MesonException, MachineChoice, unique_list, version_compare
+from ..mesonlib import (
+ is_parent_path, lazy_property, MesonException, MachineChoice,
+ unique_list, version_compare)
from .. import coredata, mlog
from ..wrap.wrap import PackageDefinition
@@ -105,6 +107,12 @@ class PackageState:
# Package configuration state
cfg: T.Optional[PackageConfiguration] = None
+ @lazy_property
+ def path(self) -> T.Optional[str]:
+ if not self.ws_subdir:
+ return None
+ return os.path.normpath(os.path.join(self.ws_subdir, self.ws_member))
+
def get_env_dict(self, environment: Environment, subdir: str) -> T.Dict[str, str]:
"""Get environment variables for this package."""
# Common variables for build.rs and crates
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 8639fa827..8c6ed2fec 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -36,6 +36,7 @@ class ModuleState:
self.source_root = interpreter.environment.get_source_dir()
self.build_to_src = relpath(interpreter.environment.get_source_dir(),
interpreter.environment.get_build_dir())
+ self.subproject_dir = interpreter.subproject_dir
self.subproject = interpreter.subproject
self.subdir = interpreter.subdir
self.root_subdir = interpreter.root_subdir
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index c1fcf049d..974d50ae6 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -23,7 +23,7 @@ from ..interpreter.type_checking import (
)
from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noKwargs, noPosargs, permittedKwargs
from ..interpreter.interpreterobjects import Doctest
-from ..mesonlib import File, MachineChoice, MesonException, PerMachine
+from ..mesonlib import (is_parent_path, File, MachineChoice, MesonException, PerMachine)
from ..programs import ExternalProgram, NonExistingExternalProgram
if T.TYPE_CHECKING:
@@ -116,6 +116,10 @@ class RustWorkspace(ModuleObject):
'subproject': self.subproject_method,
})
+ @property
+ def subdir(self) -> str:
+ return self.ws.subdir
+
@noPosargs
@noKwargs
def packages_method(self, state: ModuleState, args: T.List, kwargs: TYPE_kwargs) -> T.List[str]:
@@ -245,6 +249,10 @@ class RustPackage(RustCrate):
if kwargs['dependencies']:
for dep_key, dep_pkg in 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),
+ dep_pkg.path):
+ self.rust_ws._do_subproject(dep_pkg)
# Get the dependency name for this package
depname = dep_pkg.get_dependency_name(None)
dependency = state.overridden_dependency(depname)
diff --git a/test cases/rust/31 rust.workspace package/meson.build b/test cases/rust/31 rust.workspace package/meson.build
index ec17a00f5..d00a6096a 100644
--- a/test cases/rust/31 rust.workspace package/meson.build
+++ b/test cases/rust/31 rust.workspace package/meson.build
@@ -20,13 +20,6 @@ assert(hello_rs.api() == '1')
assert(hello_rs.all_features() == ['default', 'goodbye'])
assert(hello_rs.features() == ['default', 'goodbye'])
-answer_rs = cargo_ws.subproject('answer', '2')
-assert(answer_rs.name() == 'answer')
-assert(answer_rs.version() == '2.1.0')
-assert(answer_rs.api() == '2')
-assert(answer_rs.all_features() == ['default', 'large'])
-assert(answer_rs.features() == ['default', 'large'])
-
e = executable('package-test', 'src/main.rs',
dependencies: main_pkg.dependencies(),
rust_args: main_pkg.rust_args(),
@@ -34,6 +27,13 @@ e = executable('package-test', 'src/main.rs',
)
test('package-test', e)
+answer_rs = cargo_ws.subproject('answer', '2')
+assert(answer_rs.name() == 'answer')
+assert(answer_rs.version() == '2.1.0')
+assert(answer_rs.api() == '2')
+assert(answer_rs.all_features() == ['default', 'large'])
+assert(answer_rs.features() == ['default', 'large'])
+
# failure test cases for package()
testcase expect_error('argument to package() cannot be a subproject')
cargo_ws.package('hello')
diff --git a/test cases/rust/32 rust.workspace workspace/meson.build b/test cases/rust/32 rust.workspace workspace/meson.build
index 63df7b1c4..d54abd89b 100644
--- a/test cases/rust/32 rust.workspace workspace/meson.build
+++ b/test cases/rust/32 rust.workspace workspace/meson.build
@@ -20,13 +20,6 @@ assert(hello_rs.api() == '1')
assert(hello_rs.all_features() == ['default', 'goodbye'])
assert(hello_rs.features() == ['default', 'goodbye'])
-answer_rs = cargo_ws.subproject('answer', '2')
-assert(answer_rs.name() == 'answer')
-assert(answer_rs.version() == '2.1.0')
-assert(answer_rs.api() == '2')
-assert(answer_rs.all_features() == ['default', 'large'])
-assert(answer_rs.features() == ['default', 'large'])
-
subdir('more')
e = executable('workspace-test', 'src/main.rs',
@@ -36,6 +29,13 @@ e = executable('workspace-test', 'src/main.rs',
)
test('workspace-test', e)
+answer_rs = cargo_ws.subproject('answer', '2')
+assert(answer_rs.name() == 'answer')
+assert(answer_rs.version() == '2.1.0')
+assert(answer_rs.api() == '2')
+assert(answer_rs.all_features() == ['default', 'large'])
+assert(answer_rs.features() == ['default', 'large'])
+
# failure test cases for package()
testcase expect_error('argument to package() cannot be a subproject')
cargo_ws.package('hello')