Android: Add support for unified headers

The unified headers are preferred as of NDK r15, so use them by default
if available and provide an option to use the deprecated headers.

Inspired-by: Florent Castelli <florent.castelli@gmail.com>
Fixes: #16584
This commit is contained in:
Brad King 2017-06-12 10:57:00 -04:00
parent a131316a95
commit 3d00be13ee
8 changed files with 72 additions and 16 deletions

View File

@ -385,6 +385,11 @@ Configure use of an Android NDK with the following variables:
If not specified, a default for this variable will be chosen
as specified :ref:`above <Cross Compiling for Android>`.
:variable:`CMAKE_ANDROID_NDK_DEPRECATED_HEADERS`
Set to a true value to use the deprecated per-api-level headers
instead of the unified headers. If not specified, the default will
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.

View File

@ -255,6 +255,7 @@ Variables that Control the Build
/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
/variable/CMAKE_ANDROID_NDK
/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS
/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG
/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION
/variable/CMAKE_ANDROID_PROCESS_MAX

View File

@ -62,6 +62,11 @@ Commands
Variables
---------
* A :variable:`CMAKE_ANDROID_NDK_DEPRECATED_HEADERS` variable was added
for use when :ref:`Cross Compiling for Android with the NDK` to request
use of the deprecated headers even when unified headers are available.
The default is now to use unified headers if available.
* A :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS` variable was introduced to
allow :variable:`CMAKE_AUTOMOC` to extract additional dependency file names
for ``moc`` from the contents of source files.

View File

@ -0,0 +1,9 @@
CMAKE_ANDROID_NDK_DEPRECATED_HEADERS
------------------------------------
When :ref:`Cross Compiling for Android with the NDK`, this variable
may be set to specify whether to use the deprecated per-api-level
headers instead of the unified headers.
If not specified, the default will be *false* if using a NDK version
that provides the unified headers and *true* otherwise.

View File

@ -161,6 +161,9 @@ macro(__android_compiler_common lang)
# tied to a specific API version.
if(CMAKE_ANDROID_NDK)
list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include")
if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}")
endif()
list(REMOVE_ITEM CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include")
endif()
endmacro()

View File

@ -197,22 +197,30 @@ endif()
# https://developer.android.com/ndk/guides/abis.html
set(_ANDROID_ABI_arm64-v8a_PROC "aarch64")
set(_ANDROID_ABI_arm64-v8a_ARCH "arm64")
set(_ANDROID_ABI_armeabi-v7a_PROC "armv7-a")
set(_ANDROID_ABI_armeabi-v7a_ARCH "arm")
set(_ANDROID_ABI_armeabi-v6_PROC "armv6")
set(_ANDROID_ABI_armeabi-v6_ARCH "arm")
set(_ANDROID_ABI_armeabi_PROC "armv5te")
set(_ANDROID_ABI_armeabi_ARCH "arm")
set(_ANDROID_ABI_mips_PROC "mips")
set(_ANDROID_ABI_mips_ARCH "mips")
set(_ANDROID_ABI_mips64_PROC "mips64")
set(_ANDROID_ABI_mips64_ARCH "mips64")
set(_ANDROID_ABI_x86_PROC "i686")
set(_ANDROID_ABI_x86_ARCH "x86")
set(_ANDROID_ABI_x86_64_PROC "x86_64")
set(_ANDROID_ABI_x86_64_ARCH "x86_64")
set(_ANDROID_ABI_arm64-v8a_PROC "aarch64")
set(_ANDROID_ABI_arm64-v8a_ARCH "arm64")
set(_ANDROID_ABI_arm64-v8a_HEADER "aarch64-linux-android")
set(_ANDROID_ABI_armeabi-v7a_PROC "armv7-a")
set(_ANDROID_ABI_armeabi-v7a_ARCH "arm")
set(_ANDROID_ABI_armeabi-v7a_HEADER "arm-linux-androideabi")
set(_ANDROID_ABI_armeabi-v6_PROC "armv6")
set(_ANDROID_ABI_armeabi-v6_ARCH "arm")
set(_ANDROID_ABI_armeabi-v6_HEADER "arm-linux-androideabi")
set(_ANDROID_ABI_armeabi_PROC "armv5te")
set(_ANDROID_ABI_armeabi_ARCH "arm")
set(_ANDROID_ABI_armeabi_HEADER "arm-linux-androideabi")
set(_ANDROID_ABI_mips_PROC "mips")
set(_ANDROID_ABI_mips_ARCH "mips")
set(_ANDROID_ABI_mips_HEADER "mipsel-linux-android")
set(_ANDROID_ABI_mips64_PROC "mips64")
set(_ANDROID_ABI_mips64_ARCH "mips64")
set(_ANDROID_ABI_mips64_HEADER "mips64el-linux-android")
set(_ANDROID_ABI_x86_PROC "i686")
set(_ANDROID_ABI_x86_ARCH "x86")
set(_ANDROID_ABI_x86_HEADER "i686-linux-android")
set(_ANDROID_ABI_x86_64_PROC "x86_64")
set(_ANDROID_ABI_x86_64_ARCH "x86_64")
set(_ANDROID_ABI_x86_64_HEADER "x86_64-linux-android")
set(_ANDROID_PROC_aarch64_ARCH_ABI "arm64-v8a")
set(_ANDROID_PROC_armv7-a_ARCH_ABI "armeabi-v7a")
@ -264,6 +272,7 @@ if(_ANDROID_SYSROOT_ARCH AND NOT "x${_ANDROID_SYSROOT_ARCH}" STREQUAL "x${CMAKE_
"does not match architecture '${CMAKE_ANDROID_ARCH}' for the ABI '${CMAKE_ANDROID_ARCH_ABI}'."
)
endif()
set(CMAKE_ANDROID_ARCH_HEADER_TRIPLE "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_HEADER}")
# Select a processor.
if(NOT CMAKE_SYSTEM_PROCESSOR)
@ -275,6 +284,16 @@ if(NOT _ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC STREQUAL CMAKE_SYSTEM_PROCESS
message(FATAL_ERROR "Android: The specified CMAKE_ANDROID_ARCH_ABI='${CMAKE_ANDROID_ARCH_ABI}' and CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}' is not a valid combination.")
endif()
if(CMAKE_ANDROID_NDK AND NOT DEFINED CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
if(IS_DIRECTORY "${CMAKE_ANDROID_NDK}/sysroot/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}")
# Unified headers exist so we use them by default.
set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS 0)
else()
# Unified headers do not exist so use the deprecated headers.
set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS 1)
endif()
endif()
# Save the Android-specific information in CMakeSystem.cmake.
set(CMAKE_SYSTEM_CUSTOM_CODE "
set(CMAKE_ANDROID_NDK \"${CMAKE_ANDROID_NDK}\")
@ -283,6 +302,13 @@ set(CMAKE_ANDROID_ARCH \"${CMAKE_ANDROID_ARCH}\")
set(CMAKE_ANDROID_ARCH_ABI \"${CMAKE_ANDROID_ARCH_ABI}\")
")
if(CMAKE_ANDROID_NDK)
string(APPEND CMAKE_SYSTEM_CUSTOM_CODE
"set(CMAKE_ANDROID_ARCH_HEADER_TRIPLE \"${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}\")\n"
"set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS \"${CMAKE_ANDROID_NDK_DEPRECATED_HEADERS}\")\n"
)
endif()
# Select an ARM variant.
if(CMAKE_ANDROID_ARCH_ABI MATCHES "^armeabi")
if(CMAKE_ANDROID_ARM_MODE)

View File

@ -20,6 +20,9 @@ endif()
if(NOT CMAKE_SYSROOT)
if(CMAKE_ANDROID_NDK)
set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}")
if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
set(CMAKE_SYSROOT_COMPILE "${CMAKE_ANDROID_NDK}/sysroot")
endif()
elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
set(CMAKE_SYSROOT "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot")
endif()

View File

@ -3,6 +3,10 @@ string(APPEND _ANDROID_ABI_INIT_CFLAGS
" -no-canonical-prefixes"
)
if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
string(APPEND _ANDROID_ABI_INIT_CFLAGS " -D__ANDROID_API__=${CMAKE_SYSTEM_VERSION}")
endif()
if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE
AND NOT CMAKE_SYSTEM_VERSION VERSION_LESS 16)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)