diff options
| author | Florian "sp1rit" <sp1rit@disroot.org> | 2025-05-01 19:07:27 +0200 |
|---|---|---|
| committer | Jussi Pakkanen <jussi.pakkanen@mailbox.org> | 2025-05-22 12:23:55 +0300 |
| commit | 7f1437a928d4282e45991ff6145dee8a9043be2f (patch) | |
| tree | 2d2a7252feddc0b7b9a60368ad77f6f8c9d609bb /mesonbuild | |
| parent | e8c715786d85dcdbc367f3e379acae25a899c235 (diff) | |
| download | meson-7f1437a928d4282e45991ff6145dee8a9043be2f.tar.gz | |
support .version() for overridden executables
Also ensure that .get_version() can be called on the output of
_find_tool by the modules (kind of required for #14422).
Diffstat (limited to 'mesonbuild')
| -rw-r--r-- | mesonbuild/build.py | 14 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 7 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreterobjects.py | 11 | ||||
| -rw-r--r-- | mesonbuild/interpreter/mesonmain.py | 2 | ||||
| -rw-r--r-- | mesonbuild/modules/__init__.py | 4 |
5 files changed, 32 insertions, 6 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index d38abcbb5..73f99cb66 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -275,7 +275,7 @@ class Build: self.stdlibs = PerMachine({}, {}) self.test_setups: T.Dict[str, TestSetup] = {} self.test_setup_default_name = None - self.find_overrides: T.Dict[str, T.Union['Executable', programs.ExternalProgram, programs.OverrideProgram]] = {} + self.find_overrides: T.Dict[str, T.Union['OverrideExecutable', programs.ExternalProgram, programs.OverrideProgram]] = {} self.searched_programs: T.Set[str] = set() # The list of all programs that have been searched for. # If we are doing a cross build we need two caches, if we're doing a @@ -3116,6 +3116,18 @@ class ConfigurationData(HoldableObject): def keys(self) -> T.Iterator[str]: return self.values.keys() +class OverrideExecutable(Executable): + def __init__(self, executable: Executable, version: str): + self._executable = executable + self._version = version + + def __getattr__(self, name: str) -> T.Any: + _executable = object.__getattribute__(self, '_executable') + return getattr(_executable, name) + + def get_version(self, interpreter: T.Optional[Interpreter] = None) -> str: + return self._version + # A bit poorly named, but this represents plain data files to copy # during install. @dataclass(eq=False) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 4d1d86b72..750e54742 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -426,6 +426,7 @@ class Interpreter(InterpreterBase, HoldableObject): build.Generator: OBJ.GeneratorHolder, build.GeneratedList: OBJ.GeneratedListHolder, build.ExtractedObjects: OBJ.GeneratedObjectsHolder, + build.OverrideExecutable: OBJ.OverrideExecutableHolder, build.RunTarget: OBJ.RunTargetHolder, build.AliasTarget: OBJ.AliasTargetHolder, build.Headers: OBJ.HeadersHolder, @@ -1592,7 +1593,7 @@ class Interpreter(InterpreterBase, HoldableObject): def program_from_overrides(self, command_names: T.List[mesonlib.FileOrString], extra_info: T.List['mlog.TV_Loggable'] - ) -> T.Optional[T.Union[ExternalProgram, OverrideProgram, build.Executable]]: + ) -> T.Optional[T.Union[ExternalProgram, OverrideProgram, build.OverrideExecutable]]: for name in command_names: if not isinstance(name, str): continue @@ -1607,7 +1608,7 @@ class Interpreter(InterpreterBase, HoldableObject): if isinstance(name, str): self.build.searched_programs.add(name) - def add_find_program_override(self, name: str, exe: T.Union[build.Executable, ExternalProgram, 'OverrideProgram']) -> None: + def add_find_program_override(self, name: str, exe: T.Union[build.OverrideExecutable, ExternalProgram, 'OverrideProgram']) -> None: if name in self.build.searched_programs: raise InterpreterException(f'Tried to override finding of executable "{name}" which has already been found.') if name in self.build.find_overrides: @@ -1632,7 +1633,7 @@ class Interpreter(InterpreterBase, HoldableObject): 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']: + ) -> T.Union['ExternalProgram', 'build.OverrideExecutable', 'OverrideProgram']: args = mesonlib.listify(args) extra_info: T.List[mlog.TV_Loggable] = [] diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index a2fadbefc..af1322d0e 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -1142,3 +1142,14 @@ class StructuredSourcesHolder(ObjectHolder[build.StructuredSources]): def __init__(self, sources: build.StructuredSources, interp: 'Interpreter'): super().__init__(sources, interp) + +class OverrideExecutableHolder(BuildTargetHolder[build.OverrideExecutable]): + def __init__(self, exe: build.OverrideExecutable, interpreter: 'Interpreter') -> None: + super().__init__(exe, interpreter) + self.methods.update({'version': self.version_method}) + + @noPosargs + @noKwargs + @FeatureNew('OverrideExecutable.version', '1.9.0') + def version_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str: + return self.held_object.get_version(self.interpreter) diff --git a/mesonbuild/interpreter/mesonmain.py b/mesonbuild/interpreter/mesonmain.py index 8ede6916a..cc71104cf 100644 --- a/mesonbuild/interpreter/mesonmain.py +++ b/mesonbuild/interpreter/mesonmain.py @@ -335,6 +335,8 @@ class MesonMain(MesonInterpreterObject): if not os.path.exists(abspath): raise InterpreterException(f'Tried to override {name} with a file that does not exist.') exe = OverrideProgram(name, self.interpreter.project_version, command=[abspath]) + elif isinstance(exe, build.Executable): + exe = build.OverrideExecutable(exe, self.interpreter.project_version) self.interpreter.add_find_program_override(name, exe) @typed_kwargs( diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 67d16661a..87892e6d7 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -75,14 +75,14 @@ class ModuleState: required: bool = True, version_func: T.Optional[ProgramVersionFunc] = None, wanted: T.Union[str, T.List[str]] = '', silent: bool = False, - for_machine: MachineChoice = MachineChoice.HOST) -> T.Union[ExternalProgram, build.Executable, OverrideProgram]: + for_machine: MachineChoice = MachineChoice.HOST) -> T.Union[ExternalProgram, build.OverrideExecutable, OverrideProgram]: if not isinstance(prog, list): prog = [prog] return self._interpreter.find_program_impl(prog, required=required, version_func=version_func, wanted=wanted, silent=silent, for_machine=for_machine) def find_tool(self, name: str, depname: str, varname: str, required: bool = True, - wanted: T.Optional[str] = None) -> T.Union['build.Executable', ExternalProgram, 'OverrideProgram']: + wanted: T.Optional[str] = None) -> T.Union[build.OverrideExecutable, ExternalProgram, 'OverrideProgram']: # Look in overrides in case it's built as subproject progobj = self._interpreter.program_from_overrides([name], []) if progobj is not None: |
