summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-12-08 20:20:01 (GMT)
committerBrad King <brad.king@kitware.com>2020-12-10 17:08:13 (GMT)
commit5f882f6ce518a9f90600ae5c73f633ca5c15a7e5 (patch)
tree6fb39272e4f5e0d64fd2f124ebea6735fa9470d7 /Modules
parent0334a3c68f1064a7bb1f682d81f03e06f3608893 (diff)
downloadCMake-5f882f6ce518a9f90600ae5c73f633ca5c15a7e5.zip
CMake-5f882f6ce518a9f90600ae5c73f633ca5c15a7e5.tar.gz
CMake-5f882f6ce518a9f90600ae5c73f633ca5c15a7e5.tar.bz2
macOS: Offer control over host architecture on Apple Silicon hosts
Since commit b6c60f14b6 (macOS: Default to arm64 architecture on Apple Silicon hosts, 2020-09-28, v3.19.0-rc1~63^2) we use `sysctl` to detect that we are running on Apple Silicon in a way that pierces Rosetta. This always sets `CMAKE_HOST_SYSTEM_PROCESSOR` to be `arm64` on such hosts. However, macOS offers strong support for running processes under an emulated `x86_64` architecture. Teach CMake to select either `arm64` or `x86_64` as the host architecture on Apple Silicon based on the architecture of its own process. When CMake is built as a universal binary, macOS will select whichever slice (architecture) is appropriate under the user's shell, and `CMAKE_HOST_SYSTEM_PROCESSOR` will match. Also offer a `CMAKE_APPLE_SILICON_PROCESSOR` variable and environment variable to provide users with explicit control over the host architecture selection regardless of CMake's own architecture. Finally, if `CMAKE_OSX_ARCHITECTURES` is not set, pass explicit flags to the toolchain to use selected host architecture instead of letting the toolchain pick. Fixes: #21554
Diffstat (limited to 'Modules')
-rw-r--r--Modules/CMakeDetermineSystem.cmake37
-rw-r--r--Modules/Platform/Darwin-Initialize.cmake17
2 files changed, 41 insertions, 13 deletions
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index cb4421a..bae270d 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -43,25 +43,44 @@ if(CMAKE_HOST_UNIX)
else()
exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
endif()
- if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|Darwin|^GNU$|Android")
+ if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|^GNU$|Android")
exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
- if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
- if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
- # Check whether we are running under Rosetta on arm64 hardware.
+ elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
+ # If we are running on Apple Silicon, honor CMAKE_APPLE_SILICON_PROCESSOR.
+ if(DEFINED CMAKE_APPLE_SILICON_PROCESSOR)
+ set(_CMAKE_APPLE_SILICON_PROCESSOR "${CMAKE_APPLE_SILICON_PROCESSOR}")
+ elseif(DEFINED ENV{CMAKE_APPLE_SILICON_PROCESSOR})
+ set(_CMAKE_APPLE_SILICON_PROCESSOR "$ENV{CMAKE_APPLE_SILICON_PROCESSOR}")
+ else()
+ set(_CMAKE_APPLE_SILICON_PROCESSOR "")
+ endif()
+ if(_CMAKE_APPLE_SILICON_PROCESSOR)
+ if(";${_CMAKE_APPLE_SILICON_PROCESSOR};" MATCHES "^;(arm64|x86_64);$")
execute_process(COMMAND sysctl -q hw.optional.arm64
OUTPUT_VARIABLE _sysctl_stdout
ERROR_VARIABLE _sysctl_stderr
RESULT_VARIABLE _sysctl_result
)
- if(_sysctl_result EQUAL 0 AND _sysctl_stdout MATCHES "hw.optional.arm64: 1")
- set(CMAKE_HOST_SYSTEM_PROCESSOR "arm64")
+ if(NOT _sysctl_result EQUAL 0 OR NOT _sysctl_stdout MATCHES "hw.optional.arm64: 1")
+ set(_CMAKE_APPLE_SILICON_PROCESSOR "")
endif()
- elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
- # OS X ppc 'uname -m' may report 'Power Macintosh' instead of 'powerpc'
- set(CMAKE_HOST_SYSTEM_PROCESSOR "powerpc")
+ unset(_sysctl_result)
+ unset(_sysctl_stderr)
+ unset(_sysctl_stdout)
endif()
endif()
+ if(_CMAKE_APPLE_SILICON_PROCESSOR)
+ set(CMAKE_HOST_SYSTEM_PROCESSOR "${_CMAKE_APPLE_SILICON_PROCESSOR}")
+ else()
+ exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RETURN_VALUE val)
+ endif()
+ unset(_CMAKE_APPLE_SILICON_PROCESSOR)
+ if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
+ # OS X ppc 'uname -m' may report 'Power Macintosh' instead of 'powerpc'
+ set(CMAKE_HOST_SYSTEM_PROCESSOR "powerpc")
+ endif()
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
exec_program(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 213f71b..c2f1851 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -22,13 +22,22 @@ set(CMAKE_OSX_ARCHITECTURES "$ENV{CMAKE_OSX_ARCHITECTURES}" CACHE STRING
if(NOT CMAKE_CROSSCOMPILING AND
CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND
- CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64" AND
- CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- # When building on Apple Silicon (arm64), we need to explicitly specify
+ CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(arm64|x86_64)$")
+ execute_process(COMMAND sysctl -q hw.optional.arm64
+ OUTPUT_VARIABLE _sysctl_stdout
+ ERROR_VARIABLE _sysctl_stderr
+ RESULT_VARIABLE _sysctl_result
+ )
+ # When building on an Apple Silicon host, we need to explicitly specify
# the architecture to the toolchain since it will otherwise guess the
# architecture based on that of the build system tool.
# Set an *internal variable* to tell the generators to do this.
- set(_CMAKE_APPLE_ARCHS_DEFAULT "arm64")
+ if(_sysctl_result EQUAL 0 AND _sysctl_stdout MATCHES "hw.optional.arm64: 1")
+ set(_CMAKE_APPLE_ARCHS_DEFAULT "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+ endif()
+ unset(_sysctl_result)
+ unset(_sysctl_stderr)
+ unset(_sysctl_stdout)
endif()
# macOS, iOS, tvOS, and watchOS should lookup compilers from