@ -57,26 +57,90 @@ def detect_ninja():
if p . returncode == 0 and mesonlib . version_compare ( version , " >=1.6 " ) :
if p . returncode == 0 and mesonlib . version_compare ( version , " >=1.6 " ) :
return n
return n
def detect_cpu_family ( ) :
def detect_native_windows_arch ( ) :
"""
The architecture of Windows itself : x86 or amd64
"""
# 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 InterpreterException ( ' Unable to detect native OS architecture ' )
return arch
def detect_windows_arch ( compilers ) :
"""
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 if we ' re in an MSVC toolchain environment, and if so, return the
MSVC toolchain architecture as our ' native ' architecture .
2. If not , check environment variables that are set by Windows and WOW64 to
find out the architecture that Windows is built for , and use that as our
' native ' architecture .
"""
os_arch = detect_native_windows_arch ( )
if os_arch != ' amd64 ' :
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 ( ) :
# Check if we're using and inside an MSVC toolchain environment
if compiler . id == ' msvc ' and ' VCINSTALLDIR ' in os . environ :
# 'Platform' is only set when the target arch is not 'x86'.
# It's 'x64' when targetting x86_64 and 'arm' when targetting ARM.
platform = os . environ . get ( ' Platform ' , ' x86 ' ) . lower ( )
if platform == ' x86 ' :
return platform
if compiler . id == ' gcc ' :
# TODO: Implement this
pass
return os_arch
def detect_cpu_family ( compilers ) :
"""
"""
Python is inconsistent in its platform module .
Python is inconsistent in its platform module .
It returns different values for the same cpu .
It returns different values for the same cpu .
For x86 it might return ' x86 ' , ' i686 ' or somesuch .
For x86 it might return ' x86 ' , ' i686 ' or somesuch .
Do some canonicalization .
Do some canonicalization .
"""
"""
if mesonlib . is_windows ( ) :
trial = detect_windows_arch ( compilers )
else :
trial = platform . machine ( ) . lower ( )
trial = platform . machine ( ) . lower ( )
if trial . startswith ( ' i ' ) and trial . endswith ( ' 86 ' ) :
if trial . startswith ( ' i ' ) and trial . endswith ( ' 86 ' ) :
return ' x86 '
return ' x86 '
if trial . startswith ( ' arm ' ) :
if trial . startswith ( ' arm ' ) :
return ' arm '
return ' arm '
if trial == ' amd64 ' :
if trial in ( ' amd64 ' , ' x64 ' ) :
return ' x86_64 '
return ' x86_64 '
# Add fixes here as bugs are reported.
# Add fixes here as bugs are reported.
return trial
return trial
def detect_cpu ( ) :
def detect_cpu ( compilers ) :
if mesonlib . is_windows ( ) :
trial = detect_windows_arch ( compilers )
else :
trial = platform . machine ( ) . lower ( )
trial = platform . machine ( ) . lower ( )
if trial == ' amd64 ' :
if trial in ( ' amd64 ' , ' x64 ' ) :
return ' x86_64 '
return ' x86_64 '
# Add fixes here as bugs are reported.
# Add fixes here as bugs are reported.
return trial
return trial
@ -846,10 +910,12 @@ class CrossBuildInfo():
return ' host_machine ' in self . config
return ' host_machine ' in self . config
def need_exe_wrapper ( self ) :
def need_exe_wrapper ( self ) :
if self . has_host ( ) and detect_cpu_family ( ) == ' x86_64 ' and \
# 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 self . has_host ( ) and detect_cpu_family ( { } ) == ' x86_64 ' and \
self . config [ ' host_machine ' ] [ ' cpu_family ' ] == ' x86 ' and \
self . config [ ' host_machine ' ] [ ' cpu_family ' ] == ' x86 ' and \
self . config [ ' host_machine ' ] [ ' system ' ] == detect_system ( ) :
self . config [ ' host_machine ' ] [ ' system ' ] == detect_system ( ) :
# Can almost always run 32-bit binaries on 64-bit natively if the
# host and build systems are the same
return False
return False
return True
return True