diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2019-05-09 21:42:53 -0400 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2019-05-16 00:27:57 +0300 |
commit | 957d8e051c0c29beb0106e75ae7a71acc5c62cf5 (patch) | |
tree | 19bb30d1cca5db43b7f540b718a9607a23a6d96a /mesonbuild/mesonlib.py | |
parent | 38b347ecd026b8b0f6b533392a23aeeda5221713 (diff) | |
download | meson-957d8e051c0c29beb0106e75ae7a71acc5c62cf5.zip meson-957d8e051c0c29beb0106e75ae7a71acc5c62cf5.tar.gz meson-957d8e051c0c29beb0106e75ae7a71acc5c62cf5.tar.bz2 |
Make `PerMachine` and `MachineChoice` have just `build` and `host`
Meson itself *almost* only cares about the build and host platforms. The
exception is it takes a `target_machine` in the cross file and exposes
it to the user; but it doesn't do anything else with it. It's therefore
overkill to put target in `PerMachine` and `MachineChoice`. Instead, we
make a `PerThreeMachine` only for the machine infos.
Additionally fix a few other things that were bugging me in the process:
- Get rid of `MachineInfos` class. Since `envconfig.py` was created, it
has no methods that couldn't just got on `PerMachine`
- Make `default_missing` and `miss_defaulting` work functionally. That
means we can just locally bind rather than bind as class vars the
"unfrozen" configuration. This helps prevent bugs where one forgets
to freeze a configuration.
Diffstat (limited to 'mesonbuild/mesonlib.py')
-rw-r--r-- | mesonbuild/mesonlib.py | 97 |
1 files changed, 90 insertions, 7 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 07beb69..f53197b 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -313,37 +313,120 @@ class OrderedEnum(Enum): return self.value < other.value return NotImplemented + class MachineChoice(OrderedEnum): - """Enum class representing one of the three possible values for binaries, - the build, host, and target machines. + """Enum class representing one of the two abstract machine names used in + most places: the build, and host, machines. """ BUILD = 0 HOST = 1 - TARGET = 2 + class PerMachine(typing.Generic[_T]): - def __init__(self, build: _T, host: _T, target: _T): + def __init__(self, build: _T, host: _T): self.build = build self.host = host - self.target = target def __getitem__(self, machine: MachineChoice) -> _T: return { MachineChoice.BUILD: self.build, MachineChoice.HOST: self.host, - MachineChoice.TARGET: self.target }[machine] def __setitem__(self, machine: MachineChoice, val: _T) -> None: key = { MachineChoice.BUILD: 'build', MachineChoice.HOST: 'host', - MachineChoice.TARGET: 'target' }[machine] setattr(self, key, val) + def miss_defaulting(self) -> "PerMachineDefaultable[typing.Optional[_T]]": + """Unset definition duplicated from their previous to None + + This is the inverse of ''default_missing''. By removing defaulted + machines, we can elaborate the original and then redefault them and thus + avoid repeating the elaboration explicitly. + """ + unfreeze = PerMachineDefaultable() # type: PerMachineDefaultable[typing.Optional[_T]] + unfreeze.build = self.build + unfreeze.host = self.host + if unfreeze.host == unfreeze.build: + unfreeze.host = None + return unfreeze + + +class PerThreeMachine(PerMachine[_T]): + """Like `PerMachine` but includes `target` too. + + It turns out just one thing do we need track the target machine. There's no + need to computer the `target` field so we don't bother overriding the + `__getitem__`/`__setitem__` methods. + """ + def __init__(self, build: _T, host: _T, target: _T): + super().__init__(build, host) + self.target = target + + def miss_defaulting(self) -> "PerThreeMachineDefaultable[typing.Optional[_T]]": + """Unset definition duplicated from their previous to None + + This is the inverse of ''default_missing''. By removing defaulted + machines, we can elaborate the original and then redefault them and thus + avoid repeating the elaboration explicitly. + """ + unfreeze = PerThreeMachineDefaultable() # type: PerThreeMachineDefaultable[typing.Optional[_T]] + unfreeze.build = self.build + unfreeze.host = self.host + unfreeze.target = self.target + if unfreeze.target == unfreeze.host: + unfreeze.target = None + if unfreeze.host == unfreeze.build: + unfreeze.host = None + return unfreeze + + def matches_build_machine(self, machine: MachineChoice) -> bool: + return self.build == self[machine] + +class PerMachineDefaultable(PerMachine[typing.Optional[_T]]): + """Extends `PerMachine` with the ability to default from `None`s. + """ + def __init__(self) -> None: + super().__init__(None, None) + + def default_missing(self) -> "PerMachine[typing.Optional[_T]]": + """Default host to buid + + This allows just specifying nothing in the native case, and just host in the + cross non-compiler case. + """ + freeze = PerMachine(self.build, self.host) + if freeze.host is None: + freeze.host = freeze.build + return freeze + + +class PerThreeMachineDefaultable(PerMachineDefaultable, PerThreeMachine[typing.Optional[_T]]): + """Extends `PerThreeMachine` with the ability to default from `None`s. + """ + def __init__(self) -> None: + PerThreeMachine.__init__(self, None, None, None) + + def default_missing(self) -> "PerThreeMachine[typing.Optional[_T]]": + """Default host to buid and target to host. + + This allows just specifying nothing in the native case, just host in the + cross non-compiler case, and just target in the native-built + cross-compiler case. + """ + freeze = PerThreeMachine(self.build, self.host, self.target) + if freeze.host is None: + freeze.host = freeze.build + if freeze.target is None: + freeze.target = freeze.host + return freeze + + def is_sunos() -> bool: return platform.system().lower() == 'sunos' |