ExternalProgram: add cmd_array to complete the offfering

In case of python and especially in the case of pyInstaller
where the python command is meson.exe runpython, it should
not be full path to be used but cmd_array.

Fixing #13834
This commit is contained in:
Stéphane Cerveau
2024-10-30 15:53:52 +01:00
committed by Xavier Claessens
parent 60e3cc1c58
commit 2e0e2663b8
4 changed files with 46 additions and 1 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -667,6 +667,17 @@ class _ExternalProgramHolder(ObjectHolder[_EXTPROG]):
assert path is not None
return path
@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')

View File

@@ -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