aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2024-06-22 10:59:05 -0500
committerJussi Pakkanen <jpakkane@gmail.com>2024-06-23 15:10:42 +0300
commit9be6e653d49957c974af2c171257cbaf942abbb9 (patch)
tree788b00fc4997ec587ccc64e21cba1b7d7f030dc1
parenta111c28ecef721af960721c26b40f4e5108760c7 (diff)
downloadmeson-9be6e653d49957c974af2c171257cbaf942abbb9.zip
meson-9be6e653d49957c974af2c171257cbaf942abbb9.tar.gz
meson-9be6e653d49957c974af2c171257cbaf942abbb9.tar.bz2
find_program: add a kwarg to specify custom version argument
When trying to get the version of a program, meson was previously hardcoded to run the binary with `--version`. This does work with the vast majority of programs, but there are a few outliers (e.g. ffmpeg) which have an unusual argument for printing out the version. Support these programs by introducing a version_argument kwarg in find_program which allows users to override `--version` with whatever the custom argument for printing the version may be for the program.
-rw-r--r--docs/markdown/snippets/find_program_version_argument.md12
-rw-r--r--docs/yaml/functions/find_program.yaml9
-rw-r--r--mesonbuild/dependencies/python.py1
-rw-r--r--mesonbuild/interpreter/interpreter.py9
-rw-r--r--mesonbuild/programs.py5
-rw-r--r--test cases/common/26 find program/meson.build3
-rw-r--r--test cases/common/26 find program/print-version-custom-argument.py8
7 files changed, 42 insertions, 5 deletions
diff --git a/docs/markdown/snippets/find_program_version_argument.md b/docs/markdown/snippets/find_program_version_argument.md
new file mode 100644
index 0000000..99fe621
--- /dev/null
+++ b/docs/markdown/snippets/find_program_version_argument.md
@@ -0,0 +1,12 @@
+## New version_argument kwarg for find_program
+
+When finding an external program with `find_program`, the `version_argument`
+can be used to override the default `--version` argument when trying to parse
+the version of the program.
+
+For example, if the following is used:
+```meson
+foo = find_program('foo', version_argument: '-version')
+```
+
+meson will internally run `foo -version` when trying to find the version of `foo`.
diff --git a/docs/yaml/functions/find_program.yaml b/docs/yaml/functions/find_program.yaml
index 4a17e86..1899941 100644
--- a/docs/yaml/functions/find_program.yaml
+++ b/docs/yaml/functions/find_program.yaml
@@ -102,13 +102,20 @@ kwargs:
since: 0.52.0
description: |
Specifies the required version, see
- [[dependency]] for argument format. The version of the program
+ [[dependency]] for argument format. By default, the version of the program
is determined by running `program_name --version` command. If stdout is empty
it fallbacks to stderr. If the output contains more text than simply a version
number, only the first occurrence of numbers separated by dots is kept.
If the output is more complicated than that, the version checking will have to
be done manually using [[run_command]].
+ version_argument:
+ type: str
+ since: 1.5.0
+ description: |
+ Specifies the argument to pass when trying to find the version of the program.
+ If this is unspecified, `program_name --version` will be used.
+
dirs:
type: list[str]
since: 0.53.0
diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py
index 851c630..db4944b 100644
--- a/mesonbuild/dependencies/python.py
+++ b/mesonbuild/dependencies/python.py
@@ -83,6 +83,7 @@ class BasicPythonExternalProgram(ExternalProgram):
self.command = ext_prog.command
self.path = ext_prog.path
self.cached_version = None
+ self.version_arg = '--version'
# We want strong key values, so we always populate this with bogus data.
# Otherwise to make the type checkers happy we'd have to do .get() for
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 83363fb..13f7f22 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -1642,12 +1642,13 @@ class Interpreter(InterpreterBase, HoldableObject):
required: bool = True, silent: bool = True,
wanted: T.Union[str, T.List[str]] = '',
search_dirs: T.Optional[T.List[str]] = None,
+ version_arg: T.Optional[str] = '',
version_func: T.Optional[ProgramVersionFunc] = None
) -> T.Union['ExternalProgram', 'build.Executable', 'OverrideProgram']:
args = mesonlib.listify(args)
extra_info: T.List[mlog.TV_Loggable] = []
- progobj = self.program_lookup(args, for_machine, default_options, required, search_dirs, wanted, version_func, extra_info)
+ progobj = self.program_lookup(args, for_machine, default_options, required, search_dirs, wanted, version_arg, version_func, extra_info)
if progobj is None or not self.check_program_version(progobj, wanted, version_func, extra_info):
progobj = self.notfound_program(args)
@@ -1672,6 +1673,7 @@ class Interpreter(InterpreterBase, HoldableObject):
required: bool,
search_dirs: T.List[str],
wanted: T.Union[str, T.List[str]],
+ version_arg: T.Optional[str],
version_func: T.Optional[ProgramVersionFunc],
extra_info: T.List[mlog.TV_Loggable]
) -> T.Optional[T.Union[ExternalProgram, build.Executable, OverrideProgram]]:
@@ -1697,6 +1699,8 @@ class Interpreter(InterpreterBase, HoldableObject):
prog = ExternalProgram('python3', mesonlib.python_command, silent=True)
progobj = prog if prog.found() else None
+ if isinstance(progobj, ExternalProgram) and version_arg:
+ progobj.version_arg = version_arg
if progobj and not self.check_program_version(progobj, wanted, version_func, extra_info):
progobj = None
@@ -1756,6 +1760,7 @@ class Interpreter(InterpreterBase, HoldableObject):
REQUIRED_KW,
KwargInfo('dirs', ContainerTypeInfo(list, str), default=[], listify=True, since='0.53.0'),
KwargInfo('version', ContainerTypeInfo(list, str), default=[], listify=True, since='0.52.0'),
+ KwargInfo('version_argument', str, default='', since='1.5.0'),
DEFAULT_OPTIONS.evolve(since='1.3.0')
)
@disablerIfNotFound
@@ -1770,7 +1775,7 @@ class Interpreter(InterpreterBase, HoldableObject):
search_dirs = extract_search_dirs(kwargs)
default_options = kwargs['default_options']
return self.find_program_impl(args[0], kwargs['native'], default_options=default_options, required=required,
- silent=False, wanted=kwargs['version'],
+ silent=False, wanted=kwargs['version'], version_arg=kwargs['version_argument'],
search_dirs=search_dirs)
# When adding kwargs, please check if they make sense in dependencies.get_dep_identifier()
diff --git a/mesonbuild/programs.py b/mesonbuild/programs.py
index b73f9e4..fbe241d 100644
--- a/mesonbuild/programs.py
+++ b/mesonbuild/programs.py
@@ -36,6 +36,7 @@ class ExternalProgram(mesonlib.HoldableObject):
self.name = name
self.path: T.Optional[str] = None
self.cached_version: T.Optional[str] = None
+ self.version_arg = '--version'
if command is not None:
self.command = mesonlib.listify(command)
if mesonlib.is_windows():
@@ -93,9 +94,9 @@ class ExternalProgram(mesonlib.HoldableObject):
def get_version(self, interpreter: T.Optional['Interpreter'] = None) -> str:
if not self.cached_version:
- raw_cmd = self.get_command() + ['--version']
+ raw_cmd = self.get_command() + [self.version_arg]
if interpreter:
- res = interpreter.run_command_impl((self, ['--version']),
+ res = interpreter.run_command_impl((self, [self.version_arg]),
{'capture': True,
'check': True,
'env': mesonlib.EnvironmentVariables()},
diff --git a/test cases/common/26 find program/meson.build b/test cases/common/26 find program/meson.build
index 3c4d15c..a20f6b4 100644
--- a/test cases/common/26 find program/meson.build
+++ b/test cases/common/26 find program/meson.build
@@ -32,6 +32,9 @@ assert(prog.version() == '1.0', 'Program version should be detectable')
prog = find_program('print-version-with-prefix.py', version : '>=1.0')
assert(prog.found(), 'Program version should match')
+prog = find_program('print-version-custom-argument.py', version : '>=1.0', version_argument : '-version')
+assert(prog.found(), 'Program version should match')
+
prog = find_program('test_subdir.py', required : false)
assert(not prog.found(), 'Program should not be found')
diff --git a/test cases/common/26 find program/print-version-custom-argument.py b/test cases/common/26 find program/print-version-custom-argument.py
new file mode 100644
index 0000000..7d9ad58
--- /dev/null
+++ b/test cases/common/26 find program/print-version-custom-argument.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys
+
+if len(sys.argv) != 2 or sys.argv[1] != '-version':
+ exit(1)
+
+print('1.0')