diff options
author | Daniel Mensinger <daniel@mensinger-ka.de> | 2020-10-13 19:44:41 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2020-10-15 01:56:59 +0300 |
commit | 7c377e5a5d1e413ea3494ceed0800985fcd804ae (patch) | |
tree | beb8d9e6dfe24740de92151eaa5906b4c52b5cda /mesonbuild | |
parent | 30d78f39812a0585a27e24ab44ef4e9da1f12574 (diff) | |
download | meson-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.py | 68 | ||||
-rw-r--r-- | mesonbuild/backend/backends.py | 2 | ||||
-rw-r--r-- | mesonbuild/build.py | 5 | ||||
-rw-r--r-- | mesonbuild/mintro.py | 24 |
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 } |