aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2020-10-13 19:44:41 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2020-10-15 01:56:59 +0300
commit7c377e5a5d1e413ea3494ceed0800985fcd804ae (patch)
treebeb8d9e6dfe24740de92151eaa5906b4c52b5cda /mesonbuild
parent30d78f39812a0585a27e24ab44ef4e9da1f12574 (diff)
downloadmeson-7c377e5a5d1e413ea3494ceed0800985fcd804ae.zip
meson-7c377e5a5d1e413ea3494ceed0800985fcd804ae.tar.gz
meson-7c377e5a5d1e413ea3494ceed0800985fcd804ae.tar.bz2
intro: Add extra_files key to intro output (fixes #7310)
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/ast/introspection.py68
-rw-r--r--mesonbuild/backend/backends.py2
-rw-r--r--mesonbuild/build.py5
-rw-r--r--mesonbuild/mintro.py24
4 files changed, 59 insertions, 40 deletions
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index 9cfdded..334ff83 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -194,42 +194,51 @@ class IntrospectionInterpreter(AstInterpreter):
return None
name = args[0]
srcqueue = [node]
+ extra_queue = []
# Process the sources BEFORE flattening the kwargs, to preserve the original nodes
if 'sources' in kwargs_raw:
srcqueue += mesonlib.listify(kwargs_raw['sources'])
+ if 'extra_files' in kwargs_raw:
+ extra_queue += mesonlib.listify(kwargs_raw['extra_files'])
+
kwargs = self.flatten_kwargs(kwargs_raw, True)
- source_nodes = [] # type: T.List[BaseNode]
- while srcqueue:
- curr = srcqueue.pop(0)
- arg_node = None
- assert(isinstance(curr, BaseNode))
- if isinstance(curr, FunctionNode):
- arg_node = curr.args
- elif isinstance(curr, ArrayNode):
- arg_node = curr.args
- elif isinstance(curr, IdNode):
- # Try to resolve the ID and append the node to the queue
- assert isinstance(curr.value, str)
- var_name = curr.value
- if var_name in self.assignments:
- tmp_node = self.assignments[var_name]
- if isinstance(tmp_node, (ArrayNode, IdNode, FunctionNode)):
- srcqueue += [tmp_node]
- elif isinstance(curr, ArithmeticNode):
- srcqueue += [curr.left, curr.right]
- if arg_node is None:
- continue
- arg_nodes = arg_node.arguments.copy()
- # Pop the first element if the function is a build target function
- if isinstance(curr, FunctionNode) and curr.func_name in build_target_functions:
- arg_nodes.pop(0)
- elemetary_nodes = [x for x in arg_nodes if isinstance(x, (str, StringNode))]
- srcqueue += [x for x in arg_nodes if isinstance(x, (FunctionNode, ArrayNode, IdNode, ArithmeticNode))]
- if elemetary_nodes:
- source_nodes += [curr]
+ def traverse_nodes(inqueue: T.List[BaseNode]) -> T.List[BaseNode]:
+ res = [] # type: T.List[BaseNode]
+ while inqueue:
+ curr = inqueue.pop(0)
+ arg_node = None
+ assert(isinstance(curr, BaseNode))
+ if isinstance(curr, FunctionNode):
+ arg_node = curr.args
+ elif isinstance(curr, ArrayNode):
+ arg_node = curr.args
+ elif isinstance(curr, IdNode):
+ # Try to resolve the ID and append the node to the queue
+ assert isinstance(curr.value, str)
+ var_name = curr.value
+ if var_name in self.assignments:
+ tmp_node = self.assignments[var_name]
+ if isinstance(tmp_node, (ArrayNode, IdNode, FunctionNode)):
+ inqueue += [tmp_node]
+ elif isinstance(curr, ArithmeticNode):
+ inqueue += [curr.left, curr.right]
+ if arg_node is None:
+ continue
+ arg_nodes = arg_node.arguments.copy()
+ # Pop the first element if the function is a build target function
+ if isinstance(curr, FunctionNode) and curr.func_name in build_target_functions:
+ arg_nodes.pop(0)
+ elemetary_nodes = [x for x in arg_nodes if isinstance(x, (str, StringNode))]
+ inqueue += [x for x in arg_nodes if isinstance(x, (FunctionNode, ArrayNode, IdNode, ArithmeticNode))]
+ if elemetary_nodes:
+ res += [curr]
+ return res
+
+ source_nodes = traverse_nodes(srcqueue)
+ extraf_nodes = traverse_nodes(extra_queue)
# Make sure nothing can crash when creating the build class
kwargs_reduced = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs and k in ['install', 'build_by_default', 'build_always']}
@@ -251,6 +260,7 @@ class IntrospectionInterpreter(AstInterpreter):
'installed': target.should_install(),
'outputs': target.get_outputs(),
'sources': source_nodes,
+ 'extra_files': extraf_nodes,
'kwargs': kwargs,
'node': node,
}
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 3e883e9..23734a8 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -1390,7 +1390,7 @@ class Backend:
This is a limited fallback / reference implementation. The backend should override this method.
'''
if isinstance(target, (build.CustomTarget, build.BuildTarget)):
- source_list_raw = target.sources + target.extra_files
+ source_list_raw = target.sources
source_list = []
for j in source_list_raw:
if isinstance(j, mesonlib.File):
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index bc1f54a..26b54ff 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -370,6 +370,7 @@ a hard error in the future.'''.format(name))
self.build_always_stale = False
self.option_overrides_base = {}
self.option_overrides_compiler = defaultdict(dict)
+ self.extra_files = [] # type: T.List[File]
if not hasattr(self, 'typename'):
raise RuntimeError('Target type is not set for target class "{}". This is a bug'.format(type(self).__name__))
@@ -518,7 +519,6 @@ class BuildTarget(Target):
self.pch = {}
self.extra_args = {}
self.generated = []
- self.extra_files = []
self.d_features = {}
self.pic = False
self.pie = False
@@ -1011,7 +1011,7 @@ This will become a hard error in a future Meson release.''')
if self.gnu_symbol_visibility not in permitted:
raise InvalidArguments('GNU symbol visibility arg {} not one of: {}'.format(self.symbol_visibility, ', '.join(permitted)))
- def validate_win_subsystem(self, value: str) -> str:
+ def validate_win_subsystem(self, value: str) -> str:
value = value.lower()
if re.fullmatch(r'(boot_application|console|efi_application|efi_boot_service_driver|efi_rom|efi_runtime_driver|native|posix|windows)(,\d+(\.\d+)?)?', value) is None:
raise InvalidArguments('Invalid value for win_subsystem: {}.'.format(value))
@@ -2058,7 +2058,6 @@ class CustomTarget(Target):
self.depend_files = [] # Files that this target depends on but are not on the command line.
self.depfile = None
self.process_kwargs(kwargs, backend)
- self.extra_files = []
# Whether to use absolute paths for all files on the commandline
self.absolute_paths = absolute_paths
unknowns = []
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 4c1e8ea..924a103 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -28,7 +28,7 @@ from . import mlog
from .backend import backends
from .mparser import BaseNode, FunctionNode, ArrayNode, ArgumentNode, StringNode
from .interpreter import Interpreter
-from ._pathlib import PurePath
+from ._pathlib import Path, PurePath
import typing as T
import os
import argparse
@@ -119,9 +119,10 @@ def list_installed(installdata: backends.InstallData) -> T.Dict[str, str]:
def list_targets_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]:
tlist = [] # type: T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]
- for i in intr.targets:
- sources = [] # type: T.List[str]
- for n in i['sources']:
+ root_dir = Path(intr.source_root)
+ def nodes_to_paths(node_list: T.List[BaseNode]) -> T.List[Path]:
+ res = [] # type: T.List[Path]
+ for n in node_list:
args = [] # type: T.List[BaseNode]
if isinstance(n, FunctionNode):
args = list(n.args.arguments)
@@ -134,9 +135,16 @@ def list_targets_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[st
for j in args:
if isinstance(j, StringNode):
assert isinstance(j.value, str)
- sources += [j.value]
+ res += [Path(j.value)]
elif isinstance(j, str):
- sources += [j]
+ res += [Path(j)]
+ res = [root_dir / i['subdir'] / x for x in res]
+ res = [x.resolve() for x in res]
+ return res
+
+ for i in intr.targets:
+ sources = nodes_to_paths(i['sources'])
+ extra_f = nodes_to_paths(i['extra_files'])
tlist += [{
'name': i['name'],
@@ -149,9 +157,10 @@ def list_targets_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[st
'language': 'unknown',
'compiler': [],
'parameters': [],
- 'sources': [os.path.normpath(os.path.join(os.path.abspath(intr.source_root), i['subdir'], x)) for x in sources],
+ 'sources': [str(x) for x in sources],
'generated_sources': []
}],
+ 'extra_files': [str(x) for x in extra_f],
'subproject': None, # Subprojects are not supported
'installed': i['installed']
}]
@@ -182,6 +191,7 @@ def list_targets(builddata: build.Build, installdata: backends.InstallData, back
'filename': [os.path.join(build_dir, target.subdir, x) for x in target.get_outputs()],
'build_by_default': target.build_by_default,
'target_sources': backend.get_introspection_data(idname, target),
+ 'extra_files': [os.path.normpath(os.path.join(src_dir, x.subdir, x.fname)) for x in target.extra_files],
'subproject': target.subproject or None
}