summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py11
-rw-r--r--mesonbuild/build.py5
-rw-r--r--mesonbuild/utils/universal.py9
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: