summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/cargo/interpreter.py16
-rw-r--r--mesonbuild/interpreter/interpreter.py35
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py6
3 files changed, 35 insertions, 22 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index 527943ea8..aaf8f6387 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -86,23 +86,23 @@ class Interpreter:
build_def_files.append(os.path.join(self.subdir, 'Cargo.lock'))
return build_def_files
- def interpret(self, subdir: str) -> mparser.CodeBlockNode:
+ def interpret(self, subdir: str, project_root: T.Optional[str] = None) -> mparser.CodeBlockNode:
manifest = self._load_manifest(subdir)
filename = os.path.join(self.environment.source_dir, subdir, 'Cargo.toml')
build = builder.Builder(filename)
- return self.interpret_package(manifest, build, subdir)
+ return self.interpret_package(manifest, build, subdir, project_root)
- def interpret_package(self, manifest: Manifest, build: builder.Builder, subdir: str) -> mparser.CodeBlockNode:
+ def interpret_package(self, manifest: Manifest, build: builder.Builder, subdir: str, project_root: T.Optional[str]) -> mparser.CodeBlockNode:
+ # Build an AST for this package
+ ast: T.List[mparser.BaseNode] = []
pkg, cached = self._fetch_package(manifest.package.name, manifest.package.api)
if not cached:
# This is an entry point, always enable the 'default' feature.
# FIXME: We should have a Meson option similar to `cargo build --no-default-features`
self._enable_feature(pkg, 'default')
-
- # Build an AST for this package
- ast: T.List[mparser.BaseNode] = []
- ast += self._create_project(pkg.manifest.package.name, pkg, build)
- ast.append(build.assign(build.function('import', [build.string('rust')]), 'rust'))
+ if not project_root:
+ ast += self._create_project(pkg.manifest.package.name, pkg, build)
+ ast.append(build.assign(build.function('import', [build.string('rust')]), 'rust'))
ast += self._create_package(pkg, build, subdir)
return build.block(ast)
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index d3a9142fe..538e540b5 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -235,6 +235,7 @@ class InterpreterRuleRelaxation(Enum):
'''
ALLOW_BUILD_DIR_FILE_REFERENCES = 1
+ CARGO_SUBDIR = 2
permitted_dependency_kwargs = {
'allow_fallback',
@@ -980,6 +981,19 @@ class Interpreter(InterpreterBase, HoldableObject):
return self.disabled_subproject(subp_name, exception=e)
raise e
+ def _save_ast(self, subdir: str, ast: mparser.CodeBlockNode) -> None:
+ # Debug print the generated meson file
+ from ..ast import AstIndentationGenerator, AstPrinter
+ printer = AstPrinter(update_ast_line_nos=True)
+ ast.accept(AstIndentationGenerator())
+ ast.accept(printer)
+ printer.post_process()
+ meson_filename = os.path.join(self.build.environment.get_build_dir(), subdir, 'meson.build')
+ with open(meson_filename, "w", encoding='utf-8') as f:
+ f.write(printer.result)
+ mlog.log('Generated Meson AST:', meson_filename)
+ mlog.cmd_ci_include(meson_filename)
+
def _do_subproject_meson(self, subp_name: str, subdir: str,
default_options: OptionDict,
kwargs: kwtypes.DoSubproject,
@@ -989,18 +1003,7 @@ class Interpreter(InterpreterBase, HoldableObject):
cargo: T.Optional[cargo.Interpreter] = None) -> SubprojectHolder:
with mlog.nested(subp_name):
if ast:
- # Debug print the generated meson file
- from ..ast import AstIndentationGenerator, AstPrinter
- printer = AstPrinter(update_ast_line_nos=True)
- ast.accept(AstIndentationGenerator())
- ast.accept(printer)
- printer.post_process()
- meson_filename = os.path.join(self.build.environment.get_build_dir(), subdir, 'meson.build')
- with open(meson_filename, "w", encoding='utf-8') as f:
- f.write(printer.result)
- mlog.log('Generated Meson AST:', meson_filename)
- mlog.cmd_ci_include(meson_filename)
-
+ self._save_ast(subdir, ast)
new_build = self.build.copy()
subi = Interpreter(new_build, self.backend, subp_name, subdir, self.subproject_dir,
default_options, ast=ast, relaxations=relaxations,
@@ -1086,6 +1089,7 @@ class Interpreter(InterpreterBase, HoldableObject):
ast = cargo_int.interpret(subdir)
return self._do_subproject_meson(
subp_name, subdir, default_options, kwargs, ast,
+ relaxations={InterpreterRuleRelaxation.CARGO_SUBDIR},
cargo=cargo_int)
@typed_pos_args('get_option', str)
@@ -2479,7 +2483,12 @@ class Interpreter(InterpreterBase, HoldableObject):
os.makedirs(os.path.join(self.environment.build_dir, subdir), exist_ok=True)
- if not self._evaluate_subdir(self.environment.get_source_dir(), subdir):
+ if InterpreterRuleRelaxation.CARGO_SUBDIR in self.relaxations and \
+ os.path.exists(os.path.join(self.environment.get_source_dir(), subdir, 'Cargo.toml')):
+ codeblock = self.cargo.interpret(subdir, self.root_subdir)
+ self._save_ast(subdir, codeblock)
+ self._evaluate_codeblock(codeblock, subdir)
+ elif not self._evaluate_subdir(self.environment.get_source_dir(), subdir):
buildfilename = os.path.join(subdir, environment.build_filename)
raise InterpreterException(f"Nonexistent build file '{buildfilename!s}'")
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py
index b13bbae1a..588932cad 100644
--- a/mesonbuild/interpreterbase/interpreterbase.py
+++ b/mesonbuild/interpreterbase/interpreterbase.py
@@ -733,6 +733,11 @@ class InterpreterBase:
except mesonlib.MesonException as me:
me.file = absname
raise me
+ self._evaluate_codeblock(codeblock, subdir, visitors)
+ return True
+
+ def _evaluate_codeblock(self, codeblock: mparser.CodeBlockNode, subdir: str,
+ visitors: T.Optional[T.Iterable[AstVisitor]] = None) -> None:
try:
prev_subdir = self.subdir
self.subdir = subdir
@@ -744,4 +749,3 @@ class InterpreterBase:
pass
finally:
self.subdir = prev_subdir
- return True