diff options
author | Brad King <brad.king@kitware.com> | 2020-12-08 20:20:01 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-12-10 17:08:13 (GMT) |
commit | 5f882f6ce518a9f90600ae5c73f633ca5c15a7e5 (patch) | |
tree | 6fb39272e4f5e0d64fd2f124ebea6735fa9470d7 /Modules | |
parent | 0334a3c68f1064a7bb1f682d81f03e06f3608893 (diff) | |
download | CMake-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.cmake | 37 | ||||
-rw-r--r-- | Modules/Platform/Darwin-Initialize.cmake | 17 |
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 |