diff options
| -rw-r--r-- | mesonbuild/backend/backends.py | 11 | ||||
| -rw-r--r-- | mesonbuild/build.py | 5 | ||||
| -rw-r--r-- | mesonbuild/utils/universal.py | 9 |
3 files changed, 16 insertions, 9 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4e0cc0839..ac7104fc9 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -1582,7 +1582,7 @@ class Backend: def eval_custom_target_command( self, target: build.CustomTarget, absolute_outputs: bool = False) -> \ - T.Tuple[T.List[str], T.List[str], T.List[str]]: + T.Tuple[T.List[str], T.List[str], T.List[str | programs.ExternalProgram]]: # We want the outputs to be absolute only when using the VS backend # XXX: Maybe allow the vs backend to use relative paths too? source_root = self.build_to_src @@ -1595,7 +1595,7 @@ class Backend: outputs = [os.path.join(outdir, i) for i in target.get_outputs()] inputs = self.get_custom_target_sources(target) # Evaluate the command list - cmd: T.List[str] = [] + cmd: T.List[str | programs.ExternalProgram] = [] for i in target.command: if isinstance(i, build.BuildTarget): cmd += self.build_target_to_cmd_array(i) @@ -1631,6 +1631,9 @@ class Backend: if not target.absolute_paths: pdir = self.get_target_private_dir(target) i = i.replace('@PRIVATE_DIR@', pdir) + elif isinstance(i, programs.ExternalProgram): + # Let it pass and be extended elsewhere + pass else: raise RuntimeError(f'Argument {i} is of unknown type {type(i)}') cmd.append(i) @@ -1655,7 +1658,7 @@ class Backend: # fixed. # # https://github.com/mesonbuild/meson/pull/737 - cmd = [i.replace('\\', '/') for i in cmd] + cmd = [i.replace('\\', '/') if isinstance(i, str) else i for i in cmd] return inputs, outputs, cmd def get_introspect_command(self) -> str: @@ -2016,6 +2019,8 @@ class Backend: compiler += [j] elif isinstance(j, (build.BuildTarget, build.CustomTarget)): compiler += j.get_outputs() + elif isinstance(j, programs.ExternalProgram): + compiler += j.get_command() else: raise RuntimeError(f'Type "{type(j).__name__}" is not supported in get_introspection_data. This is a bug') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index f4183b522..d38abcbb5 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2576,7 +2576,7 @@ class CommandBase: subproject: str def flatten_command(self, cmd: T.Sequence[T.Union[str, File, programs.ExternalProgram, BuildTargetTypes]]) -> \ - T.List[T.Union[str, File, BuildTarget, 'CustomTarget']]: + T.List[T.Union[str, File, BuildTarget, CustomTarget, programs.ExternalProgram]]: cmd = listify(cmd) final_cmd: T.List[T.Union[str, File, BuildTarget, 'CustomTarget']] = [] for c in cmd: @@ -2593,7 +2593,8 @@ class CommandBase: # Can only add a dependency on an external program which we # know the absolute path of self.depend_files.append(File.from_absolute_file(path)) - final_cmd += c.get_command() + # Do NOT flatten -- it is needed for later parsing + final_cmd.append(c) elif isinstance(c, (BuildTarget, CustomTarget)): self.dependencies.append(c) final_cmd.append(c) diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index d165bf54d..f3b4355bf 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -38,6 +38,7 @@ if T.TYPE_CHECKING: from ..environment import Environment from ..compilers.compilers import Compiler from ..interpreterbase.baseobjects import SubProject + from .. import programs class _EnvPickleLoadable(Protocol): @@ -1738,7 +1739,7 @@ def Popen_safe_logged(args: T.List[str], msg: str = 'Called', **kwargs: T.Any) - return p, o, e -def iter_regexin_iter(regexiter: T.Iterable[str], initer: T.Iterable[str]) -> T.Optional[str]: +def iter_regexin_iter(regexiter: T.Iterable[str], initer: T.Iterable[str | programs.ExternalProgram]) -> T.Optional[str]: ''' Takes each regular expression in @regexiter and tries to search for it in every item in @initer. If there is a match, returns that match. @@ -1754,7 +1755,7 @@ def iter_regexin_iter(regexiter: T.Iterable[str], initer: T.Iterable[str]) -> T. return None -def _substitute_values_check_errors(command: T.List[str], values: T.Dict[str, T.Union[str, T.List[str]]]) -> None: +def _substitute_values_check_errors(command: T.List[str | programs.ExternalProgram], values: T.Dict[str, T.Union[str, T.List[str]]]) -> None: # Error checking inregex: T.List[str] = ['@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@'] outregex: T.List[str] = ['@OUTPUT([0-9]+)?@', '@OUTDIR@'] @@ -1794,7 +1795,7 @@ def _substitute_values_check_errors(command: T.List[str], values: T.Dict[str, T. raise MesonException(m.format(match2.group(), len(values['@OUTPUT@']))) -def substitute_values(command: T.List[str], values: T.Dict[str, T.Union[str, T.List[str]]]) -> T.List[str]: +def substitute_values(command: T.List[str | programs.ExternalProgram], values: T.Dict[str, T.Union[str, T.List[str]]]) -> T.List[str | programs.ExternalProgram]: ''' Substitute the template strings in the @values dict into the list of strings @command and return a new list. For a full list of the templates, @@ -1821,7 +1822,7 @@ def substitute_values(command: T.List[str], values: T.Dict[str, T.Union[str, T.L _substitute_values_check_errors(command, values) # Substitution - outcmd: T.List[str] = [] + outcmd: T.List[str | programs.ExternalProgram] = [] rx_keys = [re.escape(key) for key in values if key not in ('@INPUT@', '@OUTPUT@')] value_rx = re.compile('|'.join(rx_keys)) if rx_keys else None for vv in command: |
