summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/compilers/detect.py6
-rw-r--r--mesonbuild/dependencies/mpi.py2
-rw-r--r--mesonbuild/dependencies/python.py2
-rw-r--r--mesonbuild/dependencies/ui.py2
-rw-r--r--mesonbuild/envconfig.py263
-rw-r--r--mesonbuild/environment.py259
-rw-r--r--mesonbuild/interpreter/interpreter.py2
-rwxr-xr-xrun_tests.py3
-rw-r--r--unittests/allplatformstests.py16
-rw-r--r--unittests/datatests.py2
-rw-r--r--unittests/internaltests.py36
-rw-r--r--unittests/machinefiletests.py2
12 files changed, 300 insertions, 295 deletions
diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py
index 7300fa366..979b9ce60 100644
--- a/mesonbuild/compilers/detect.py
+++ b/mesonbuild/compilers/detect.py
@@ -8,7 +8,7 @@ from ..mesonlib import (
search_version, is_windows, Popen_safe, Popen_safe_logged, version_compare, windows_proof_rm,
)
from ..programs import ExternalProgram
-from ..envconfig import BinaryTable
+from ..envconfig import BinaryTable, detect_cpu_family, detect_machine_info
from .. import mlog
from ..linkers import guess_win_linker, guess_nix_linker
@@ -1172,8 +1172,6 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile
if not is_msvc:
c_compiler = {}
- # Import here to avoid circular imports
- from ..environment import detect_cpu_family
arch = detect_cpu_family(c_compiler)
if is_msvc and arch == 'x86':
arch = 'x86_mscoff'
@@ -1317,7 +1315,6 @@ def detect_nasm_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
# We need a C compiler to properly detect the machine info and linker
cc = detect_c_compiler(env, for_machine)
if not is_cross:
- from ..environment import detect_machine_info
info = detect_machine_info({'c': cc})
else:
info = env.machines[for_machine]
@@ -1362,7 +1359,6 @@ def detect_masm_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
is_cross = env.is_cross_build(for_machine)
cc = detect_c_compiler(env, for_machine)
if not is_cross:
- from ..environment import detect_machine_info
info = detect_machine_info({'c': cc})
else:
info = env.machines[for_machine]
diff --git a/mesonbuild/dependencies/mpi.py b/mesonbuild/dependencies/mpi.py
index 074dafde3..1eae1a493 100644
--- a/mesonbuild/dependencies/mpi.py
+++ b/mesonbuild/dependencies/mpi.py
@@ -8,7 +8,7 @@ import typing as T
import os
import re
-from ..environment import detect_cpu_family
+from ..envconfig import detect_cpu_family
from ..mesonlib import Popen_safe
from .base import DependencyException, DependencyMethods, detect_compiler, SystemDependency
from .configtool import ConfigToolDependency
diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py
index 707e07499..c204a5197 100644
--- a/mesonbuild/dependencies/python.py
+++ b/mesonbuild/dependencies/python.py
@@ -14,7 +14,7 @@ from .detect import packages
from .factory import DependencyFactory
from .framework import ExtraFrameworkDependency
from .pkgconfig import PkgConfigDependency
-from ..environment import detect_cpu_family
+from ..envconfig import detect_cpu_family
from ..programs import ExternalProgram
from ..options import OptionKey
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 29e65ea3d..de2a4cf36 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -15,7 +15,7 @@ from .. import mesonlib
from ..mesonlib import (
Popen_safe, version_compare_many
)
-from ..environment import detect_cpu_family
+from ..envconfig import detect_cpu_family
from .base import DependencyException, DependencyMethods, DependencyTypeName, SystemDependency
from .configtool import ConfigToolDependency
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py
index f50578905..f4616ac14 100644
--- a/mesonbuild/envconfig.py
+++ b/mesonbuild/envconfig.py
@@ -6,15 +6,20 @@ from __future__ import annotations
from dataclasses import dataclass
import typing as T
from enum import Enum
+import os
+import platform
+import sys
from . import mesonlib
-from .mesonlib import EnvironmentException, HoldableObject
+from .mesonlib import EnvironmentException, HoldableObject, Popen_safe
from .programs import ExternalProgram
from . import mlog
from pathlib import Path
if T.TYPE_CHECKING:
from .options import ElementaryOptionValues
+ from .compilers import Compiler
+ from .compilers.mixins.visualstudio import VisualStudioLikeCompiler
# These classes contains all the data pulled from configuration files (native
@@ -483,3 +488,259 @@ class CMakeVariables:
def get_variables(self) -> T.Dict[str, T.List[str]]:
return self.variables
+
+
+# Machine and platform detection functions
+# ========================================
+
+KERNEL_MAPPINGS: T.Mapping[str, str] = {'freebsd': 'freebsd',
+ 'openbsd': 'openbsd',
+ 'netbsd': 'netbsd',
+ 'windows': 'nt',
+ 'android': 'linux',
+ 'linux': 'linux',
+ 'cygwin': 'nt',
+ 'darwin': 'xnu',
+ 'ios': 'xnu',
+ 'tvos': 'xnu',
+ 'visionos': 'xnu',
+ 'watchos': 'xnu',
+ 'dragonfly': 'dragonfly',
+ 'haiku': 'haiku',
+ 'gnu': 'gnu',
+ }
+
+def detect_windows_arch(compilers: T.Dict[str, Compiler]) -> str:
+ """
+ Detecting the 'native' architecture of Windows is not a trivial task. We
+ cannot trust that the architecture that Python is built for is the 'native'
+ one because you can run 32-bit apps on 64-bit Windows using WOW64 and
+ people sometimes install 32-bit Python on 64-bit Windows.
+
+ We also can't rely on the architecture of the OS itself, since it's
+ perfectly normal to compile and run 32-bit applications on Windows as if
+ they were native applications. It's a terrible experience to require the
+ user to supply a cross-info file to compile 32-bit applications on 64-bit
+ Windows. Thankfully, the only way to compile things with Visual Studio on
+ Windows is by entering the 'msvc toolchain' environment, which can be
+ easily detected.
+
+ In the end, the sanest method is as follows:
+ 1. Check environment variables that are set by Windows and WOW64 to find out
+ if this is x86 (possibly in WOW64), if so use that as our 'native'
+ architecture.
+ 2. If the compiler toolchain target architecture is x86, use that as our
+ 'native' architecture.
+ 3. Otherwise, use the actual Windows architecture
+
+ """
+ os_arch = mesonlib.windows_detect_native_arch()
+ if os_arch == 'x86':
+ return os_arch
+ # If we're on 64-bit Windows, 32-bit apps can be compiled without
+ # cross-compilation. So if we're doing that, just set the native arch as
+ # 32-bit and pretend like we're running under WOW64. Else, return the
+ # actual Windows architecture that we deduced above.
+ for compiler in compilers.values():
+ compiler = T.cast('VisualStudioLikeCompiler', compiler)
+ if compiler.id == 'msvc' and (compiler.target in {'x86', '80x86'}):
+ return 'x86'
+ if compiler.id == 'clang-cl' and (compiler.target in {'x86', 'i686'}):
+ return 'x86'
+ if compiler.id == 'gcc' and compiler.has_builtin_define('__i386__'):
+ return 'x86'
+ return os_arch
+
+def any_compiler_has_define(compilers: T.Dict[str, Compiler], define: str) -> bool:
+ for c in compilers.values():
+ try:
+ if c.has_builtin_define(define):
+ return True
+ except mesonlib.MesonException:
+ # Ignore compilers that do not support has_builtin_define.
+ pass
+ return False
+
+def detect_cpu_family(compilers: T.Dict[str, Compiler]) -> str:
+ """
+ Python is inconsistent in its platform module.
+ It returns different values for the same cpu.
+ For x86 it might return 'x86', 'i686' or some such.
+ Do some canonicalization.
+ """
+ if mesonlib.is_windows():
+ trial = detect_windows_arch(compilers)
+ elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_qnx() or mesonlib.is_aix():
+ trial = platform.processor().lower()
+ else:
+ trial = platform.machine().lower()
+ if trial.startswith('i') and trial.endswith('86'):
+ trial = 'x86'
+ elif trial == 'bepc':
+ trial = 'x86'
+ elif trial == 'arm64':
+ trial = 'aarch64'
+ elif trial.startswith('aarch64'):
+ # This can be `aarch64_be`
+ trial = 'aarch64'
+ elif trial.startswith('arm') or trial.startswith('earm'):
+ trial = 'arm'
+ elif trial.startswith(('powerpc64', 'ppc64')):
+ trial = 'ppc64'
+ elif trial.startswith(('powerpc', 'ppc')) or trial in {'macppc', 'power macintosh'}:
+ trial = 'ppc'
+ elif trial in {'amd64', 'x64', 'i86pc'}:
+ trial = 'x86_64'
+ elif trial in {'sun4u', 'sun4v'}:
+ trial = 'sparc64'
+ elif trial.startswith('mips'):
+ if '64' not in trial:
+ trial = 'mips'
+ else:
+ trial = 'mips64'
+ elif trial in {'ip30', 'ip35'}:
+ trial = 'mips64'
+
+ # On Linux (and maybe others) there can be any mixture of 32/64 bit code in
+ # the kernel, Python, system, 32-bit chroot on 64-bit host, etc. The only
+ # reliable way to know is to check the compiler defines.
+ if trial == 'x86_64':
+ if any_compiler_has_define(compilers, '__i386__'):
+ trial = 'x86'
+ elif trial == 'aarch64':
+ if any_compiler_has_define(compilers, '__arm__'):
+ trial = 'arm'
+ # Add more quirks here as bugs are reported. Keep in sync with detect_cpu()
+ # below.
+ elif trial == 'parisc64':
+ # ATM there is no 64 bit userland for PA-RISC. Thus always
+ # report it as 32 bit for simplicity.
+ trial = 'parisc'
+ elif trial == 'ppc':
+ # AIX always returns powerpc, check here for 64-bit
+ if any_compiler_has_define(compilers, '__64BIT__'):
+ trial = 'ppc64'
+ # MIPS64 is able to run MIPS32 code natively, so there is a chance that
+ # such mixture mentioned above exists.
+ elif trial == 'mips64':
+ if compilers and not any_compiler_has_define(compilers, '__mips64'):
+ trial = 'mips'
+
+ if trial not in known_cpu_families:
+ mlog.warning(f'Unknown CPU family {trial!r}, please report this at '
+ 'https://github.com/mesonbuild/meson/issues/new with the '
+ 'output of `uname -a` and `cat /proc/cpuinfo`')
+
+ return trial
+
+def detect_cpu(compilers: T.Dict[str, Compiler]) -> str:
+ if mesonlib.is_windows():
+ trial = detect_windows_arch(compilers)
+ elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_aix():
+ trial = platform.processor().lower()
+ else:
+ trial = platform.machine().lower()
+
+ if trial in {'amd64', 'x64', 'i86pc'}:
+ trial = 'x86_64'
+ if trial == 'x86_64':
+ # Same check as above for cpu_family
+ if any_compiler_has_define(compilers, '__i386__'):
+ trial = 'i686' # All 64 bit cpus have at least this level of x86 support.
+ elif trial.startswith('aarch64') or trial.startswith('arm64'):
+ # Same check as above for cpu_family
+ if any_compiler_has_define(compilers, '__arm__'):
+ trial = 'arm'
+ else:
+ # for aarch64_be
+ trial = 'aarch64'
+ elif trial.startswith('earm'):
+ trial = 'arm'
+ elif trial == 'e2k':
+ # Make more precise CPU detection for Elbrus platform.
+ trial = platform.processor().lower()
+ elif trial.startswith('mips'):
+ if '64' not in trial:
+ trial = 'mips'
+ else:
+ if compilers and not any_compiler_has_define(compilers, '__mips64'):
+ trial = 'mips'
+ else:
+ trial = 'mips64'
+ elif trial == 'ppc':
+ # AIX always returns powerpc, check here for 64-bit
+ if any_compiler_has_define(compilers, '__64BIT__'):
+ trial = 'ppc64'
+
+ # Add more quirks here as bugs are reported. Keep in sync with
+ # detect_cpu_family() above.
+ return trial
+
+def detect_kernel(system: str) -> T.Optional[str]:
+ if system == 'sunos':
+ # Solaris 5.10 uname doesn't support the -o switch, and illumos started
+ # with version 5.11 so shortcut the logic to report 'solaris' in such
+ # cases where the version is 5.10 or below.
+ if mesonlib.version_compare(platform.uname().release, '<=5.10'):
+ return 'solaris'
+ # This needs to be /usr/bin/uname because gnu-uname could be installed and
+ # won't provide the necessary information
+ p, out, _ = Popen_safe(['/usr/bin/uname', '-o'])
+ if p.returncode != 0:
+ raise mesonlib.MesonException('Failed to run "/usr/bin/uname -o"')
+ out = out.lower().strip()
+ if out not in {'illumos', 'solaris'}:
+ mlog.warning(f'Got an unexpected value for kernel on a SunOS derived platform, expected either "illumos" or "solaris", but got "{out}".'
+ "Please open a Meson issue with the OS you're running and the value detected for your kernel.")
+ return None
+ return out
+ return KERNEL_MAPPINGS.get(system, None)
+
+def detect_subsystem(system: str) -> T.Optional[str]:
+ if system == 'darwin':
+ return 'macos'
+ return system
+
+def detect_system() -> str:
+ if sys.platform == 'cygwin':
+ return 'cygwin'
+ return platform.system().lower()
+
+def detect_msys2_arch() -> T.Optional[str]:
+ return os.environ.get('MSYSTEM_CARCH', None)
+
+def detect_machine_info(compilers: T.Optional[T.Dict[str, Compiler]] = None) -> MachineInfo:
+ """Detect the machine we're running on
+
+ If compilers are not provided, we cannot know as much. None out those
+ fields to avoid accidentally depending on partial knowledge. The
+ underlying ''detect_*'' method can be called to explicitly use the
+ partial information.
+ """
+ system = detect_system()
+ return MachineInfo(
+ system,
+ detect_cpu_family(compilers) if compilers is not None else None,
+ detect_cpu(compilers) if compilers is not None else None,
+ sys.byteorder,
+ detect_kernel(system),
+ detect_subsystem(system))
+
+# TODO make this compare two `MachineInfo`s purely. How important is the
+# `detect_cpu_family({})` distinction? It is the one impediment to that.
+def machine_info_can_run(machine_info: MachineInfo) -> bool:
+ """Whether we can run binaries for this machine on the current machine.
+
+ Can almost always run 32-bit binaries on 64-bit natively if the host
+ and build systems are the same. We don't pass any compilers to
+ detect_cpu_family() here because we always want to know the OS
+ architecture, not what the compiler environment tells us.
+ """
+ if machine_info.system != detect_system():
+ return False
+ true_build_cpu_family = detect_cpu_family({})
+ assert machine_info.cpu_family is not None, 'called on incomplete machine_info'
+ return \
+ (machine_info.cpu_family == true_build_cpu_family) or \
+ ((true_build_cpu_family == 'x86_64') and (machine_info.cpu_family == 'x86')) or \
+ ((true_build_cpu_family == 'mips64') and (machine_info.cpu_family == 'mips'))
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 970f012b0..4d89c88ef 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -5,7 +5,7 @@
from __future__ import annotations
import itertools
-import os, platform, re, sys, shutil
+import os, re, shutil
import typing as T
import collections
@@ -25,7 +25,8 @@ from . import mlog
from .programs import ExternalProgram
from .envconfig import (
- BinaryTable, MachineInfo, Properties, known_cpu_families, CMakeVariables,
+ BinaryTable, MachineInfo, Properties, CMakeVariables,
+ detect_machine_info, machine_info_can_run
)
from . import compilers
@@ -33,12 +34,9 @@ from mesonbuild import envconfig
if T.TYPE_CHECKING:
from .compilers import Compiler
- from .compilers.mixins.visualstudio import VisualStudioLikeCompiler
from .options import OptionDict, ElementaryOptionValues
from .wrap.wrap import Resolver
- CompilersDict = T.Dict[str, Compiler]
-
NON_LANG_ENV_OPTIONS = [
('PKG_CONFIG_PATH', 'pkg_config_path'),
@@ -312,257 +310,6 @@ def detect_clangapply() -> T.List[str]:
return [path]
return []
-def detect_windows_arch(compilers: CompilersDict) -> str:
- """
- Detecting the 'native' architecture of Windows is not a trivial task. We
- cannot trust that the architecture that Python is built for is the 'native'
- one because you can run 32-bit apps on 64-bit Windows using WOW64 and
- people sometimes install 32-bit Python on 64-bit Windows.
-
- We also can't rely on the architecture of the OS itself, since it's
- perfectly normal to compile and run 32-bit applications on Windows as if
- they were native applications. It's a terrible experience to require the
- user to supply a cross-info file to compile 32-bit applications on 64-bit
- Windows. Thankfully, the only way to compile things with Visual Studio on
- Windows is by entering the 'msvc toolchain' environment, which can be
- easily detected.
-
- In the end, the sanest method is as follows:
- 1. Check environment variables that are set by Windows and WOW64 to find out
- if this is x86 (possibly in WOW64), if so use that as our 'native'
- architecture.
- 2. If the compiler toolchain target architecture is x86, use that as our
- 'native' architecture.
- 3. Otherwise, use the actual Windows architecture
-
- """
- os_arch = mesonlib.windows_detect_native_arch()
- if os_arch == 'x86':
- return os_arch
- # If we're on 64-bit Windows, 32-bit apps can be compiled without
- # cross-compilation. So if we're doing that, just set the native arch as
- # 32-bit and pretend like we're running under WOW64. Else, return the
- # actual Windows architecture that we deduced above.
- for compiler in compilers.values():
- compiler = T.cast('VisualStudioLikeCompiler', compiler)
- if compiler.id == 'msvc' and (compiler.target in {'x86', '80x86'}):
- return 'x86'
- if compiler.id == 'clang-cl' and (compiler.target in {'x86', 'i686'}):
- return 'x86'
- if compiler.id == 'gcc' and compiler.has_builtin_define('__i386__'):
- return 'x86'
- return os_arch
-
-def any_compiler_has_define(compilers: CompilersDict, define: str) -> bool:
- for c in compilers.values():
- try:
- if c.has_builtin_define(define):
- return True
- except mesonlib.MesonException:
- # Ignore compilers that do not support has_builtin_define.
- pass
- return False
-
-def detect_cpu_family(compilers: CompilersDict) -> str:
- """
- Python is inconsistent in its platform module.
- It returns different values for the same cpu.
- For x86 it might return 'x86', 'i686' or some such.
- Do some canonicalization.
- """
- if mesonlib.is_windows():
- trial = detect_windows_arch(compilers)
- elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_qnx() or mesonlib.is_aix():
- trial = platform.processor().lower()
- else:
- trial = platform.machine().lower()
- if trial.startswith('i') and trial.endswith('86'):
- trial = 'x86'
- elif trial == 'bepc':
- trial = 'x86'
- elif trial == 'arm64':
- trial = 'aarch64'
- elif trial.startswith('aarch64'):
- # This can be `aarch64_be`
- trial = 'aarch64'
- elif trial.startswith('arm') or trial.startswith('earm'):
- trial = 'arm'
- elif trial.startswith(('powerpc64', 'ppc64')):
- trial = 'ppc64'
- elif trial.startswith(('powerpc', 'ppc')) or trial in {'macppc', 'power macintosh'}:
- trial = 'ppc'
- elif trial in {'amd64', 'x64', 'i86pc'}:
- trial = 'x86_64'
- elif trial in {'sun4u', 'sun4v'}:
- trial = 'sparc64'
- elif trial.startswith('mips'):
- if '64' not in trial:
- trial = 'mips'
- else:
- trial = 'mips64'
- elif trial in {'ip30', 'ip35'}:
- trial = 'mips64'
-
- # On Linux (and maybe others) there can be any mixture of 32/64 bit code in
- # the kernel, Python, system, 32-bit chroot on 64-bit host, etc. The only
- # reliable way to know is to check the compiler defines.
- if trial == 'x86_64':
- if any_compiler_has_define(compilers, '__i386__'):
- trial = 'x86'
- elif trial == 'aarch64':
- if any_compiler_has_define(compilers, '__arm__'):
- trial = 'arm'
- # Add more quirks here as bugs are reported. Keep in sync with detect_cpu()
- # below.
- elif trial == 'parisc64':
- # ATM there is no 64 bit userland for PA-RISC. Thus always
- # report it as 32 bit for simplicity.
- trial = 'parisc'
- elif trial == 'ppc':
- # AIX always returns powerpc, check here for 64-bit
- if any_compiler_has_define(compilers, '__64BIT__'):
- trial = 'ppc64'
- # MIPS64 is able to run MIPS32 code natively, so there is a chance that
- # such mixture mentioned above exists.
- elif trial == 'mips64':
- if compilers and not any_compiler_has_define(compilers, '__mips64'):
- trial = 'mips'
-
- if trial not in known_cpu_families:
- mlog.warning(f'Unknown CPU family {trial!r}, please report this at '
- 'https://github.com/mesonbuild/meson/issues/new with the '
- 'output of `uname -a` and `cat /proc/cpuinfo`')
-
- return trial
-
-def detect_cpu(compilers: CompilersDict) -> str:
- if mesonlib.is_windows():
- trial = detect_windows_arch(compilers)
- elif mesonlib.is_freebsd() or mesonlib.is_netbsd() or mesonlib.is_openbsd() or mesonlib.is_aix():
- trial = platform.processor().lower()
- else:
- trial = platform.machine().lower()
-
- if trial in {'amd64', 'x64', 'i86pc'}:
- trial = 'x86_64'
- if trial == 'x86_64':
- # Same check as above for cpu_family
- if any_compiler_has_define(compilers, '__i386__'):
- trial = 'i686' # All 64 bit cpus have at least this level of x86 support.
- elif trial.startswith('aarch64') or trial.startswith('arm64'):
- # Same check as above for cpu_family
- if any_compiler_has_define(compilers, '__arm__'):
- trial = 'arm'
- else:
- # for aarch64_be
- trial = 'aarch64'
- elif trial.startswith('earm'):
- trial = 'arm'
- elif trial == 'e2k':
- # Make more precise CPU detection for Elbrus platform.
- trial = platform.processor().lower()
- elif trial.startswith('mips'):
- if '64' not in trial:
- trial = 'mips'
- else:
- if compilers and not any_compiler_has_define(compilers, '__mips64'):
- trial = 'mips'
- else:
- trial = 'mips64'
- elif trial == 'ppc':
- # AIX always returns powerpc, check here for 64-bit
- if any_compiler_has_define(compilers, '__64BIT__'):
- trial = 'ppc64'
-
- # Add more quirks here as bugs are reported. Keep in sync with
- # detect_cpu_family() above.
- return trial
-
-KERNEL_MAPPINGS: T.Mapping[str, str] = {'freebsd': 'freebsd',
- 'openbsd': 'openbsd',
- 'netbsd': 'netbsd',
- 'windows': 'nt',
- 'android': 'linux',
- 'linux': 'linux',
- 'cygwin': 'nt',
- 'darwin': 'xnu',
- 'ios': 'xnu',
- 'tvos': 'xnu',
- 'visionos': 'xnu',
- 'watchos': 'xnu',
- 'dragonfly': 'dragonfly',
- 'haiku': 'haiku',
- 'gnu': 'gnu',
- }
-
-def detect_kernel(system: str) -> T.Optional[str]:
- if system == 'sunos':
- # Solaris 5.10 uname doesn't support the -o switch, and illumos started
- # with version 5.11 so shortcut the logic to report 'solaris' in such
- # cases where the version is 5.10 or below.
- if mesonlib.version_compare(platform.uname().release, '<=5.10'):
- return 'solaris'
- # This needs to be /usr/bin/uname because gnu-uname could be installed and
- # won't provide the necessary information
- p, out, _ = Popen_safe(['/usr/bin/uname', '-o'])
- if p.returncode != 0:
- raise MesonException('Failed to run "/usr/bin/uname -o"')
- out = out.lower().strip()
- if out not in {'illumos', 'solaris'}:
- mlog.warning(f'Got an unexpected value for kernel on a SunOS derived platform, expected either "illumos" or "solaris", but got "{out}".'
- "Please open a Meson issue with the OS you're running and the value detected for your kernel.")
- return None
- return out
- return KERNEL_MAPPINGS.get(system, None)
-
-def detect_subsystem(system: str) -> T.Optional[str]:
- if system == 'darwin':
- return 'macos'
- return system
-
-def detect_system() -> str:
- if sys.platform == 'cygwin':
- return 'cygwin'
- return platform.system().lower()
-
-def detect_msys2_arch() -> T.Optional[str]:
- return os.environ.get('MSYSTEM_CARCH', None)
-
-def detect_machine_info(compilers: T.Optional[CompilersDict] = None) -> MachineInfo:
- """Detect the machine we're running on
-
- If compilers are not provided, we cannot know as much. None out those
- fields to avoid accidentally depending on partial knowledge. The
- underlying ''detect_*'' method can be called to explicitly use the
- partial information.
- """
- system = detect_system()
- return MachineInfo(
- system,
- detect_cpu_family(compilers) if compilers is not None else None,
- detect_cpu(compilers) if compilers is not None else None,
- sys.byteorder,
- detect_kernel(system),
- detect_subsystem(system))
-
-# TODO make this compare two `MachineInfo`s purely. How important is the
-# `detect_cpu_family({})` distinction? It is the one impediment to that.
-def machine_info_can_run(machine_info: MachineInfo) -> bool:
- """Whether we can run binaries for this machine on the current machine.
-
- Can almost always run 32-bit binaries on 64-bit natively if the host
- and build systems are the same. We don't pass any compilers to
- detect_cpu_family() here because we always want to know the OS
- architecture, not what the compiler environment tells us.
- """
- if machine_info.system != detect_system():
- return False
- true_build_cpu_family = detect_cpu_family({})
- assert machine_info.cpu_family is not None, 'called on incomplete machine_info'
- return \
- (machine_info.cpu_family == true_build_cpu_family) or \
- ((true_build_cpu_family == 'x86_64') and (machine_info.cpu_family == 'x86')) or \
- ((true_build_cpu_family == 'mips64') and (machine_info.cpu_family == 'mips'))
class Environment:
private_dir = 'meson-private'
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index c1500630c..3e1010471 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -309,7 +309,7 @@ class Interpreter(InterpreterBase, HoldableObject):
# have the compilers needed to gain more knowledge, so wipe out old
# inference and start over.
machines = self.build.environment.machines.miss_defaulting()
- machines.build = environment.detect_machine_info(self.coredata.compilers.build)
+ machines.build = envconfig.detect_machine_info(self.coredata.compilers.build)
self.build.environment.machines = machines.default_missing()
assert self.build.environment.machines.build.cpu is not None
assert self.build.environment.machines.host.cpu is not None
diff --git a/run_tests.py b/run_tests.py
index ed224f817..38c1e812b 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -32,7 +32,8 @@ from mesonbuild import mesonlib
from mesonbuild import mesonmain
from mesonbuild import mtest
from mesonbuild import mlog
-from mesonbuild.environment import Environment, detect_ninja, detect_machine_info
+from mesonbuild.environment import Environment, detect_ninja
+from mesonbuild.envconfig import detect_machine_info
from mesonbuild.coredata import version as meson_version
from mesonbuild.options import backendlist
from mesonbuild.mesonlib import setup_vsenv
diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py
index 5e4739ce3..21cdaa8be 100644
--- a/unittests/allplatformstests.py
+++ b/unittests/allplatformstests.py
@@ -1054,7 +1054,7 @@ class AllPlatformTests(BasePlatformTests):
def test_internal_include_order(self):
- if mesonbuild.environment.detect_msys2_arch() and ('MESON_RSP_THRESHOLD' in os.environ):
+ if mesonbuild.envconfig.detect_msys2_arch() and ('MESON_RSP_THRESHOLD' in os.environ):
raise SkipTest('Test does not yet support gcc rsp files on msys2')
testdir = os.path.join(self.common_test_dir, '130 include order')
@@ -4075,7 +4075,7 @@ class AllPlatformTests(BasePlatformTests):
return basename
def get_shared_lib_name(basename: str) -> str:
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
return f'lib{basename}.dll'
elif is_windows():
return f'{basename}.dll'
@@ -4288,7 +4288,7 @@ class AllPlatformTests(BasePlatformTests):
self.assertTrue((covdir / f).is_file(), msg=f'{f} is not a file')
def test_coverage(self):
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with coverage on MSYS2')
gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
if not gcovr_exe:
@@ -4308,7 +4308,7 @@ class AllPlatformTests(BasePlatformTests):
self._check_coverage_files()
def test_coverage_complex(self):
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with coverage on MSYS2')
gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
if not gcovr_exe:
@@ -4328,7 +4328,7 @@ class AllPlatformTests(BasePlatformTests):
self._check_coverage_files()
def test_coverage_html(self):
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with coverage on MSYS2')
gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
if not gcovr_exe:
@@ -4348,7 +4348,7 @@ class AllPlatformTests(BasePlatformTests):
self._check_coverage_files(['html'])
def test_coverage_text(self):
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with coverage on MSYS2')
gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
if not gcovr_exe:
@@ -4368,7 +4368,7 @@ class AllPlatformTests(BasePlatformTests):
self._check_coverage_files(['text'])
def test_coverage_xml(self):
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with coverage on MSYS2')
gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
if not gcovr_exe:
@@ -4388,7 +4388,7 @@ class AllPlatformTests(BasePlatformTests):
self._check_coverage_files(['xml'])
def test_coverage_escaping(self):
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with coverage on MSYS2')
gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
if not gcovr_exe:
diff --git a/unittests/datatests.py b/unittests/datatests.py
index 58b74188e..e529e4e5b 100644
--- a/unittests/datatests.py
+++ b/unittests/datatests.py
@@ -183,7 +183,7 @@ class DataTests(unittest.TestCase):
arches = [m.group(1) for m in re.finditer(r"^\| (\w+) +\|", content, re.MULTILINE)]
# Drop the header
arches = set(arches[1:])
- self.assertEqual(arches, set(mesonbuild.environment.known_cpu_families))
+ self.assertEqual(arches, set(mesonbuild.envconfig.known_cpu_families))
def test_markdown_files_in_sitemap(self):
'''
diff --git a/unittests/internaltests.py b/unittests/internaltests.py
index dfa797dc7..71e32ba3f 100644
--- a/unittests/internaltests.py
+++ b/unittests/internaltests.py
@@ -1594,9 +1594,9 @@ class InternalTests(unittest.TestCase):
"""Mock all of the ways we could get the trial at once."""
mocked = mock.Mock(return_value=value)
- with mock.patch('mesonbuild.environment.detect_windows_arch', mocked), \
- mock.patch('mesonbuild.environment.platform.processor', mocked), \
- mock.patch('mesonbuild.environment.platform.machine', mocked):
+ with mock.patch('mesonbuild.envconfig.detect_windows_arch', mocked), \
+ mock.patch('mesonbuild.envconfig.platform.processor', mocked), \
+ mock.patch('mesonbuild.envconfig.platform.machine', mocked):
yield
cases = [
@@ -1629,26 +1629,26 @@ class InternalTests(unittest.TestCase):
cc = ClangCCompiler([], [], 'fake', MachineChoice.HOST, False, mock.Mock())
- with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=False)):
+ with mock.patch('mesonbuild.envconfig.any_compiler_has_define', mock.Mock(return_value=False)):
for test, expected in cases:
with self.subTest(test, has_define=False), mock_trial(test):
- actual = mesonbuild.environment.detect_cpu_family({'c': cc})
+ actual = mesonbuild.envconfig.detect_cpu_family({'c': cc})
self.assertEqual(actual, expected)
- with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=True)):
+ with mock.patch('mesonbuild.envconfig.any_compiler_has_define', mock.Mock(return_value=True)):
for test, expected in [('x86_64', 'x86'), ('aarch64', 'arm'), ('ppc', 'ppc64'), ('mips64', 'mips64')]:
with self.subTest(test, has_define=True), mock_trial(test):
- actual = mesonbuild.environment.detect_cpu_family({'c': cc})
+ actual = mesonbuild.envconfig.detect_cpu_family({'c': cc})
self.assertEqual(actual, expected)
# machine_info_can_run calls detect_cpu_family with no compilers at all
with mock.patch(
- 'mesonbuild.environment.any_compiler_has_define',
+ 'mesonbuild.envconfig.any_compiler_has_define',
mock.Mock(side_effect=AssertionError('Should not be called')),
):
for test, expected in [('mips64', 'mips64')]:
with self.subTest(test, has_compiler=False), mock_trial(test):
- actual = mesonbuild.environment.detect_cpu_family({})
+ actual = mesonbuild.envconfig.detect_cpu_family({})
self.assertEqual(actual, expected)
def test_detect_cpu(self) -> None:
@@ -1658,9 +1658,9 @@ class InternalTests(unittest.TestCase):
"""Mock all of the ways we could get the trial at once."""
mocked = mock.Mock(return_value=value)
- with mock.patch('mesonbuild.environment.detect_windows_arch', mocked), \
- mock.patch('mesonbuild.environment.platform.processor', mocked), \
- mock.patch('mesonbuild.environment.platform.machine', mocked):
+ with mock.patch('mesonbuild.envconfig.detect_windows_arch', mocked), \
+ mock.patch('mesonbuild.envconfig.platform.processor', mocked), \
+ mock.patch('mesonbuild.envconfig.platform.machine', mocked):
yield
cases = [
@@ -1678,25 +1678,25 @@ class InternalTests(unittest.TestCase):
cc = ClangCCompiler([], [], 'fake', MachineChoice.HOST, False, mock.Mock())
- with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=False)):
+ with mock.patch('mesonbuild.envconfig.any_compiler_has_define', mock.Mock(return_value=False)):
for test, expected in cases:
with self.subTest(test, has_define=False), mock_trial(test):
- actual = mesonbuild.environment.detect_cpu({'c': cc})
+ actual = mesonbuild.envconfig.detect_cpu({'c': cc})
self.assertEqual(actual, expected)
- with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=True)):
+ with mock.patch('mesonbuild.envconfig.any_compiler_has_define', mock.Mock(return_value=True)):
for test, expected in [('x86_64', 'i686'), ('aarch64', 'arm'), ('ppc', 'ppc64'), ('mips64', 'mips64')]:
with self.subTest(test, has_define=True), mock_trial(test):
- actual = mesonbuild.environment.detect_cpu({'c': cc})
+ actual = mesonbuild.envconfig.detect_cpu({'c': cc})
self.assertEqual(actual, expected)
with mock.patch(
- 'mesonbuild.environment.any_compiler_has_define',
+ 'mesonbuild.envconfig.any_compiler_has_define',
mock.Mock(side_effect=AssertionError('Should not be called')),
):
for test, expected in [('mips64', 'mips64')]:
with self.subTest(test, has_compiler=False), mock_trial(test):
- actual = mesonbuild.environment.detect_cpu({})
+ actual = mesonbuild.envconfig.detect_cpu({})
self.assertEqual(actual, expected)
@mock.patch('mesonbuild.interpreter.Interpreter.load_root_meson_file', mock.Mock(return_value=None))
diff --git a/unittests/machinefiletests.py b/unittests/machinefiletests.py
index 15c0e5728..7f583de2e 100644
--- a/unittests/machinefiletests.py
+++ b/unittests/machinefiletests.py
@@ -204,7 +204,7 @@ class NativeFileTests(BasePlatformTests):
def test_config_tool_dep(self):
# Do the skip at this level to avoid screwing up the cache
- if mesonbuild.environment.detect_msys2_arch():
+ if mesonbuild.envconfig.detect_msys2_arch():
raise SkipTest('Skipped due to problems with LLVM on MSYS2')
if not shutil.which('llvm-config'):
raise SkipTest('No llvm-installed, cannot test')