mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
Merge topic 'apple-silicon-host-arch' into release-3.19
b7f0327dcd
Tests: Cover macOS host architecture selection on Apple Silicon hosts5f882f6ce5
macOS: Offer control over host architecture on Apple Silicon hosts Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5589
This commit is contained in:
13
Help/envvar/CMAKE_APPLE_SILICON_PROCESSOR.rst
Normal file
13
Help/envvar/CMAKE_APPLE_SILICON_PROCESSOR.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
CMAKE_APPLE_SILICON_PROCESSOR
|
||||
-----------------------------
|
||||
|
||||
.. versionadded:: 3.19.2
|
||||
|
||||
.. include:: ENV_VAR.txt
|
||||
|
||||
On Apple Silicon hosts running macOS, set this environment variable to tell
|
||||
CMake what architecture to use for :variable:`CMAKE_HOST_SYSTEM_PROCESSOR`.
|
||||
The value must be either ``arm64`` or ``x86_64``.
|
||||
|
||||
The :variable:`CMAKE_APPLE_SILICON_PROCESSOR` normal variable, if set,
|
||||
overrides this environment variable.
|
@@ -28,6 +28,7 @@ Environment Variables that Control the Build
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
/envvar/CMAKE_APPLE_SILICON_PROCESSOR
|
||||
/envvar/CMAKE_BUILD_PARALLEL_LEVEL
|
||||
/envvar/CMAKE_CONFIG_TYPE
|
||||
/envvar/CMAKE_EXPORT_COMPILE_COMMANDS
|
||||
|
@@ -353,6 +353,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_ANDROID_SKIP_ANT_STEP
|
||||
/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN
|
||||
/variable/CMAKE_ANDROID_STL_TYPE
|
||||
/variable/CMAKE_APPLE_SILICON_PROCESSOR
|
||||
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY
|
||||
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
|
||||
/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS
|
||||
|
@@ -53,6 +53,22 @@ Languages
|
||||
|
||||
* ``CUDA`` language support now works on QNX.
|
||||
|
||||
Platforms
|
||||
---------
|
||||
|
||||
* Apple Silicon is now supported (since CMake 3.19.2):
|
||||
|
||||
* The :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` is selected using ``uname -m``.
|
||||
Since this may vary based on CMake's own architecture and that of
|
||||
the invoking process tree, the :variable:`CMAKE_APPLE_SILICON_PROCESSOR`
|
||||
variable or :envvar:`CMAKE_APPLE_SILICON_PROCESSOR` environment
|
||||
variable may be set to specify a host architecture explicitly.
|
||||
|
||||
* If :variable:`CMAKE_OSX_ARCHITECTURES` is not set, CMake adds explicit
|
||||
flags to tell the compiler to build for the
|
||||
:variable:`CMAKE_HOST_SYSTEM_PROCESSOR` so the toolchain does not
|
||||
have to guess based on the process tree's architecture.
|
||||
|
||||
File-Based API
|
||||
--------------
|
||||
|
||||
@@ -357,3 +373,11 @@ Changes made since CMake 3.19.0 include the following.
|
||||
It requires macOS 10.10 or newer.
|
||||
The package file naming pattern has been changed from
|
||||
``cmake-$ver-Darwin-x86_64`` to ``cmake-$ver-macos-universal``.
|
||||
|
||||
* Apple Silicon host architecture selection support was updated.
|
||||
CMake 3.19.0 and 3.19.1 always chose ``arm64`` as the host architecture.
|
||||
CMake 3.19.2 returns to using ``uname -m`` as CMake 3.18 and below did.
|
||||
Since this may vary based on CMake's own architecture and that of
|
||||
the invoking process tree, the :variable:`CMAKE_APPLE_SILICON_PROCESSOR`
|
||||
variable or :envvar:`CMAKE_APPLE_SILICON_PROCESSOR` environment
|
||||
variable may be set to specify a host architecture explicitly.
|
||||
|
15
Help/variable/CMAKE_APPLE_SILICON_PROCESSOR.rst
Normal file
15
Help/variable/CMAKE_APPLE_SILICON_PROCESSOR.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
CMAKE_APPLE_SILICON_PROCESSOR
|
||||
-----------------------------
|
||||
|
||||
.. versionadded:: 3.19.2
|
||||
|
||||
On Apple Silicon hosts running macOS, set this variable to tell
|
||||
CMake what architecture to use for :variable:`CMAKE_HOST_SYSTEM_PROCESSOR`.
|
||||
The value must be either ``arm64`` or ``x86_64``.
|
||||
|
||||
The value of this variable should never be modified by project code.
|
||||
It is meant to be set by a toolchain file specified by the
|
||||
:variable:`CMAKE_TOOLCHAIN_FILE` variable, or as a cache entry
|
||||
provided by the user, e.g. via ``-DCMAKE_APPLE_SILICON_PROCESSOR=...``.
|
||||
|
||||
See also the :envvar:`CMAKE_APPLE_SILICON_PROCESSOR` environment variable.
|
@@ -3,13 +3,40 @@ CMAKE_HOST_SYSTEM_PROCESSOR
|
||||
|
||||
The name of the CPU CMake is running on.
|
||||
|
||||
On Windows, this variable is set to the value of the environment variable
|
||||
``PROCESSOR_ARCHITECTURE``. On systems that support ``uname``, this variable is
|
||||
set to the output of:
|
||||
Windows Platforms
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
- ``uname -m`` on GNU, Linux, Cygwin, Darwin, Android, or
|
||||
On Windows, this variable is set to the value of the environment variable
|
||||
``PROCESSOR_ARCHITECTURE``.
|
||||
|
||||
Unix Platforms
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
On systems that support ``uname``, this variable is set to the output of:
|
||||
|
||||
- ``uname -m`` on GNU, Linux, Cygwin, Android, or
|
||||
- ``arch`` on OpenBSD, or
|
||||
- on other systems,
|
||||
|
||||
* ``uname -p`` if its exit code is nonzero, or
|
||||
* ``uname -m`` otherwise.
|
||||
|
||||
macOS Platforms
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The value of ``uname -m`` is used by default.
|
||||
|
||||
On Apple Silicon hosts, the architecture printed by ``uname -m`` may vary
|
||||
based on CMake's own architecture and that of the invoking process tree.
|
||||
|
||||
.. versionadded:: 3.19.2
|
||||
|
||||
On Apple Silicon hosts:
|
||||
|
||||
* The :variable:`CMAKE_APPLE_SILICON_PROCESSOR` variable or
|
||||
the :envvar:`CMAKE_APPLE_SILICON_PROCESSOR` environment variable
|
||||
may be set to specify the host architecture explicitly.
|
||||
|
||||
* If :variable:`CMAKE_OSX_ARCHITECTURES` is not set, CMake adds explicit
|
||||
flags to tell the compiler to build for the host architecture so the
|
||||
toolchain does not have to guess based on the process tree's architecture.
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -228,6 +228,22 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT DEFINED CMake_TEST_APPLE_SILICON)
|
||||
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_TEST_APPLE_SILICON 1)
|
||||
else()
|
||||
set(CMake_TEST_APPLE_SILICON 0)
|
||||
endif()
|
||||
unset(_sysctl_result)
|
||||
unset(_sysctl_stderr)
|
||||
unset(_sysctl_stdout)
|
||||
endif()
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Add tests below here.
|
||||
|
||||
|
3
Tests/RunCMake/AppleSilicon/CMakeLists.txt
Normal file
3
Tests/RunCMake/AppleSilicon/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
27
Tests/RunCMake/AppleSilicon/RunCMakeTest.cmake
Normal file
27
Tests/RunCMake/AppleSilicon/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,27 @@
|
||||
include(RunCMake)
|
||||
|
||||
# Isolate from caller's environment.
|
||||
set(ENV{CMAKE_APPLE_SILICON_PROCESSOR} "")
|
||||
set(ENV{CMAKE_OSX_ARCHITECTURES} "")
|
||||
|
||||
function(run_arch case)
|
||||
set(RunCMake_TEST_OPTIONS ${ARGN})
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${case}-build")
|
||||
run_cmake(${case})
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
endfunction()
|
||||
|
||||
run_arch(default)
|
||||
|
||||
run_arch(arm64-var -DCMAKE_APPLE_SILICON_PROCESSOR=arm64)
|
||||
run_arch(x86_64-var -DCMAKE_APPLE_SILICON_PROCESSOR=x86_64)
|
||||
|
||||
set(ENV{CMAKE_APPLE_SILICON_PROCESSOR} "arm64")
|
||||
run_arch(arm64-env)
|
||||
|
||||
set(ENV{CMAKE_APPLE_SILICON_PROCESSOR} "x86_64")
|
||||
run_arch(x86_64-env)
|
||||
|
||||
set(ENV{CMAKE_APPLE_SILICON_PROCESSOR} "")
|
10
Tests/RunCMake/AppleSilicon/arm64-common.cmake
Normal file
10
Tests/RunCMake/AppleSilicon/arm64-common.cmake
Normal file
@@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
if(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
message(FATAL_ERROR "CMAKE_HOST_SYSTEM_PROCESSOR is '${CMAKE_HOST_SYSTEM_PROCESSOR}', not 'arm64'")
|
||||
endif()
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
||||
message(FATAL_ERROR "CMAKE_OSX_ARCHITECTURES is '${CMAKE_OSX_ARCHITECTURES}', not empty ''")
|
||||
endif()
|
||||
|
||||
add_library(arm64 arm64.c)
|
1
Tests/RunCMake/AppleSilicon/arm64-env.cmake
Normal file
1
Tests/RunCMake/AppleSilicon/arm64-env.cmake
Normal file
@@ -0,0 +1 @@
|
||||
include(arm64-common.cmake)
|
1
Tests/RunCMake/AppleSilicon/arm64-var.cmake
Normal file
1
Tests/RunCMake/AppleSilicon/arm64-var.cmake
Normal file
@@ -0,0 +1 @@
|
||||
include(arm64-common.cmake)
|
9
Tests/RunCMake/AppleSilicon/arm64.c
Normal file
9
Tests/RunCMake/AppleSilicon/arm64.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __aarch64__
|
||||
# error "Not compiling as arm64"
|
||||
#endif
|
||||
#ifdef __x86_64__
|
||||
# error "Incorrectly compiling as x86_64"
|
||||
#endif
|
||||
void arm64_arch(void)
|
||||
{
|
||||
}
|
14
Tests/RunCMake/AppleSilicon/default.c
Normal file
14
Tests/RunCMake/AppleSilicon/default.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#if defined(HOST_ARM64)
|
||||
# if !defined(__aarch64__)
|
||||
# error "Not compiling as host arm64"
|
||||
# endif
|
||||
#elif defined(HOST_X86_64)
|
||||
# if !defined(__x86_64__)
|
||||
# error "Not compiling as host x86_64"
|
||||
# endif
|
||||
#else
|
||||
# error "One of HOST_ARM64 or HOST_X86_64 must be defined."
|
||||
#endif
|
||||
void default_arch(void)
|
||||
{
|
||||
}
|
15
Tests/RunCMake/AppleSilicon/default.cmake
Normal file
15
Tests/RunCMake/AppleSilicon/default.cmake
Normal file
@@ -0,0 +1,15 @@
|
||||
enable_language(C)
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
set(host_def HOST_ARM64)
|
||||
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
set(host_def HOST_X86_64)
|
||||
else()
|
||||
message(FATAL_ERROR "CMAKE_HOST_SYSTEM_PROCESSOR is '${CMAKE_HOST_SYSTEM_PROCESSOR}', not 'arm64' or 'x86_64'")
|
||||
endif()
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
||||
message(FATAL_ERROR "CMAKE_OSX_ARCHITECTURES is '${CMAKE_OSX_ARCHITECTURES}', not empty ''")
|
||||
endif()
|
||||
|
||||
add_library(default default.c)
|
||||
target_compile_definitions(default PRIVATE ${host_def})
|
10
Tests/RunCMake/AppleSilicon/x86_64-common.cmake
Normal file
10
Tests/RunCMake/AppleSilicon/x86_64-common.cmake
Normal file
@@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
if(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
message(FATAL_ERROR "CMAKE_HOST_SYSTEM_PROCESSOR is '${CMAKE_HOST_SYSTEM_PROCESSOR}', not 'x86_64'")
|
||||
endif()
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
||||
message(FATAL_ERROR "CMAKE_OSX_ARCHITECTURES is '${CMAKE_OSX_ARCHITECTURES}', not empty ''")
|
||||
endif()
|
||||
|
||||
add_library(x86_64 x86_64.c)
|
1
Tests/RunCMake/AppleSilicon/x86_64-env.cmake
Normal file
1
Tests/RunCMake/AppleSilicon/x86_64-env.cmake
Normal file
@@ -0,0 +1 @@
|
||||
include(x86_64-common.cmake)
|
1
Tests/RunCMake/AppleSilicon/x86_64-var.cmake
Normal file
1
Tests/RunCMake/AppleSilicon/x86_64-var.cmake
Normal file
@@ -0,0 +1 @@
|
||||
include(x86_64-common.cmake)
|
9
Tests/RunCMake/AppleSilicon/x86_64.c
Normal file
9
Tests/RunCMake/AppleSilicon/x86_64.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __x86_64__
|
||||
# error "Not compiling as x86_64"
|
||||
#endif
|
||||
#ifdef __aarch64__
|
||||
# error "Incorrectly compiling as arm64"
|
||||
#endif
|
||||
void x86_64_arch(void)
|
||||
{
|
||||
}
|
@@ -176,6 +176,9 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
|
||||
endif()
|
||||
|
||||
add_RunCMake_test(AndroidTestUtilities)
|
||||
if(CMake_TEST_APPLE_SILICON)
|
||||
add_RunCMake_test(AppleSilicon)
|
||||
endif()
|
||||
set(autogen_with_qt5 FALSE)
|
||||
if(CMake_TEST_Qt5)
|
||||
find_package(Qt5Widgets QUIET NO_MODULE)
|
||||
|
Reference in New Issue
Block a user