mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-04 21:00:17 -06:00
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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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:
|
||||
#
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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 '[^']+')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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\)
|
||||
|
||||
@@ -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\)
|
||||
|
||||
@@ -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 '[^']+')
|
||||
|
||||
@@ -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 '[^']+')
|
||||
|
||||
@@ -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 '[^']+')
|
||||
|
||||
@@ -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 '[^']+')
|
||||
|
||||
Reference in New Issue
Block a user