diff options
author | Brad King <brad.king@kitware.com> | 2019-07-26 16:48:35 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2019-07-26 18:17:07 (GMT) |
commit | 97bca2f9fab58fcf5bbcb29e1e7e86e37b5cc1e0 (patch) | |
tree | 048fee25cd8797b3527994c504c5b8ce50e2ede2 /Modules | |
parent | 19f36c5fb2497703e4f071b3a9424a8d121ccef9 (diff) | |
download | CMake-97bca2f9fab58fcf5bbcb29e1e7e86e37b5cc1e0.zip CMake-97bca2f9fab58fcf5bbcb29e1e7e86e37b5cc1e0.tar.gz CMake-97bca2f9fab58fcf5bbcb29e1e7e86e37b5cc1e0.tar.bz2 |
Android: Use unified toolchain in NDK r19+
The NDK build system now uses only a single toolchain in
<ndk>/toolchains/llvm/prebuilt/<host>
Its compilers are always `bin/{clang,clang++}` and its binutils are
always `bin/<triple>-*`. It is a standalone toolchain:
* The Anrdoid API level is specified at the end of `--target=`.
* The standard library may be specified via `-stdlib=`.
* No need to pass system includes or libraries explicitly.
* No need to pass `--sysroot` or `-gcc-toolchain`.
Teach CMake to recognize NDK versions that have a unified
toolchain with its own sysroot and use the above approach.
Fixes: #18739
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/Platform/Android-Clang.cmake | 3 | ||||
-rw-r--r-- | Modules/Platform/Android-Common.cmake | 42 | ||||
-rw-r--r-- | Modules/Platform/Android-Determine.cmake | 8 | ||||
-rw-r--r-- | Modules/Platform/Android-Initialize.cmake | 5 | ||||
-rw-r--r-- | Modules/Platform/Android/Determine-Compiler-NDK.cmake | 25 | ||||
-rw-r--r-- | Modules/Platform/Android/abi-common.cmake | 2 |
6 files changed, 82 insertions, 3 deletions
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() |