Merge pull request #4326 from Ericson2314/per-machine

Start leveraging MachineInfo with for_* methods
pull/4349/head
Jussi Pakkanen 6 years ago committed by GitHub
commit 6f6afe24a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 84
      mesonbuild/environment.py
  2. 111
      mesonbuild/mesonlib.py

@ -17,7 +17,7 @@ import configparser, os, platform, re, sys, shlex, shutil, subprocess
from . import coredata from . import coredata
from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker
from . import mesonlib from . import mesonlib
from .mesonlib import EnvironmentException, Popen_safe from .mesonlib import EnvironmentException, PerMachine, Popen_safe
from . import mlog from . import mlog
from . import compilers from . import compilers
@ -1130,6 +1130,20 @@ class MachineInfo:
self.cpu = cpu self.cpu = cpu
self.endian = endian self.endian = endian
def __eq__(self, other):
if self.__class__ is not other.__class__:
return NotImplemented
return \
self.system == other.system and \
self.cpu_family == other.cpu_family and \
self.cpu == other.cpu and \
self.endian == other.endian
def __ne__(self, other):
if self.__class__ is not other.__class__:
return NotImplemented
return not self.__eq__(other)
@staticmethod @staticmethod
def detect(compilers = None): def detect(compilers = None):
"""Detect the machine we're running on """Detect the machine we're running on
@ -1167,11 +1181,71 @@ class MachineInfo:
literal['cpu'], literal['cpu'],
endian) endian)
class MachineInfos: def is_windows(self):
"""
Machine is windows?
"""
return self.system == 'windows'
def is_cygwin(self):
"""
Machine is cygwin?
"""
return self.system == 'cygwin'
def is_linux(self):
"""
Machine is linux?
"""
return self.system == 'linux'
def is_darwin(self):
"""
Machine is Darwin (iOS/OS X)?
"""
return self.system in ('darwin', 'ios')
def is_android(self):
"""
Machine is Android?
"""
return self.system == 'android'
def is_haiku(self):
"""
Machine is Haiku?
"""
return self.system == 'haiku'
def is_openbsd(self):
"""
Machine is OpenBSD?
"""
return self.system == 'openbsd'
# Various prefixes and suffixes for import libraries, shared libraries,
# static libraries, and executables.
# Versioning is added to these names in the backends as-needed.
def get_exe_suffix(self):
if self.is_windows() or self.is_cygwin():
return 'exe'
else:
return ''
def get_object_suffix(self):
if self.is_windows():
return 'obj'
else:
return 'o'
def libdir_layout_is_win(self):
return self.is_windows() \
or self.is_cygwin()
class MachineInfos(PerMachine):
def __init__(self): def __init__(self):
self.build = None super().__init__(None, None, None)
self.host = None
self.target = None
def default_missing(self): def default_missing(self):
"""Default host to buid and target to host. """Default host to buid and target to host.

