diff options
author | Dudemanguy <random342@airmail.cc> | 2024-06-22 10:59:05 -0500 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2024-06-23 15:10:42 +0300 |
commit | 9be6e653d49957c974af2c171257cbaf942abbb9 (patch) | |
tree | 788b00fc4997ec587ccc64e21cba1b7d7f030dc1 | |
parent | a111c28ecef721af960721c26b40f4e5108760c7 (diff) | |
download | meson-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.md | 12 | ||||
-rw-r--r-- | docs/yaml/functions/find_program.yaml | 9 | ||||
-rw-r--r-- | mesonbuild/dependencies/python.py | 1 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 9 | ||||
-rw-r--r-- | mesonbuild/programs.py | 5 | ||||
-rw-r--r-- | test cases/common/26 find program/meson.build | 3 | ||||
-rw-r--r-- | test cases/common/26 find program/print-version-custom-argument.py | 8 |
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') |