summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/add_external-program_cmd-array.md11
-rw-r--r--docs/yaml/objects/external_program.yaml5
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py11
-rw-r--r--test cases/common/26 find program/meson.build20
4 files changed, 46 insertions, 1 deletions
diff --git a/docs/markdown/snippets/add_external-program_cmd-array.md b/docs/markdown/snippets/add_external-program_cmd-array.md
new file mode 100644
index 000000000..f4d7a6c0e
--- /dev/null
+++ b/docs/markdown/snippets/add_external-program_cmd-array.md
@@ -0,0 +1,11 @@
+## Add cmd_array method to ExternalProgram
+
+Added a new `cmd_array()` method to the `ExternalProgram` object that returns
+an array containing the command(s) for the program. This is particularly useful
+in cases like pyInstaller where the Python command is `meson.exe runpython`,
+and the full path should not be used but rather the command array.
+
+The method returns a list of strings representing the complete command needed
+to execute the external program, which may differ from just the full path
+returned by `full_path()` in cases where wrapper commands or interpreters are
+involved.
diff --git a/docs/yaml/objects/external_program.yaml b/docs/yaml/objects/external_program.yaml
index 4c24497a9..db5d39fab 100644
--- a/docs/yaml/objects/external_program.yaml
+++ b/docs/yaml/objects/external_program.yaml
@@ -56,3 +56,8 @@ methods:
```meson
run_command(find_program('foo'), 'arg1', 'arg2')
```
+
+- name: cmd_array
+ returns: array[str]
+ description: Returns an array containing the command(s) for the program.
+ since: 1.10.0
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index 1005fc273..3bdbcb93e 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -669,6 +669,17 @@ class _ExternalProgramHolder(ObjectHolder[_EXTPROG]):
@noPosargs
@noKwargs
+ @FeatureNew('ExternalProgram.cmd_array', '1.10.0')
+ @InterpreterObject.method('cmd_array')
+ def cmd_array_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.List[str]:
+ if not self.found():
+ raise InterpreterException('Unable to get the path of a not-found external program')
+ cmd = self.held_object.get_command()
+ assert cmd is not None
+ return cmd
+
+ @noPosargs
+ @noKwargs
@FeatureNew('ExternalProgram.version', '0.62.0')
@InterpreterObject.method('version')
def version_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
diff --git a/test cases/common/26 find program/meson.build b/test cases/common/26 find program/meson.build
index a20f6b45a..72d311c41 100644
--- a/test cases/common/26 find program/meson.build
+++ b/test cases/common/26 find program/meson.build
@@ -1,4 +1,4 @@
-project('find program')
+project('find program', meson_version: '>= 1.10.0',)
if build_machine.system() == 'windows'
# Things Windows does not provide:
@@ -40,3 +40,21 @@ assert(not prog.found(), 'Program should not be found')
prog = find_program('test_subdir.py', dirs : ['/nonexistent', meson.current_source_dir() / 'scripts'])
assert(prog.found(), 'Program should be found')
+
+prog = find_program('print-version.py')
+if build_machine.system() != 'cygwin'
+ assert(prog.cmd_array() != [prog.full_path()])
+ assert(prog.cmd_array().length() == 2)
+endif
+
+ret = run_command(prog.cmd_array(),'--version', check: true)
+assert(ret.returncode() == 0)
+assert(ret.stdout().strip() == '1.0')
+
+if build_machine.system() == 'windows'
+ prog = find_program('cmd.exe')
+ assert(prog.cmd_array() == [prog.full_path()])
+else
+ prog = find_program('ld')
+ assert(prog.cmd_array() == [prog.full_path()])
+endif \ No newline at end of file