@ -20,6 +20,8 @@ import stat
import time import time
import platform, subprocess, operator, os, shutil, re import platform, subprocess, operator, os, shutil, re
import collections import collections
from enum import Enum
from mesonbuild import mlog from mesonbuild import mlog
have_fcntl = False have_fcntl = False
@ -277,6 +279,53 @@ def classify_unity_sources(compilers, sources):
compsrclist[comp].append(src) compsrclist[comp].append(src)
return compsrclist return compsrclist
class OrderedEnum(Enum):
"""
An Enum which additionally offers homogeneous ordered comparison.
"""
def __ge__(self, other):
if self.__class__ is other.__class__:
return self.value >= other.value
return NotImplemented
def __gt__(self, other):
if self.__class__ is other.__class__:
return self.value > other.value
return NotImplemented
def __le__(self, other):
if self.__class__ is other.__class__:
return self.value <= other.value
return NotImplemented
def __lt__(self, other):
if self.__class__ is other.__class__:
return self.value < other.value
return NotImplemented
MachineChoice = OrderedEnum('MachineChoice', ['BUILD', 'HOST', 'TARGET'])
class PerMachine:
def __init__(self, build, host, target):
self.build = build,
self.host = host
self.target = target
def __getitem__(self, machine: MachineChoice):
return {
MachineChoice.BUILD: self.build,
MachineChoice.HOST: self.host,
MachineChoice.TARGET: self.target
}[machine]
def __setitem__(self, machine: MachineChoice, val):
key = {
MachineChoice.BUILD: 'build',
MachineChoice.HOST: 'host',
MachineChoice.TARGET: 'target'
}[machine]
setattr(self, key, val)
def is_osx(): def is_osx():
return platform.system().lower() == 'darwin' return platform.system().lower() == 'darwin'
@ -309,77 +358,93 @@ def is_dragonflybsd():
def is_freebsd(): def is_freebsd():
return platform.system().lower() == 'freebsd' return platform.system().lower() == 'freebsd'
def _get_machine_is_cross(env, is_cross):
"""
This is not morally correct, but works for now. For cross builds the build
and host machines differ. `is_cross == true` means the host machine, while
`is_cross == false` means the build machine. Both are used in practice,
even though the documentation refers to the host machine implying we should
hard-code it. For non-cross builds `is_cross == false` is passed but the
host and build machines are identical so it doesn't matter.
Users for `for_*` should instead specify up front which machine they want
and query that like:
env.machines[MachineChoice.HOST].is_haiku()
"""
for_machine = MachineChoice.HOST if is_cross else MachineChoice.BUILD
return env.machines[for_machine]
def for_windows(is_cross, env): def for_windows(is_cross, env):
""" """
Host machine is windows? Host machine is windows?
Deprecated: Please use `env.machines[for_machine].is_windows()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_windows()
return is_windows()
return env.cross_info.get_host_system() == 'windows'
def for_cygwin(is_cross, env): def for_cygwin(is_cross, env):
""" """
Host machine is cygwin? Host machine is cygwin?
Deprecated: Please use `env.machines[for_machine].is_cygwin()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_cygwin()
return is_cygwin()
return env.cross_info.get_host_system() == 'cygwin'
def for_linux(is_cross, env): def for_linux(is_cross, env):
""" """
Host machine is linux? Host machine is linux?
Deprecated: Please use `env.machines[for_machine].is_linux()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_linux()
return is_linux()
return env.cross_info.get_host_system() == 'linux'
def for_darwin(is_cross, env): def for_darwin(is_cross, env):
""" """
Host machine is Darwin (iOS/OS X)? Host machine is Darwin (iOS/OS X)?
Deprecated: Please use `env.machines[for_machine].is_darwin()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_darwin()
return is_osx()
return env.cross_info.get_host_system() in ('darwin', 'ios')
def for_android(is_cross, env): def for_android(is_cross, env):
""" """
Host machine is Android? Host machine is Android?
Deprecated: Please use `env.machines[for_machine].is_android()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_android()
return is_android()
return env.cross_info.get_host_system() == 'android'
def for_haiku(is_cross, env): def for_haiku(is_cross, env):
""" """
Host machine is Haiku? Host machine is Haiku?
Deprecated: Please use `env.machines[for_machine].is_haiku()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_haiku()
return is_haiku()
return env.cross_info.get_host_system() == 'haiku'
def for_openbsd(is_cross, env): def for_openbsd(is_cross, env):
""" """
Host machine is OpenBSD? Host machine is OpenBSD?
Deprecated: Please use `env.machines[for_machine].is_openbsd()`.
Note: 'host' is the machine on which compiled binaries will run Note: 'host' is the machine on which compiled binaries will run
""" """
if not is_cross: return _get_machine_is_cross(env, is_cross).is_openbsd()
return is_openbsd()
elif env.cross_info.has_host():
return env.cross_info.config['host_machine']['system'] == 'openbsd'
return False
def exe_exists(arglist): def exe_exists(arglist):
try: try:

Loading…
Cancel
Save