aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/mesonlib.py
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2019-05-09 21:42:53 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2019-05-16 00:27:57 +0300
commit957d8e051c0c29beb0106e75ae7a71acc5c62cf5 (patch)
tree19bb30d1cca5db43b7f540b718a9607a23a6d96a /mesonbuild/mesonlib.py
parent38b347ecd026b8b0f6b533392a23aeeda5221713 (diff)
downloadmeson-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.py97
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'