summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Brunet <charles.brunet@optelgroup.com>2024-02-23 11:40:15 -0500
committerDylan Baker <dylan@pnwbakers.com>2024-02-24 09:08:20 -0800
commit11f2e07071d062f31a69de531faa0a5d68b1f5bc (patch)
tree0361645f1bed81d4a76ff3cbbda9399168221706
parent8ba0ea68017b489b0a461abbd375f319dc7a48f3 (diff)
downloadmeson-11f2e07071d062f31a69de531faa0a5d68b1f5bc.tar.gz
Allow using CustomTarget as test executable
Fixes #6567
-rw-r--r--docs/markdown/snippets/test_using_custom_target_executable.md4
-rw-r--r--docs/yaml/functions/benchmark.yaml5
-rw-r--r--mesonbuild/backend/backends.py4
-rw-r--r--mesonbuild/interpreter/interpreter.py17
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py4
-rw-r--r--mesonbuild/mtest.py5
-rw-r--r--test cases/common/273 customtarget exe for test/generate.py14
-rw-r--r--test cases/common/273 customtarget exe for test/meson.build14
8 files changed, 56 insertions, 11 deletions
diff --git a/docs/markdown/snippets/test_using_custom_target_executable.md b/docs/markdown/snippets/test_using_custom_target_executable.md
new file mode 100644
index 000000000..e8b08da6b
--- /dev/null
+++ b/docs/markdown/snippets/test_using_custom_target_executable.md
@@ -0,0 +1,4 @@
+## Use `custom_target` as test executable
+
+The [[test]] function now accepts [[@custom_tgt]] and [[@custom_idx]] for the
+command to execute.
diff --git a/docs/yaml/functions/benchmark.yaml b/docs/yaml/functions/benchmark.yaml
index 9d0ca3116..0323b26e4 100644
--- a/docs/yaml/functions/benchmark.yaml
+++ b/docs/yaml/functions/benchmark.yaml
@@ -22,8 +22,9 @@ posargs:
description: The *unique* test id
executable:
- type: exe | jar | external_program | file
- description: The program to execute
+ type: exe | jar | external_program | file | custom_tgt | custom_idx
+ description: |
+ The program to execute. *(Since 1.4.0)* A CustomTarget is also accepted.
kwargs:
args:
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 92cc9fb51..c3be900ab 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -1160,7 +1160,7 @@ class Backend:
return results
def determine_windows_extra_paths(
- self, target: T.Union[build.BuildTarget, build.CustomTarget, programs.ExternalProgram, mesonlib.File, str],
+ self, target: T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, programs.ExternalProgram, mesonlib.File, str],
extra_bdeps: T.Sequence[T.Union[build.BuildTarget, build.CustomTarget]]) -> T.List[str]:
"""On Windows there is no such thing as an rpath.
@@ -1269,7 +1269,7 @@ class Backend:
t.is_parallel, cmd_args, t_env,
t.should_fail, t.timeout, t.workdir,
extra_paths, t.protocol, t.priority,
- isinstance(exe, build.Target),
+ isinstance(exe, (build.Target, build.CustomTargetIndex)),
isinstance(exe, build.Executable),
[x.get_id() for x in depends],
self.environment.coredata.version,
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 5603b9937..aaffec0b9 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -2151,17 +2151,17 @@ class Interpreter(InterpreterBase, HoldableObject):
self.generators.append(gen)
return gen
- @typed_pos_args('benchmark', str, (build.Executable, build.Jar, ExternalProgram, mesonlib.File))
+ @typed_pos_args('benchmark', str, (build.Executable, build.Jar, ExternalProgram, mesonlib.File, build.CustomTarget, build.CustomTargetIndex))
@typed_kwargs('benchmark', *TEST_KWS)
def func_benchmark(self, node: mparser.BaseNode,
args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
kwargs: 'kwtypes.FuncBenchmark') -> None:
self.add_test(node, args, kwargs, False)
- @typed_pos_args('test', str, (build.Executable, build.Jar, ExternalProgram, mesonlib.File))
+ @typed_pos_args('test', str, (build.Executable, build.Jar, ExternalProgram, mesonlib.File, build.CustomTarget, build.CustomTargetIndex))
@typed_kwargs('test', *TEST_KWS, KwargInfo('is_parallel', bool, default=True))
def func_test(self, node: mparser.BaseNode,
- args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
+ args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File, build.CustomTarget, build.CustomTargetIndex]],
kwargs: 'kwtypes.FuncTest') -> None:
self.add_test(node, args, kwargs, True)
@@ -2175,7 +2175,7 @@ class Interpreter(InterpreterBase, HoldableObject):
return ENV_KW.convertor(envlist)
def make_test(self, node: mparser.BaseNode,
- args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
+ args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File, build.CustomTarget, build.CustomTargetIndex]],
kwargs: 'kwtypes.BaseTest') -> Test:
name = args[0]
if ':' in name:
@@ -2188,6 +2188,10 @@ class Interpreter(InterpreterBase, HoldableObject):
raise InvalidArguments('Tried to use not-found external program as test exe')
elif isinstance(exe, mesonlib.File):
exe = self.find_program_impl([exe])
+ elif isinstance(exe, build.CustomTarget):
+ kwargs.setdefault('depends', []).append(exe)
+ elif isinstance(exe, build.CustomTargetIndex):
+ kwargs.setdefault('depends', []).append(exe.target)
env = self.unpack_env_kwarg(kwargs)
@@ -2218,8 +2222,11 @@ class Interpreter(InterpreterBase, HoldableObject):
kwargs['verbose'])
def add_test(self, node: mparser.BaseNode,
- args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
+ args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File, build.CustomTarget, build.CustomTargetIndex]],
kwargs: T.Dict[str, T.Any], is_base_test: bool):
+ if isinstance(args[1], (build.CustomTarget, build.CustomTargetIndex)):
+ FeatureNew.single_use('test with CustomTarget as command', '1.4.0', self.subproject)
+
t = self.make_test(node, args, kwargs)
if is_base_test:
self.build.tests.append(t)
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index 9aefc2f97..28e7170c9 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -742,7 +742,7 @@ class GeneratedObjectsHolder(ObjectHolder[build.ExtractedObjects]):
class Test(MesonInterpreterObject):
def __init__(self, name: str, project: str, suite: T.List[str],
- exe: T.Union[ExternalProgram, build.Executable, build.CustomTarget],
+ exe: T.Union[ExternalProgram, build.Executable, build.CustomTarget, build.CustomTargetIndex],
depends: T.List[T.Union[build.CustomTarget, build.BuildTarget]],
is_parallel: bool,
cmd_args: T.List[T.Union[str, mesonlib.File, build.Target]],
@@ -765,7 +765,7 @@ class Test(MesonInterpreterObject):
self.priority = priority
self.verbose = verbose
- def get_exe(self) -> T.Union[ExternalProgram, build.Executable, build.CustomTarget]:
+ def get_exe(self) -> T.Union[ExternalProgram, build.Executable, build.CustomTarget, build.CustomTargetIndex]:
return self.exe
def get_name(self) -> str:
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index b43f165ed..21414d2c5 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -1458,6 +1458,11 @@ class SingleTestRunner:
'found. Please check the command and/or add it to PATH.')
raise TestException(msg.format(self.test.exe_wrapper.name))
return self.test.exe_wrapper.get_command() + self.test.fname
+ elif self.test.cmd_is_built and not self.test.cmd_is_exe and is_windows():
+ test_cmd = ExternalProgram._shebang_to_cmd(self.test.fname[0])
+ if test_cmd is not None:
+ test_cmd += self.test.fname[1:]
+ return test_cmd
return self.test.fname
def _get_cmd(self) -> T.Optional[T.List[str]]:
diff --git a/test cases/common/273 customtarget exe for test/generate.py b/test cases/common/273 customtarget exe for test/generate.py
new file mode 100644
index 000000000..e66f1db70
--- /dev/null
+++ b/test cases/common/273 customtarget exe for test/generate.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+program = '''#!/usr/bin/env python3
+
+raise SystemExit({})
+'''
+
+for i, a in enumerate(sys.argv[1:]):
+ with open(a, 'w') as f:
+ print(program.format(i), file=f)
+ os.chmod(a, 0o755)
diff --git a/test cases/common/273 customtarget exe for test/meson.build b/test cases/common/273 customtarget exe for test/meson.build
new file mode 100644
index 000000000..089d70dee
--- /dev/null
+++ b/test cases/common/273 customtarget exe for test/meson.build
@@ -0,0 +1,14 @@
+project('test customtarget')
+
+ct1 = custom_target(
+ command: ['generate.py', '@OUTPUT@'],
+ output: 'a.py',
+)
+ct2 = custom_target(
+ command: ['generate.py', '@OUTPUT@'],
+ output: ['b.py', 'c.py'],
+)
+
+test('using_custom_target', ct1)
+test('using_custom_target_index', ct2[0])
+test('using_custom_target_index_1', ct2[1], should_fail: true)