aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavoLCR <gugulcr@gmail.com>2022-09-14 01:34:46 -0300
committerJussi Pakkanen <jpakkane@gmail.com>2022-10-25 14:59:06 +0300
commit32bc64e63210cee6df7364a39005d89cdfdc6b71 (patch)
tree281c411c322547f9ca45fe14a62795e03eef3da1
parent3c0ac626d7bbf667762b72a8b075617763e17795 (diff)
downloadmeson-32bc64e63210cee6df7364a39005d89cdfdc6b71.zip
meson-32bc64e63210cee6df7364a39005d89cdfdc6b71.tar.gz
meson-32bc64e63210cee6df7364a39005d89cdfdc6b71.tar.bz2
Fix native compilation on ARM64 Windows
Move `detect_native_windows_arch()` to `mesonlib/universal.py` and rename it to `windows_detect_native_arch()` Use `IsWow64Process2()` to detect native architecture if available Use native `vcvarsarm64.bat` to initialize vsenv if available
-rw-r--r--mesonbuild/environment.py22
-rw-r--r--mesonbuild/utils/universal.py37
-rw-r--r--mesonbuild/utils/vsenv.py9
3 files changed, 45 insertions, 23 deletions
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index bf6d374..7b09a2c 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -20,7 +20,7 @@ import collections
from . import coredata
from . import mesonlib
from .mesonlib import (
- MesonException, EnvironmentException, MachineChoice, Popen_safe, PerMachine,
+ MesonException, MachineChoice, Popen_safe, PerMachine,
PerMachineDefaultable, PerThreeMachineDefaultable, split_args, quote_arg, OptionKey,
search_version, MesonBugException
)
@@ -228,22 +228,6 @@ def detect_clangformat() -> T.List[str]:
return [path]
return []
-def detect_native_windows_arch():
- """
- The architecture of Windows itself: x86, amd64 or arm64
- """
- # These env variables are always available. See:
- # https://msdn.microsoft.com/en-us/library/aa384274(VS.85).aspx
- # https://blogs.msdn.microsoft.com/david.wang/2006/03/27/howto-detect-process-bitness/
- arch = os.environ.get('PROCESSOR_ARCHITEW6432', '').lower()
- if not arch:
- try:
- # If this doesn't exist, something is messing with the environment
- arch = os.environ['PROCESSOR_ARCHITECTURE'].lower()
- except KeyError:
- raise EnvironmentException('Unable to detect native OS architecture')
- return arch
-
def detect_windows_arch(compilers: CompilersDict) -> str:
"""
Detecting the 'native' architecture of Windows is not a trivial task. We
@@ -268,7 +252,7 @@ def detect_windows_arch(compilers: CompilersDict) -> str:
3. Otherwise, use the actual Windows architecture
"""
- os_arch = detect_native_windows_arch()
+ 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
@@ -375,7 +359,7 @@ def detect_cpu(compilers: CompilersDict) -> str:
# 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'):
+ elif trial.startswith('aarch64') or trial.startswith('arm64'):
# Same check as above for cpu_family
if any_compiler_has_define(compilers, '__arm__'):
trial = 'arm'
diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py
index aaefbc5..0c611bb 100644
--- a/mesonbuild/utils/universal.py
+++ b/mesonbuild/utils/universal.py
@@ -17,6 +17,7 @@
from __future__ import annotations
from pathlib import Path
import argparse
+import ctypes
import enum
import sys
import stat
@@ -141,6 +142,7 @@ __all__ = [
'version_compare_condition_with_min',
'version_compare_many',
'search_version',
+ 'windows_detect_native_arch',
'windows_proof_rm',
'windows_proof_rmtree',
]
@@ -689,6 +691,41 @@ def darwin_get_object_archs(objpath: str) -> 'ImmutableListProtocol[str]':
stdo += ' arm'
return stdo.split()
+def windows_detect_native_arch() -> str:
+ """
+ The architecture of Windows itself: x86, amd64 or arm64
+ """
+ if sys.platform != 'win32':
+ return ''
+ try:
+ process_arch = ctypes.c_ushort()
+ native_arch = ctypes.c_ushort()
+ kernel32 = ctypes.windll.kernel32
+ process = ctypes.c_void_p(kernel32.GetCurrentProcess())
+ # This is the only reliable way to detect an arm system if we are an x86/x64 process being emulated
+ if kernel32.IsWow64Process2(process, ctypes.byref(process_arch), ctypes.byref(native_arch)):
+ # https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants
+ if native_arch.value == 0x8664:
+ return 'amd64'
+ elif native_arch.value == 0x014C:
+ return 'x86'
+ elif native_arch.value == 0xAA64:
+ return 'arm64'
+ elif native_arch.value == 0x01C4:
+ return 'arm'
+ except (OSError, AttributeError):
+ pass
+ # These env variables are always available. See:
+ # https://msdn.microsoft.com/en-us/library/aa384274(VS.85).aspx
+ # https://blogs.msdn.microsoft.com/david.wang/2006/03/27/howto-detect-process-bitness/
+ arch = os.environ.get('PROCESSOR_ARCHITEW6432', '').lower()
+ if not arch:
+ try:
+ # If this doesn't exist, something is messing with the environment
+ arch = os.environ['PROCESSOR_ARCHITECTURE'].lower()
+ except KeyError:
+ raise EnvironmentException('Unable to detect native OS architecture')
+ return arch
def detect_vcs(source_dir: T.Union[str, Path]) -> T.Optional[T.Dict[str, str]]:
vcs_systems = [
diff --git a/mesonbuild/utils/vsenv.py b/mesonbuild/utils/vsenv.py
index 5f32990..47055a0 100644
--- a/mesonbuild/utils/vsenv.py
+++ b/mesonbuild/utils/vsenv.py
@@ -2,12 +2,11 @@ import os
import subprocess
import json
import pathlib
-import platform
import shutil
import tempfile
from .. import mlog
-from .universal import MesonException, is_windows
+from .universal import MesonException, is_windows, windows_detect_native_arch
__all__ = [
@@ -72,8 +71,10 @@ def _setup_vsenv(force: bool) -> bool:
# VS installer instelled but not VS itself maybe?
raise MesonException('Could not parse vswhere.exe output')
bat_root = pathlib.Path(bat_info[0]['installationPath'])
- if platform.machine() == 'ARM64':
- bat_path = bat_root / 'VC/Auxiliary/Build/vcvarsx86_arm64.bat'
+ if windows_detect_native_arch() == 'arm64':
+ bat_path = bat_root / 'VC/Auxiliary/Build/vcvarsarm64.bat'
+ if not bat_path.exists():
+ bat_path = bat_root / 'VC/Auxiliary/Build/vcvarsx86_arm64.bat'
else:
bat_path = bat_root / 'VC/Auxiliary/Build/vcvars64.bat'
# if VS is not found try VS Express