aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Rewriter.md3
-rw-r--r--mesonbuild/ast/interpreter.py5
-rw-r--r--mesonbuild/ast/introspection.py7
-rw-r--r--mesonbuild/rewriter.py24
-rwxr-xr-xrun_unittests.py9
-rw-r--r--test cases/rewrite/4 same name targets/addSrc.json8
-rw-r--r--test cases/rewrite/4 same name targets/info.json12
-rw-r--r--test cases/rewrite/4 same name targets/meson.build6
-rw-r--r--test cases/rewrite/4 same name targets/sub1/meson.build3
9 files changed, 63 insertions, 14 deletions
diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md
index b88b4a8..8d46597 100644
--- a/docs/markdown/Rewriter.md
+++ b/docs/markdown/Rewriter.md
@@ -63,7 +63,8 @@ exe1 = executable('testExe', src)
In this case, `exe1` could also have been used for the target name. This is
possible because the rewriter also searches for assignments and unique meson
-IDs, which can be acquired with introspection.
+IDs, which can be acquired with introspection. If there are multiple targets
+with the same name, meson will do nothing and print an error message.
For more information see the help output of the rewriter target command.
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index b2cd3f5..01277f0 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -51,6 +51,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.visitors = visitors
self.visited_subdirs = {}
self.assignments = {}
+ self.assign_vals = {}
self.reverse_assignment = {}
self.funcs.update({'project': self.func_do_nothing,
'test': self.func_do_nothing,
@@ -161,7 +162,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.assignments[node.var_name] += [node.value] # Save a reference to the value node
if hasattr(node.value, 'ast_id'):
self.reverse_assignment[node.value.ast_id] = node
- self.evaluate_statement(node.value) # Evaluate the value just in case
+ self.assign_vals[node.var_name] += [self.evaluate_statement(node.value)]
def evaluate_indexing(self, node):
return 0
@@ -200,7 +201,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.assignments[node.var_name] = [node.value] # Save a reference to the value node
if hasattr(node.value, 'ast_id'):
self.reverse_assignment[node.value.ast_id] = node
- self.evaluate_statement(node.value) # Evaluate the value just in case
+ self.assign_vals[node.var_name] = [self.evaluate_statement(node.value)] # Evaluate the value just in case
def flatten_args(self, args, include_unknown_args: bool = False):
# Resolve mparser.ArrayNode if needed
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index 12cb379..5745d29 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -194,7 +194,7 @@ class IntrospectionInterpreter(AstInterpreter):
empty_sources = [] # Passing the unresolved sources list causes errors
target = targetclass(name, self.subdir, self.subproject, is_cross, empty_sources, objects, self.environment, kwargs_reduced)
- self.targets += [{
+ new_target = {
'name': target.get_basename(),
'id': target.get_id(),
'type': target.get_typename(),
@@ -206,9 +206,10 @@ class IntrospectionInterpreter(AstInterpreter):
'sources': source_nodes,
'kwargs': kwargs,
'node': node,
- }]
+ }
- return
+ self.targets += [new_target]
+ return new_target
def build_library(self, node, args, kwargs):
default_library = self.coredata.get_builtin_option('default_library')
diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py
index 52c5a6f..2a41b2e 100644
--- a/mesonbuild/rewriter.py
+++ b/mesonbuild/rewriter.py
@@ -379,23 +379,31 @@ class Rewriter:
sys.stderr.write(json.dumps(self.info_dump, indent=2))
def find_target(self, target: str):
- def check_list(name: str):
+ def check_list(name: str) -> List[BaseNode]:
+ result = []
for i in self.interpreter.targets:
if name == i['name'] or name == i['id']:
- return i
- return None
+ result += [i]
+ return result
- tgt = check_list(target)
- if tgt is not None:
- return tgt
+ targets = check_list(target)
+ if targets:
+ if len(targets) == 1:
+ return targets[0]
+ else:
+ mlog.error('There are multiple targets matching', mlog.bold(target))
+ for i in targets:
+ mlog.error(' -- Target name', mlog.bold(i['name']), 'with ID', mlog.bold(i['id']))
+ mlog.error('Please try again with the unique ID of the target --> skipping')
+ return None
# Check the assignments
+ tgt = None
if target in self.interpreter.assignments:
node = self.interpreter.assignments[target][0]
if isinstance(node, FunctionNode):
if node.func_name in ['executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries']:
- name = self.interpreter.flatten_args(node.args)[0]
- tgt = check_list(name)
+ tgt = self.interpreter.assign_vals[target][0]
return tgt
diff --git a/run_unittests.py b/run_unittests.py
index dc8ff6f..408a7af 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5401,6 +5401,15 @@ class RewriterTests(BasePlatformTests):
}
self.assertDictEqual(out, expected)
+ def test_target_same_name_skip(self):
+ self.prime('4 same name targets')
+ out = self.rewrite(self.builddir, os.path.join(self.builddir, 'addSrc.json'))
+ out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
+ expected = {'name': 'myExe', 'sources': ['main.cpp']}
+ self.assertEqual(len(out['target']), 2)
+ for _, val in out['target'].items():
+ self.assertDictEqual(expected, val)
+
def test_kwargs_info(self):
self.prime('3 kwargs')
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
diff --git a/test cases/rewrite/4 same name targets/addSrc.json b/test cases/rewrite/4 same name targets/addSrc.json
new file mode 100644
index 0000000..98d0d1e
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/addSrc.json
@@ -0,0 +1,8 @@
+[
+ {
+ "type": "target",
+ "target": "myExe",
+ "operation": "src_add",
+ "sources": ["a1.cpp", "a2.cpp"]
+ }
+]
diff --git a/test cases/rewrite/4 same name targets/info.json b/test cases/rewrite/4 same name targets/info.json
new file mode 100644
index 0000000..a9fc2dd
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/info.json
@@ -0,0 +1,12 @@
+[
+ {
+ "type": "target",
+ "target": "exe1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe2",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/4 same name targets/meson.build b/test cases/rewrite/4 same name targets/meson.build
new file mode 100644
index 0000000..384fa2b
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/meson.build
@@ -0,0 +1,6 @@
+project('rewrite same name targets', 'cpp')
+
+src1 = ['main.cpp']
+
+exe1 = executable('myExe', src1)
+subdir('sub1')
diff --git a/test cases/rewrite/4 same name targets/sub1/meson.build b/test cases/rewrite/4 same name targets/sub1/meson.build
new file mode 100644
index 0000000..ac53667
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/sub1/meson.build
@@ -0,0 +1,3 @@
+src2 = ['main.cpp']
+
+exe2 = executable('myExe', src2)