diff options
22 files changed, 245 insertions, 16 deletions
diff --git a/Help/envvar/CMAKE_APPLE_SILICON_PROCESSOR.rst b/Help/envvar/CMAKE_APPLE_SILICON_PROCESSOR.rst new file mode 100644 index 0000000..adecb72 --- /dev/null +++ b/Help/envvar/CMAKE_APPLE_SILICON_PROCESSOR.rst @@ -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. diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index 26e0c48..bc1fa1d 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -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 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 4420468..f898ae9 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -355,6 +355,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 diff --git a/Help/release/3.19.rst b/Help/release/3.19.rst index 899e745..4f26058 100644 --- a/Help/release/3.19.rst +++ b/Help/release/3.19.rst @@ -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. diff --git a/Help/variable/CMAKE_APPLE_SILICON_PROCESSOR.rst b/Help/variable/CMAKE_APPLE_SILICON_PROCESSOR.rst new file mode 100644 index 0000000..ad297c3 --- /dev/null +++ b/Help/variable/CMAKE_APPLE_SILICON_PROCESSOR.rst @@ -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. diff --git a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst index 5f08728..c305779 100644 --- a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst +++ b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst @@ -3,13 +3,40 @@ CMAKE_HOST_SYSTEM_PROCESSOR The name of the CPU CMake is running on. +Windows Platforms +^^^^^^^^^^^^^^^^^ + 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: +``PROCESSOR_ARCHITECTURE``. + +Unix Platforms +^^^^^^^^^^^^^^ + +On systems that support ``uname``, this variable is set to the output of: -- ``uname -m`` on GNU, Linux, Cygwin, Darwin, Android, or +- ``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. 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 diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 14095dd..2a59d66 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -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. diff --git a/Tests/RunCMake/AppleSilicon/CMakeLists.txt b/Tests/RunCMake/AppleSilicon/CMakeLists.txt new file mode 100644 index 0000000..ab1a20c --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.19) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/AppleSilicon/RunCMakeTest.cmake b/Tests/RunCMake/AppleSilicon/RunCMakeTest.cmake new file mode 100644 index 0000000..39e462e --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/RunCMakeTest.cmake @@ -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} "") diff --git a/Tests/RunCMake/AppleSilicon/arm64-common.cmake b/Tests/RunCMake/AppleSilicon/arm64-common.cmake new file mode 100644 index 0000000..5a13728 --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/arm64-common.cmake @@ -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) diff --git a/Tests/RunCMake/AppleSilicon/arm64-env.cmake b/Tests/RunCMake/AppleSilicon/arm64-env.cmake new file mode 100644 index 0000000..8cb9dbc --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/arm64-env.cmake @@ -0,0 +1 @@ +include(arm64-common.cmake) diff --git a/Tests/RunCMake/AppleSilicon/arm64-var.cmake b/Tests/RunCMake/AppleSilicon/arm64-var.cmake new file mode 100644 index 0000000..8cb9dbc --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/arm64-var.cmake @@ -0,0 +1 @@ +include(arm64-common.cmake) diff --git a/Tests/RunCMake/AppleSilicon/arm64.c b/Tests/RunCMake/AppleSilicon/arm64.c new file mode 100644 index 0000000..d5f65fe --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/arm64.c @@ -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) +{ +} diff --git a/Tests/RunCMake/AppleSilicon/default.c b/Tests/RunCMake/AppleSilicon/default.c new file mode 100644 index 0000000..7b0535b --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/default.c @@ -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) +{ +} diff --git a/Tests/RunCMake/AppleSilicon/default.cmake b/Tests/RunCMake/AppleSilicon/default.cmake new file mode 100644 index 0000000..f160e25 --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/default.cmake @@ -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}) diff --git a/Tests/RunCMake/AppleSilicon/x86_64-common.cmake b/Tests/RunCMake/AppleSilicon/x86_64-common.cmake new file mode 100644 index 0000000..602bf92 --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/x86_64-common.cmake @@ -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) diff --git a/Tests/RunCMake/AppleSilicon/x86_64-env.cmake b/Tests/RunCMake/AppleSilicon/x86_64-env.cmake new file mode 100644 index 0000000..a44eaa4 --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/x86_64-env.cmake @@ -0,0 +1 @@ +include(x86_64-common.cmake) diff --git a/Tests/RunCMake/AppleSilicon/x86_64-var.cmake b/Tests/RunCMake/AppleSilicon/x86_64-var.cmake new file mode 100644 index 0000000..a44eaa4 --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/x86_64-var.cmake @@ -0,0 +1 @@ +include(x86_64-common.cmake) diff --git a/Tests/RunCMake/AppleSilicon/x86_64.c b/Tests/RunCMake/AppleSilicon/x86_64.c new file mode 100644 index 0000000..cd3cc9b --- /dev/null +++ b/Tests/RunCMake/AppleSilicon/x86_64.c @@ -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) +{ +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 7f79982..0cab867 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -186,6 +186,9 @@ set_property(TEST RunCMake.ABI APPEND PROPERTY LABELS "CUDA") 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) |