2016-06-02 17:23:20 +03:00
#=============================================================================
# Copyright 2015-2016 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# When CMAKE_SYSTEM_NAME is "Android", CMakeDetermineSystem loads this module.
2016-06-02 18:16:21 +03:00
# This module detects platform-wide information about the Android target
# in order to store it in "CMakeSystem.cmake".
2016-06-02 17:24:44 +03:00
# Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
# implemented in the CMake VS IDE generators. Avoid interfering with
# that functionality for now. Later we may try to integrate this.
if ( CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android" )
return ( )
endif ( )
2016-06-02 18:16:21 +03:00
2016-06-06 20:56:21 +03:00
# Commonly used Android toolchain files that pre-date CMake upstream support
# set CMAKE_SYSTEM_VERSION to 1. Avoid interfering with them.
if ( CMAKE_SYSTEM_VERSION EQUAL 1 )
return ( )
endif ( )
2016-06-02 23:21:36 +03:00
# If the user provided CMAKE_SYSROOT for us, extract information from it.
set ( _ANDROID_SYSROOT_NDK "" )
set ( _ANDROID_SYSROOT_API "" )
set ( _ANDROID_SYSROOT_ARCH "" )
2016-06-03 22:06:58 +03:00
set ( _ANDROID_SYSROOT_STANDALONE_TOOLCHAIN "" )
2016-06-02 23:21:36 +03:00
if ( CMAKE_SYSROOT )
if ( NOT IS_DIRECTORY "${CMAKE_SYSROOT}" )
message ( FATAL_ERROR
" A n d r o i d : T h e s p e c i f i e d C M A K E _ S Y S R O O T : \ n "
" $ { C M A K E _ S Y S R O O T } \ n "
" i s n o t a n e x i s t i n g d i r e c t o r y . "
)
endif ( )
if ( CMAKE_SYSROOT MATCHES "^([^\\\n]*)/platforms/android-([0-9]+)/arch-([a-z0-9_]+)$" )
set ( _ANDROID_SYSROOT_NDK "${CMAKE_MATCH_1}" )
set ( _ANDROID_SYSROOT_API "${CMAKE_MATCH_2}" )
set ( _ANDROID_SYSROOT_ARCH "${CMAKE_MATCH_3}" )
2016-06-03 22:06:58 +03:00
elseif ( CMAKE_SYSROOT MATCHES "^([^\\\n]*)/sysroot$" )
set ( _ANDROID_SYSROOT_STANDALONE_TOOLCHAIN "${CMAKE_MATCH_1}" )
2016-06-02 23:21:36 +03:00
else ( )
message ( FATAL_ERROR
" T h e v a l u e o f C M A K E _ S Y S R O O T : \ n "
" $ { C M A K E _ S Y S R O O T } \ n "
2016-06-03 22:06:58 +03:00
" d o e s n o t m a t c h a n y o f t h e f o r m s : \ n "
2016-06-02 23:21:36 +03:00
" < n d k > / p l a t f o r m s / a n d r o i d - < a p i > / a r c h - < a r c h > \ n "
2016-06-03 22:06:58 +03:00
" < s t a n d a l o n e - t o o l c h a i n > / s y s r o o t \ n "
2016-06-02 23:21:36 +03:00
" w h e r e : \ n "
" < n d k > = A n d r o i d N D K directory ( with forward slashes ) \ n "
" < a p i > = A n d r o i d A P I v e r s i o n number ( decimal digits ) \ n "
2016-06-03 22:06:58 +03:00
" < a r c h > = A n d r o i d A R C H name ( lower case ) \ n "
" < s t a n d a l o n e - t o o l c h a i n > = P a t h t o s t a n d a l o n e t o o l c h a i n p r e f i x \ n "
2016-06-02 23:21:36 +03:00
)
endif ( )
endif ( )
2016-06-02 18:16:21 +03:00
# Find the Android NDK.
if ( CMAKE_ANDROID_NDK )
if ( NOT IS_DIRECTORY "${CMAKE_ANDROID_NDK}" )
message ( FATAL_ERROR
" A n d r o i d : T h e N D K r o o t d i r e c t o r y s p e c i f i e d b y C M A K E _ A N D R O I D _ N D K : \ n "
" $ { C M A K E _ A N D R O I D _ N D K } \ n "
" d o e s n o t e x i s t . "
)
endif ( )
2016-06-03 22:06:58 +03:00
elseif ( CMAKE_ANDROID_STANDALONE_TOOLCHAIN )
if ( NOT IS_DIRECTORY "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}" )
message ( FATAL_ERROR
" A n d r o i d : T h e s t a n d a l o n e t o o l c h a i n d i r e c t o r y s p e c i f i e d b y C M A K E _ A N D R O I D _ S T A N D A L O N E _ T O O L C H A I N : \ n "
" $ { C M A K E _ A N D R O I D _ S T A N D A L O N E _ T O O L C H A I N } \ n "
" d o e s n o t e x i s t . "
)
endif ( )
if ( NOT EXISTS "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
message ( FATAL_ERROR
" A n d r o i d : T h e s t a n d a l o n e t o o l c h a i n d i r e c t o r y s p e c i f i e d b y C M A K E _ A N D R O I D _ S T A N D A L O N E _ T O O L C H A I N : \ n "
" $ { C M A K E _ A N D R O I D _ S T A N D A L O N E _ T O O L C H A I N } \ n "
" d o e s n o t c o n t a i n a s y s r o o t w i t h a k n o w n l a y o u t . T h e f i l e : \ n "
" $ { C M A K E _ A N D R O I D _ S T A N D A L O N E _ T O O L C H A I N } / s y s r o o t / u s r / i n c l u d e / a n d r o i d / a p i - l e v e l . h \ n "
" d o e s n o t e x i s t . "
)
endif ( )
2016-06-02 18:16:21 +03:00
else ( )
2016-06-02 23:21:36 +03:00
if ( IS_DIRECTORY "${_ANDROID_SYSROOT_NDK}" )
set ( CMAKE_ANDROID_NDK "${_ANDROID_SYSROOT_NDK}" )
2016-06-03 22:06:58 +03:00
elseif ( IS_DIRECTORY "${_ANDROID_SYSROOT_STANDALONE_TOOLCHAIN}" )
set ( CMAKE_ANDROID_STANDALONE_TOOLCHAIN "${_ANDROID_SYSROOT_STANDALONE_TOOLCHAIN}" )
2016-06-06 21:55:48 +03:00
elseif ( IS_DIRECTORY "${ANDROID_NDK}" )
file ( TO_CMAKE_PATH "${ANDROID_NDK}" CMAKE_ANDROID_NDK )
elseif ( IS_DIRECTORY "${ANDROID_STANDALONE_TOOLCHAIN}" )
file ( TO_CMAKE_PATH "${ANDROID_STANDALONE_TOOLCHAIN}" CMAKE_ANDROID_STANDALONE_TOOLCHAIN )
2016-06-02 23:21:36 +03:00
elseif ( IS_DIRECTORY "$ENV{ANDROID_NDK_ROOT}" )
2016-06-02 18:16:21 +03:00
file ( TO_CMAKE_PATH "$ENV{ANDROID_NDK_ROOT}" CMAKE_ANDROID_NDK )
2016-06-06 21:55:48 +03:00
elseif ( IS_DIRECTORY "$ENV{ANDROID_NDK}" )
file ( TO_CMAKE_PATH "$ENV{ANDROID_NDK}" CMAKE_ANDROID_NDK )
elseif ( IS_DIRECTORY "$ENV{ANDROID_STANDALONE_TOOLCHAIN}" )
file ( TO_CMAKE_PATH "$ENV{ANDROID_STANDALONE_TOOLCHAIN}" CMAKE_ANDROID_STANDALONE_TOOLCHAIN )
2016-06-02 18:16:21 +03:00
endif ( )
2016-06-03 22:06:58 +03:00
# TODO: Search harder for the NDK or standalone toolchain.
endif ( )
set ( _ANDROID_STANDALONE_TOOLCHAIN_API "" )
if ( CMAKE_ANDROID_STANDALONE_TOOLCHAIN )
set ( _ANDROID_API_LEVEL_H_REGEX "^[\t ]*#[\t ]*define[\t ]+__ANDROID_API__[\t ]+([0-9]+)" )
file ( STRINGS "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h"
_ A N D R O I D _ A P I _ L E V E L _ H _ C O N T E N T R E G E X " $ { _ A N D R O I D _ A P I _ L E V E L _ H _ R E G E X } " )
if ( _ANDROID_API_LEVEL_H_CONTENT MATCHES "${_ANDROID_API_LEVEL_H_REGEX}" )
set ( _ANDROID_STANDALONE_TOOLCHAIN_API "${CMAKE_MATCH_1}" )
endif ( )
2016-06-02 18:16:21 +03:00
endif ( )
2016-06-03 22:06:58 +03:00
if ( NOT CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_STANDALONE_TOOLCHAIN )
message ( FATAL_ERROR "Android: Neither the NDK or a standalone toolchain was found." )
2016-06-02 18:16:21 +03:00
endif ( )
2016-06-02 18:26:32 +03:00
# Select an API.
if ( CMAKE_SYSTEM_VERSION )
set ( _ANDROID_API_VAR CMAKE_SYSTEM_VERSION )
elseif ( CMAKE_ANDROID_API )
set ( CMAKE_SYSTEM_VERSION "${CMAKE_ANDROID_API}" )
set ( _ANDROID_API_VAR CMAKE_ANDROID_API )
2016-06-02 23:21:36 +03:00
elseif ( _ANDROID_SYSROOT_API )
set ( CMAKE_SYSTEM_VERSION "${_ANDROID_SYSROOT_API}" )
set ( _ANDROID_API_VAR CMAKE_SYSROOT )
2016-06-03 22:06:58 +03:00
elseif ( _ANDROID_STANDALONE_TOOLCHAIN_API )
set ( CMAKE_SYSTEM_VERSION "${_ANDROID_STANDALONE_TOOLCHAIN_API}" )
2016-06-02 18:26:32 +03:00
endif ( )
if ( CMAKE_SYSTEM_VERSION )
if ( CMAKE_ANDROID_API AND NOT "x${CMAKE_ANDROID_API}" STREQUAL "x${CMAKE_SYSTEM_VERSION}" )
message ( FATAL_ERROR
" A n d r o i d : T h e A P I s p e c i f i e d b y C M A K E _ A N D R O I D _ A P I = ' $ { C M A K E _ A N D R O I D _ A P I } ' i s n o t c o n s i s t e n t w i t h C M A K E _ S Y S T E M _ V E R S I O N = ' $ { C M A K E _ S Y S T E M _ V E R S I O N } ' . "
)
endif ( )
2016-06-02 23:21:36 +03:00
if ( _ANDROID_SYSROOT_API )
foreach ( v CMAKE_ANDROID_API CMAKE_SYSTEM_VERSION )
if ( ${ v } AND NOT "x${_ANDROID_SYSROOT_API}" STREQUAL "x${${v}}" )
message ( FATAL_ERROR
" A n d r o i d : T h e A P I s p e c i f i e d b y $ { v } = ' $ { $ { v } } ' i s n o t c o n s i s t e n t w i t h C M A K E _ S Y S R O O T : \ n "
" $ { C M A K E _ S Y S R O O T } "
)
endif ( )
endforeach ( )
endif ( )
2016-06-02 18:26:32 +03:00
if ( CMAKE_ANDROID_NDK AND NOT IS_DIRECTORY "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}" )
message ( FATAL_ERROR
" A n d r o i d : T h e A P I s p e c i f i e d b y $ { _ A N D R O I D _ A P I _ V A R } = ' $ { $ { _ A N D R O I D _ A P I _ V A R } } ' d o e s n o t e x i s t i n t h e N D K . "
" T h e d i r e c t o r y : \ n "
" $ { C M A K E _ A N D R O I D _ N D K } / p l a t f o r m s / a n d r o i d - $ { C M A K E _ S Y S T E M _ V E R S I O N } \ n "
" d o e s n o t e x i s t . "
)
endif ( )
elseif ( CMAKE_ANDROID_NDK )
file ( GLOB _ANDROID_APIS_1 RELATIVE "${CMAKE_ANDROID_NDK}/platforms" "${CMAKE_ANDROID_NDK}/platforms/android-[0-9]" )
file ( GLOB _ANDROID_APIS_2 RELATIVE "${CMAKE_ANDROID_NDK}/platforms" "${CMAKE_ANDROID_NDK}/platforms/android-[0-9][0-9]" )
list ( SORT _ANDROID_APIS_1 )
list ( SORT _ANDROID_APIS_2 )
set ( _ANDROID_APIS ${ _ANDROID_APIS_1 } ${ _ANDROID_APIS_2 } )
unset ( _ANDROID_APIS_1 )
unset ( _ANDROID_APIS_2 )
if ( _ANDROID_APIS STREQUAL "" )
message ( FATAL_ERROR
" A n d r o i d : N o A P I s f o u n d i n t h e N D K . N o \ n "
" $ { C M A K E _ A N D R O I D _ N D K } / p l a t f o r m s / a n d r o i d - * \ n "
" d i r e c t o r i e s e x i s t . "
)
endif ( )
string ( REPLACE "android-" "" _ANDROID_APIS "${_ANDROID_APIS}" )
list ( REVERSE _ANDROID_APIS )
list ( GET _ANDROID_APIS 0 CMAKE_SYSTEM_VERSION )
unset ( _ANDROID_APIS )
endif ( )
if ( NOT CMAKE_SYSTEM_VERSION MATCHES "^[0-9]+$" )
message ( FATAL_ERROR "Android: The API specified by CMAKE_SYSTEM_VERSION='${CMAKE_SYSTEM_VERSION}' is not an integer." )
endif ( )
2016-06-02 18:29:57 +03:00
# 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_PROC_aarch64_ARCH_ABI "arm64-v8a" )
set ( _ANDROID_PROC_armv7-a_ARCH_ABI "armeabi-v7a" )
set ( _ANDROID_PROC_armv6_ARCH_ABI "armeabi-v6" )
set ( _ANDROID_PROC_armv5te_ARCH_ABI "armeabi" )
set ( _ANDROID_PROC_i686_ARCH_ABI "x86" )
set ( _ANDROID_PROC_mips_ARCH_ABI "mips" )
set ( _ANDROID_PROC_mips64_ARCH_ABI "mips64" )
set ( _ANDROID_PROC_x86_64_ARCH_ABI "x86_64" )
2016-06-02 23:21:36 +03:00
set ( _ANDROID_ARCH_arm64_ABI "arm64-v8a" )
set ( _ANDROID_ARCH_arm_ABI "armeabi" )
set ( _ANDROID_ARCH_mips_ABI "mips" )
set ( _ANDROID_ARCH_mips64_ABI "mips64" )
set ( _ANDROID_ARCH_x86_ABI "x86" )
set ( _ANDROID_ARCH_x86_64_ABI "x86_64" )
2016-06-02 18:29:57 +03:00
# Validate inputs.
if ( CMAKE_ANDROID_ARCH_ABI AND NOT DEFINED "_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC" )
message ( FATAL_ERROR "Android: Unknown ABI CMAKE_ANDROID_ARCH_ABI='${CMAKE_ANDROID_ARCH_ABI}'." )
endif ( )
if ( CMAKE_SYSTEM_PROCESSOR AND NOT DEFINED "_ANDROID_PROC_${CMAKE_SYSTEM_PROCESSOR}_ARCH_ABI" )
message ( FATAL_ERROR "Android: Unknown processor CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}'." )
endif ( )
2016-06-02 23:21:36 +03:00
if ( _ANDROID_SYSROOT_ARCH AND NOT DEFINED "_ANDROID_ARCH_${_ANDROID_SYSROOT_ARCH}_ABI" )
message ( FATAL_ERROR
" A n d r o i d : U n k n o w n a r c h i t e c t u r e ' $ { _ A N D R O I D _ S Y S R O O T _ A R C H } ' s p e c i f i e d i n C M A K E _ S Y S R O O T : \ n "
" $ { C M A K E _ S Y S R O O T } "
)
endif ( )
2016-06-02 18:29:57 +03:00
# Select an ABI.
if ( NOT CMAKE_ANDROID_ARCH_ABI )
if ( CMAKE_SYSTEM_PROCESSOR )
set ( CMAKE_ANDROID_ARCH_ABI "${_ANDROID_PROC_${CMAKE_SYSTEM_PROCESSOR}_ARCH_ABI}" )
2016-06-02 23:21:36 +03:00
elseif ( _ANDROID_SYSROOT_ARCH )
set ( CMAKE_ANDROID_ARCH_ABI "${_ANDROID_ARCH_${_ANDROID_SYSROOT_ARCH}_ABI}" )
2016-06-02 18:29:57 +03:00
else ( )
# https://developer.android.com/ndk/guides/application_mk.html
# Default is the oldest ARM ABI.
set ( CMAKE_ANDROID_ARCH_ABI "armeabi" )
endif ( )
endif ( )
set ( CMAKE_ANDROID_ARCH "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_ARCH}" )
2016-06-02 23:21:36 +03:00
if ( _ANDROID_SYSROOT_ARCH AND NOT "x${_ANDROID_SYSROOT_ARCH}" STREQUAL "x${CMAKE_ANDROID_ARCH}" )
message ( FATAL_ERROR
" A n d r o i d : A r c h i t e c t u r e ' $ { _ A N D R O I D _ S Y S R O O T _ A R C H } ' s p e c i f i e d i n C M A K E _ S Y S R O O T : \ n "
" $ { C M A K E _ S Y S R O O T } \ n "
" d o e s n o t m a t c h a r c h i t e c t u r e ' $ { C M A K E _ A N D R O I D _ A R C H } ' f o r t h e A B I ' $ { C M A K E _ A N D R O I D _ A R C H _ A B I } ' . "
)
endif ( )
2016-06-02 18:29:57 +03:00
# Select a processor.
if ( NOT CMAKE_SYSTEM_PROCESSOR )
set ( CMAKE_SYSTEM_PROCESSOR "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC}" )
endif ( )
# If the user specified both an ABI and a processor then they might not match.
if ( NOT _ANDROID_ABI_ ${ CMAKE_ANDROID_ARCH_ABI } _PROC STREQUAL CMAKE_SYSTEM_PROCESSOR )
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 ( )
2016-06-02 18:16:21 +03:00
# Save the Android-specific information in CMakeSystem.cmake.
set ( CMAKE_SYSTEM_CUSTOM_CODE "
set ( CMAKE_ANDROID_NDK \"${CMAKE_ANDROID_NDK}\")
2016-06-03 22:06:58 +03:00
set ( CMAKE_ANDROID_STANDALONE_TOOLCHAIN \"${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}\")
2016-06-02 18:29:57 +03:00
set ( CMAKE_ANDROID_ARCH \"${CMAKE_ANDROID_ARCH}\")
set ( CMAKE_ANDROID_ARCH_ABI \"${CMAKE_ANDROID_ARCH_ABI}\")
2016-06-02 18:16:21 +03:00
" )
2016-06-02 18:26:32 +03:00
2016-06-02 18:29:57 +03:00
# Select an ARM variant.
if ( CMAKE_ANDROID_ARCH_ABI MATCHES "^armeabi" )
if ( CMAKE_ANDROID_ARM_MODE )
set ( CMAKE_ANDROID_ARM_MODE 1 )
else ( )
set ( CMAKE_ANDROID_ARM_MODE 0 )
endif ( )
string ( APPEND CMAKE_SYSTEM_CUSTOM_CODE
" set ( CMAKE_ANDROID_ARM_MODE \"${CMAKE_ANDROID_ARM_MODE}\")\n"
)
elseif ( DEFINED CMAKE_ANDROID_ARM_MODE )
message ( FATAL_ERROR "Android: CMAKE_ANDROID_ARM_MODE is set but is valid only for 'armeabi' architectures." )
endif ( )
if ( CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a" )
if ( CMAKE_ANDROID_ARM_NEON )
set ( CMAKE_ANDROID_ARM_NEON 1 )
else ( )
set ( CMAKE_ANDROID_ARM_NEON 0 )
endif ( )
string ( APPEND CMAKE_SYSTEM_CUSTOM_CODE
" set ( CMAKE_ANDROID_ARM_NEON \"${CMAKE_ANDROID_ARM_NEON}\")\n"
)
elseif ( DEFINED CMAKE_ANDROID_ARM_NEON )
message ( FATAL_ERROR "Android: CMAKE_ANDROID_ARM_NEON is set but is valid only for 'armeabi-v7a' architecture." )
endif ( )
2016-06-02 18:26:32 +03:00
# Report the chosen architecture.
2016-06-02 18:29:57 +03:00
message ( STATUS "Android: Targeting API '${CMAKE_SYSTEM_VERSION}' with architecture '${CMAKE_ANDROID_ARCH}', ABI '${CMAKE_ANDROID_ARCH_ABI}', and processor '${CMAKE_SYSTEM_PROCESSOR}'" )