diff options
18 files changed, 106 insertions, 18 deletions
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index 7435d9a..f233d08 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst @@ -399,8 +399,10 @@ Configure use of an Android NDK with the following variables: be false unless using a NDK that does not provide unified headers. :variable:`CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION` - Set to the version of the NDK toolchain to be selected as the compiler. - If not specified, the default will be the latest available GCC toolchain. + On NDK r19 or above, this variable must be unset or set to ``clang``. + On NDK r18 or below, set this to the version of the NDK toolchain to + be selected as the compiler. If not specified, the default will be + the latest available GCC toolchain. :variable:`CMAKE_ANDROID_STL_TYPE` Set to specify which C++ standard library to use. If not specified, diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst index 5ae55d1..22808e3 100644 --- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst +++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst @@ -3,7 +3,11 @@ CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION When :ref:`Cross Compiling for Android with the NDK`, this variable may be set to specify the version of the toolchain to be used -as the compiler. The variable must be set to one of these forms: +as the compiler. + +On NDK r19 or above, this variable must be unset or set to ``clang``. + +On NDK r18 or below, this variable must be set to one of these forms: * ``<major>.<minor>``: GCC of specified version * ``clang<major>.<minor>``: Clang of specified version diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake index 9ed1e01..847178f 100644 --- a/Modules/Platform/Android-Clang.cmake +++ b/Modules/Platform/Android-Clang.cmake @@ -40,6 +40,9 @@ macro(__android_compiler_clang lang) endif() if(NOT CMAKE_${lang}_COMPILER_TARGET) set(CMAKE_${lang}_COMPILER_TARGET "${_ANDROID_ABI_CLANG_TARGET}") + if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) + string(APPEND CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_VERSION}") + endif() list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") endif() endmacro() diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake index fb9ebd0..1affcd0 100644 --- a/Modules/Platform/Android-Common.cmake +++ b/Modules/Platform/Android-Common.cmake @@ -47,7 +47,41 @@ if(CMAKE_ANDROID_NDK) endif() if(CMAKE_ANDROID_STL_TYPE) - if(CMAKE_ANDROID_NDK) + if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) + if(CMAKE_ANDROID_STL_TYPE STREQUAL "system") + set(_ANDROID_STL_EXCEPTIONS 0) + set(_ANDROID_STL_RTTI 0) + macro(__android_stl lang) + string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libstdc++") + endmacro() + elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_static") + set(_ANDROID_STL_EXCEPTIONS 1) + set(_ANDROID_STL_RTTI 1) + macro(__android_stl lang) + string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++") + string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -static-libstdc++") + endmacro() + elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_shared") + set(_ANDROID_STL_EXCEPTIONS 1) + set(_ANDROID_STL_RTTI 1) + macro(__android_stl lang) + string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++") + endmacro() + elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "none") + set(_ANDROID_STL_RTTI 0) + set(_ANDROID_STL_EXCEPTIONS 0) + macro(__android_stl lang) + # FIXME: Add a way to add project-wide language-specific compile-only flags. + set(CMAKE_CXX_COMPILE_OBJECT + "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++") + string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -nostdlib++") + endmacro() + else() + message(FATAL_ERROR + "Android: STL '${CMAKE_ANDROID_STL_TYPE}' not supported by this NDK." + ) + endif() + elseif(CMAKE_ANDROID_NDK) macro(__android_stl_inc lang dir req) if(EXISTS "${dir}") @@ -152,6 +186,10 @@ macro(__android_compiler_common lang) __android_stl(CXX) endif() + if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) + string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -latomic -lm") + endif() + # <ndk>/build/core/definitions.mk appends the sysroot's include directory # explicitly at the end of the command-line include path so that it # precedes the toolchain's builtin include directories. This is @@ -161,7 +199,7 @@ macro(__android_compiler_common lang) # # Do not do this for a standalone toolchain because it is already # tied to a specific API version. - if(CMAKE_ANDROID_NDK) + if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) if(CMAKE_SYSROOT_COMPILE) set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}") else() diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index 56ed328..e7c1b48 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -221,8 +221,15 @@ if(CMAKE_ANDROID_NDK) else() message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.") endif() + + # Look for a unified toolchain/sysroot provided with the NDK. + set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}") + if(NOT IS_DIRECTORY "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/sysroot") + set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "") + endif() else() set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "") + set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "") endif() # https://developer.android.com/ndk/guides/abis.html @@ -370,6 +377,7 @@ if(CMAKE_ANDROID_NDK) "set(CMAKE_ANDROID_ARCH_TRIPLE \"${CMAKE_ANDROID_ARCH_TRIPLE}\")\n" "set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS \"${CMAKE_ANDROID_NDK_DEPRECATED_HEADERS}\")\n" "set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG \"${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}\")\n" + "set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED \"${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}\")\n" ) endif() diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake index 1dcb939..a5d2820 100644 --- a/Modules/Platform/Android-Initialize.cmake +++ b/Modules/Platform/Android-Initialize.cmake @@ -19,6 +19,11 @@ endif() set(CMAKE_BUILD_TYPE_INIT Debug) +# Skip sysroot selection if the NDK has a unified toolchain. +if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) + return() +endif() + if(NOT CMAKE_SYSROOT) if(CMAKE_ANDROID_NDK) set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}") diff --git a/Modules/Platform/Android/Determine-Compiler-NDK.cmake b/Modules/Platform/Android/Determine-Compiler-NDK.cmake index e5a7390..e009c10 100644 --- a/Modules/Platform/Android/Determine-Compiler-NDK.cmake +++ b/Modules/Platform/Android/Determine-Compiler-NDK.cmake @@ -1,6 +1,31 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. +# In Android NDK r19 and above there is a single clang toolchain. +if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) + if(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION STREQUAL "clang") + message(FATAL_ERROR + "Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value '${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}' " + "is not supported by this NDK. It must be 'clang' or not set at all." + ) + endif() + message(STATUS "Android: Selected unified Clang toolchain") + set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "clang") + set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/clang${_ANDROID_HOST_EXT}") + set(_ANDROID_TOOL_C_TOOLCHAIN_MACHINE "${CMAKE_ANDROID_ARCH_TRIPLE}") + set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "") + set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN "") + set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/${CMAKE_ANDROID_ARCH_TRIPLE}-") + set(_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}") + set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/clang++${_ANDROID_HOST_EXT}") + set(_ANDROID_TOOL_CXX_TOOLCHAIN_MACHINE "${CMAKE_ANDROID_ARCH_TRIPLE}") + set(_ANDROID_TOOL_CXX_TOOLCHAIN_VERSION "") + set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "") + set(_ANDROID_TOOL_CXX_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/${CMAKE_ANDROID_ARCH_TRIPLE}-") + set(_ANDROID_TOOL_CXX_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}") + return() +endif() + # In Android NDK releases there is build system toolchain selection logic in # these files: # diff --git a/Modules/Platform/Android/abi-common.cmake b/Modules/Platform/Android/abi-common.cmake index 6bce3c7..b01ef61 100644 --- a/Modules/Platform/Android/abi-common.cmake +++ b/Modules/Platform/Android/abi-common.cmake @@ -3,7 +3,7 @@ string(APPEND _ANDROID_ABI_INIT_CFLAGS " -no-canonical-prefixes" ) -if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS) +if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS) string(APPEND _ANDROID_ABI_INIT_CFLAGS " -D__ANDROID_API__=${CMAKE_SYSTEM_VERSION}") endif() diff --git a/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt b/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt index 8d0bdc2..a228ccc 100644 --- a/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt +++ b/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt @@ -1,2 +1,2 @@ -- Android: Targeting API '[0-9]+' with architecture 'arm64', ABI 'arm64-v8a', and processor 'aarch64' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') diff --git a/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt index 3741da3..72ec00e 100644 --- a/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt +++ b/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt @@ -1,3 +1,3 @@ -- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi', and processor 'armv5te' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') .*-- CMAKE_ANDROID_ARM_MODE=1 diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt index ac2bfd5..8bd87fa 100644 --- a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt +++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt @@ -1,3 +1,3 @@ -- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') .*-- CMAKE_ANDROID_ARM_NEON=1 diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt index 0edb4f7..554548e 100644 --- a/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt +++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt @@ -1,3 +1,3 @@ -- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') .*-- CMAKE_ANDROID_ARM_NEON=0 diff --git a/Tests/RunCMake/Android/ndk-badver-stderr.txt b/Tests/RunCMake/Android/ndk-badver-stderr.txt index df2c5e6..ce6bc4e 100644 --- a/Tests/RunCMake/Android/ndk-badver-stderr.txt +++ b/Tests/RunCMake/Android/ndk-badver-stderr.txt @@ -1,11 +1,12 @@ ^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\): - Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value 'badver' is not one + Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value 'badver' is not( + supported by this NDK. It must be 'clang' or not set at all\.| one of the allowed forms: <major>.<minor> = GCC of specified version clang<major>.<minor> = Clang of specified version clang = Clang of most recent available version - +) Call Stack \(most recent call first\): .* ndk-badver.cmake:1 \(enable_language\) diff --git a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt index adacaf1..aec91d9 100644 --- a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt +++ b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt @@ -1,4 +1,6 @@ -^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\): +^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):( + Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value '1.0' is not + supported by this NDK. It must be 'clang' or not set at all.| Android: No toolchain for ABI 'armeabi(-v7a)?' found in the NDK: .* @@ -6,7 +8,7 @@ of the version specified by CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION: 1\.0 - +) Call Stack \(most recent call first\): .* ndk-badvernum.cmake:1 \(enable_language\) diff --git a/Tests/RunCMake/Android/ndk-mips-stdout.txt b/Tests/RunCMake/Android/ndk-mips-stdout.txt index c744683..8ce544d 100644 --- a/Tests/RunCMake/Android/ndk-mips-stdout.txt +++ b/Tests/RunCMake/Android/ndk-mips-stdout.txt @@ -1,2 +1,2 @@ -- Android: Targeting API '[0-9]+' with architecture 'mips', ABI 'mips', and processor 'mips' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') diff --git a/Tests/RunCMake/Android/ndk-mips64-stdout.txt b/Tests/RunCMake/Android/ndk-mips64-stdout.txt index 839ddfd..1d7edea 100644 --- a/Tests/RunCMake/Android/ndk-mips64-stdout.txt +++ b/Tests/RunCMake/Android/ndk-mips64-stdout.txt @@ -1,2 +1,2 @@ -- Android: Targeting API '[0-9]+' with architecture 'mips64', ABI 'mips64', and processor 'mips64' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') diff --git a/Tests/RunCMake/Android/ndk-x86-stdout.txt b/Tests/RunCMake/Android/ndk-x86-stdout.txt index 2dbb2f0..8d710fe 100644 --- a/Tests/RunCMake/Android/ndk-x86-stdout.txt +++ b/Tests/RunCMake/Android/ndk-x86-stdout.txt @@ -1,2 +1,2 @@ -- Android: Targeting API '[0-9]+' with architecture 'x86', ABI 'x86', and processor 'i686' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') diff --git a/Tests/RunCMake/Android/ndk-x86_64-stdout.txt b/Tests/RunCMake/Android/ndk-x86_64-stdout.txt index a7ae91d..695a088 100644 --- a/Tests/RunCMake/Android/ndk-x86_64-stdout.txt +++ b/Tests/RunCMake/Android/ndk-x86_64-stdout.txt @@ -1,2 +1,2 @@ -- Android: Targeting API '[0-9]+' with architecture 'x86_64', ABI 'x86_64', and processor 'x86_64' --- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+' +-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+') |