Home | History | Annotate | Download | only in android-cmake
      1 # Copyright (c) 2010-2011, Ethan Rublee
      2 # Copyright (c) 2011-2014, Andrey Kamaev
      3 # All rights reserved.
      4 #
      5 # Redistribution and use in source and binary forms, with or without
      6 # modification, are permitted provided that the following conditions are met:
      7 #
      8 # 1.  Redistributions of source code must retain the above copyright notice,
      9 #     this list of conditions and the following disclaimer.
     10 #
     11 # 2.  Redistributions in binary form must reproduce the above copyright notice,
     12 #     this list of conditions and the following disclaimer in the documentation
     13 #     and/or other materials provided with the distribution.
     14 #
     15 # 3.  Neither the name of the copyright holder nor the names of its
     16 #     contributors may be used to endorse or promote products derived from this
     17 #     software without specific prior written permission.
     18 #
     19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     20 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     23 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29 # POSSIBILITY OF SUCH DAMAGE.
     30 
     31 # ------------------------------------------------------------------------------
     32 #  Android CMake toolchain file, for use with the Android NDK r5-r10d
     33 #  Requires cmake 2.6.3 or newer (2.8.9 or newer is recommended).
     34 #  See home page: https://github.com/taka-no-me/android-cmake
     35 #
     36 #  Usage Linux:
     37 #   $ export ANDROID_NDK=/absolute/path/to/the/android-ndk
     38 #   $ mkdir build && cd build
     39 #   $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake ..
     40 #   $ make -j8
     41 #
     42 #  Usage Windows:
     43 #     You need native port of make to build your project.
     44 #     Android NDK r7 (and newer) already has make.exe on board.
     45 #     For older NDK you have to install it separately.
     46 #     For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm
     47 #
     48 #   $ SET ANDROID_NDK=C:\absolute\path\to\the\android-ndk
     49 #   $ mkdir build && cd build
     50 #   $ cmake.exe -G"MinGW Makefiles"
     51 #       -DCMAKE_TOOLCHAIN_FILE=path\to\the\android.toolchain.cmake
     52 #       -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows\bin\make.exe" ..
     53 #   $ cmake.exe --build .
     54 #
     55 #
     56 #  Options (can be set as cmake parameters: -D<option_name>=<value>):
     57 #    ANDROID_NDK=/opt/android-ndk - path to the NDK root.
     58 #      Can be set as environment variable. Can be set only at first cmake run.
     59 #
     60 #    ANDROID_ABI=armeabi-v7a - specifies the target Application Binary
     61 #      Interface (ABI). This option nearly matches to the APP_ABI variable
     62 #      used by ndk-build tool from Android NDK.
     63 #
     64 #      Possible targets are:
     65 #        "armeabi" - ARMv5TE based CPU with software floating point operations
     66 #        "armeabi-v7a" - ARMv7 based devices with hardware FPU instructions
     67 #            this ABI target is used by default
     68 #        "armeabi-v7a with NEON" - same as armeabi-v7a, but
     69 #            sets NEON as floating-point unit
     70 #        "armeabi-v7a with VFPV3" - same as armeabi-v7a, but
     71 #            sets VFPV3 as floating-point unit (has 32 registers instead of 16)
     72 #        "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP
     73 #        "x86" - IA-32 instruction set
     74 #        "mips" - MIPS32 instruction set
     75 #
     76 #      64-bit ABIs for NDK r10 and newer:
     77 #        "arm64-v8a" - ARMv8 AArch64 instruction set
     78 #        "x86_64" - Intel64 instruction set (r1)
     79 #        "mips64" - MIPS64 instruction set (r6)
     80 #
     81 #    ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for.
     82 #      Option is read-only when standalone toolchain is used.
     83 #      Note: building for "android-L" requires explicit configuration.
     84 #
     85 #    ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 - the name of compiler
     86 #      toolchain to be used. The list of possible values depends on the NDK
     87 #      version. For NDK r10c the possible values are:
     88 #
     89 #        * aarch64-linux-android-4.9
     90 #        * aarch64-linux-android-clang3.4
     91 #        * aarch64-linux-android-clang3.5
     92 #        * arm-linux-androideabi-4.6
     93 #        * arm-linux-androideabi-4.8
     94 #        * arm-linux-androideabi-4.9 (default)
     95 #        * arm-linux-androideabi-clang3.4
     96 #        * arm-linux-androideabi-clang3.5
     97 #        * mips64el-linux-android-4.9
     98 #        * mips64el-linux-android-clang3.4
     99 #        * mips64el-linux-android-clang3.5
    100 #        * mipsel-linux-android-4.6
    101 #        * mipsel-linux-android-4.8
    102 #        * mipsel-linux-android-4.9
    103 #        * mipsel-linux-android-clang3.4
    104 #        * mipsel-linux-android-clang3.5
    105 #        * x86-4.6
    106 #        * x86-4.8
    107 #        * x86-4.9
    108 #        * x86-clang3.4
    109 #        * x86-clang3.5
    110 #        * x86_64-4.9
    111 #        * x86_64-clang3.4
    112 #        * x86_64-clang3.5
    113 #
    114 #    ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions
    115 #      instead of Thumb. Is not available for "armeabi-v6 with VFP"
    116 #      (is forced to be ON) ABI.
    117 #
    118 #    ANDROID_NO_UNDEFINED=ON - set ON to show all undefined symbols as linker
    119 #      errors even if they are not used.
    120 #
    121 #    ANDROID_SO_UNDEFINED=OFF - set ON to allow undefined symbols in shared
    122 #      libraries. Automatically turned for NDK r5x and r6x due to GLESv2
    123 #      problems.
    124 #
    125 #    ANDROID_STL=gnustl_static - specify the runtime to use.
    126 #
    127 #      Possible values are:
    128 #        none           -> Do not configure the runtime.
    129 #        system         -> Use the default minimal system C++ runtime library.
    130 #                          Implies -fno-rtti -fno-exceptions.
    131 #                          Is not available for standalone toolchain.
    132 #        system_re      -> Use the default minimal system C++ runtime library.
    133 #                          Implies -frtti -fexceptions.
    134 #                          Is not available for standalone toolchain.
    135 #        gabi++_static  -> Use the GAbi++ runtime as a static library.
    136 #                          Implies -frtti -fno-exceptions.
    137 #                          Available for NDK r7 and newer.
    138 #                          Is not available for standalone toolchain.
    139 #        gabi++_shared  -> Use the GAbi++ runtime as a shared library.
    140 #                          Implies -frtti -fno-exceptions.
    141 #                          Available for NDK r7 and newer.
    142 #                          Is not available for standalone toolchain.
    143 #        stlport_static -> Use the STLport runtime as a static library.
    144 #                          Implies -fno-rtti -fno-exceptions for NDK before r7.
    145 #                          Implies -frtti -fno-exceptions for NDK r7 and newer.
    146 #                          Is not available for standalone toolchain.
    147 #        stlport_shared -> Use the STLport runtime as a shared library.
    148 #                          Implies -fno-rtti -fno-exceptions for NDK before r7.
    149 #                          Implies -frtti -fno-exceptions for NDK r7 and newer.
    150 #                          Is not available for standalone toolchain.
    151 #        gnustl_static  -> Use the GNU STL as a static library.
    152 #                          Implies -frtti -fexceptions.
    153 #        gnustl_shared  -> Use the GNU STL as a shared library.
    154 #                          Implies -frtti -fno-exceptions.
    155 #                          Available for NDK r7b and newer.
    156 #                          Silently degrades to gnustl_static if not available.
    157 #
    158 #    ANDROID_STL_FORCE_FEATURES=ON - turn rtti and exceptions support based on
    159 #      chosen runtime. If disabled, then the user is responsible for settings
    160 #      these options.
    161 #
    162 #  What?:
    163 #    android-cmake toolchain searches for NDK/toolchain in the following order:
    164 #      ANDROID_NDK - cmake parameter
    165 #      ANDROID_NDK - environment variable
    166 #      ANDROID_STANDALONE_TOOLCHAIN - cmake parameter
    167 #      ANDROID_STANDALONE_TOOLCHAIN - environment variable
    168 #      ANDROID_NDK - default locations
    169 #      ANDROID_STANDALONE_TOOLCHAIN - default locations
    170 #
    171 #    Make sure to do the following in your scripts:
    172 #      SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}" )
    173 #      SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}" )
    174 #    The flags will be prepopulated with critical flags, so don't loose them.
    175 #    Also be aware that toolchain also sets configuration-specific compiler
    176 #    flags and linker flags.
    177 #
    178 #    ANDROID and BUILD_ANDROID will be set to true, you may test any of these
    179 #    variables to make necessary Android-specific configuration changes.
    180 #
    181 #    Also ARMEABI or ARMEABI_V7A or X86 or MIPS or ARM64_V8A or X86_64 or MIPS64
    182 #    will be set true, mutually exclusive. NEON option will be set true
    183 #    if VFP is set to NEON.
    184 #
    185 # ------------------------------------------------------------------------------
    186 
    187 cmake_minimum_required( VERSION 2.6.3 )
    188 
    189 if( DEFINED CMAKE_CROSSCOMPILING )
    190  # subsequent toolchain loading is not really needed
    191  return()
    192 endif()
    193 
    194 if( CMAKE_TOOLCHAIN_FILE )
    195  # touch toolchain variable to suppress "unused variable" warning
    196 endif()
    197 
    198 # inherit settings in recursive loads
    199 get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
    200 if( _CMAKE_IN_TRY_COMPILE )
    201  include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL )
    202 endif()
    203 
    204 # this one is important
    205 if( CMAKE_VERSION VERSION_GREATER "3.0.99" )
    206  set( CMAKE_SYSTEM_NAME Android )
    207 else()
    208  set( CMAKE_SYSTEM_NAME Linux )
    209 endif()
    210 
    211 # this one not so much
    212 set( CMAKE_SYSTEM_VERSION 1 )
    213 
    214 # rpath makes low sense for Android
    215 set( CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "" )
    216 set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
    217 
    218 # NDK search paths
    219 set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r10d -r10c -r10b -r10 -r9d -r9c -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
    220 if( NOT DEFINED ANDROID_NDK_SEARCH_PATHS )
    221  if( CMAKE_HOST_WIN32 )
    222   file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
    223   set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}" "$ENV{SystemDrive}/NVPACK" )
    224  else()
    225   file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS )
    226   set( ANDROID_NDK_SEARCH_PATHS /opt "${ANDROID_NDK_SEARCH_PATHS}/NVPACK" )
    227  endif()
    228 endif()
    229 if( NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH )
    230  set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain )
    231 endif()
    232 
    233 # known ABIs
    234 set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" )
    235 set( ANDROID_SUPPORTED_ABIS_arm64 "arm64-v8a" )
    236 set( ANDROID_SUPPORTED_ABIS_x86 "x86" )
    237 set( ANDROID_SUPPORTED_ABIS_x86_64 "x86_64" )
    238 set( ANDROID_SUPPORTED_ABIS_mips "mips" )
    239 set( ANDROID_SUPPORTED_ABIS_mips64 "mips64" )
    240 
    241 # API level defaults
    242 set( ANDROID_DEFAULT_NDK_API_LEVEL 8 )
    243 set( ANDROID_DEFAULT_NDK_API_LEVEL_arm64 21 )
    244 set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 )
    245 set( ANDROID_DEFAULT_NDK_API_LEVEL_x86_64 21 )
    246 set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 )
    247 set( ANDROID_DEFAULT_NDK_API_LEVEL_mips64 21 )
    248 
    249 
    250 macro( __LIST_FILTER listvar regex )
    251   if( ${listvar} )
    252     foreach( __val ${${listvar}} )
    253       if( __val MATCHES "${regex}" )
    254         list( REMOVE_ITEM ${listvar} "${__val}" )
    255       endif()
    256     endforeach()
    257   endif()
    258 endmacro()
    259 
    260 macro( __INIT_VARIABLE var_name )
    261   set( __test_path 0 )
    262   foreach( __var ${ARGN} )
    263     if( __var STREQUAL "PATH" )
    264       set( __test_path 1 )
    265       break()
    266     endif()
    267   endforeach()
    268 
    269   if( __test_path AND NOT EXISTS "${${var_name}}" )
    270     unset( ${var_name} CACHE )
    271   endif()
    272 
    273   if( " ${${var_name}}" STREQUAL " " )
    274     set( __values 0 )
    275     foreach( __var ${ARGN} )
    276       if( __var STREQUAL "VALUES" )
    277         set( __values 1 )
    278       elseif( NOT __var STREQUAL "PATH" )
    279         if( __var MATCHES "^ENV_.*$" )
    280           string( REPLACE "ENV_" "" __var "${__var}" )
    281           set( __value "$ENV{${__var}}" )
    282         elseif( DEFINED ${__var} )
    283           set( __value "${${__var}}" )
    284         elseif( __values )
    285           set( __value "${__var}" )
    286         else()
    287           set( __value "" )
    288         endif()
    289 
    290         if( NOT " ${__value}" STREQUAL " " AND (NOT __test_path OR EXISTS "${__value}") )
    291           set( ${var_name} "${__value}" )
    292           break()
    293         endif()
    294       endif()
    295     endforeach()
    296     unset( __value )
    297     unset( __values )
    298   endif()
    299 
    300   if( __test_path )
    301     file( TO_CMAKE_PATH "${${var_name}}" ${var_name} )
    302   endif()
    303   unset( __test_path )
    304 endmacro()
    305 
    306 macro( __DETECT_NATIVE_API_LEVEL _var _path )
    307   set( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*.*$" )
    308   file( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" )
    309   if( NOT __apiFileContent )
    310     message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." )
    311   endif()
    312   string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" )
    313   unset( __apiFileContent )
    314   unset( __ndkApiLevelRegex )
    315 endmacro()
    316 
    317 macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root )
    318  if( EXISTS "${_root}" )
    319     file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" )
    320     __LIST_FILTER( __gccExePath "^[.].*" )
    321     list( LENGTH __gccExePath __gccExePathsCount )
    322     if( NOT __gccExePathsCount EQUAL 1  AND NOT _CMAKE_IN_TRY_COMPILE )
    323       message( WARNING "Could not determine machine name for compiler from ${_root}" )
    324       set( ${_var} "" )
    325     else()
    326       get_filename_component( __gccExeName "${__gccExePath}" NAME_WE )
    327       string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" )
    328     endif()
    329     unset( __gccExePath )
    330     unset( __gccExePathsCount )
    331     unset( __gccExeName )
    332   else()
    333     set( ${_var} "" )
    334   endif()
    335 endmacro()
    336 
    337 
    338 # fight against cygwin
    339 set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools")
    340 mark_as_advanced( ANDROID_FORBID_SYGWIN )
    341 if( ANDROID_FORBID_SYGWIN )
    342  if( CYGWIN )
    343   message( FATAL_ERROR "Android NDK and android-cmake toolchain are not welcome Cygwin. It is unlikely that this cmake toolchain will work under cygwin. But if you want to try then you can set cmake variable ANDROID_FORBID_SYGWIN to FALSE and rerun cmake." )
    344  endif()
    345 
    346  if( CMAKE_HOST_WIN32 )
    347   # remove cygwin from PATH
    348   set( __new_path "$ENV{PATH}")
    349   __LIST_FILTER( __new_path "cygwin" )
    350   set(ENV{PATH} "${__new_path}")
    351   unset(__new_path)
    352  endif()
    353 endif()
    354 
    355 
    356 # detect current host platform
    357 if( NOT DEFINED ANDROID_NDK_HOST_X64 AND (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64" OR CMAKE_HOST_APPLE) )
    358  set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" )
    359  mark_as_advanced( ANDROID_NDK_HOST_X64 )
    360 endif()
    361 
    362 set( TOOL_OS_SUFFIX "" )
    363 if( CMAKE_HOST_APPLE )
    364  set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86_64" )
    365  set( ANDROID_NDK_HOST_SYSTEM_NAME2 "darwin-x86" )
    366 elseif( CMAKE_HOST_WIN32 )
    367  set( ANDROID_NDK_HOST_SYSTEM_NAME "windows-x86_64" )
    368  set( ANDROID_NDK_HOST_SYSTEM_NAME2 "windows" )
    369  set( TOOL_OS_SUFFIX ".exe" )
    370 elseif( CMAKE_HOST_UNIX )
    371  set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86_64" )
    372  set( ANDROID_NDK_HOST_SYSTEM_NAME2 "linux-x86" )
    373 else()
    374  message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
    375 endif()
    376 
    377 if( NOT ANDROID_NDK_HOST_X64 )
    378  set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} )
    379 endif()
    380 
    381 # see if we have path to Android NDK
    382 if( NOT ANDROID_NDK AND NOT ANDROID_STANDALONE_TOOLCHAIN )
    383   __INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
    384 endif()
    385 if( NOT ANDROID_NDK )
    386  # see if we have path to Android standalone toolchain
    387  __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN )
    388 
    389  if( NOT ANDROID_STANDALONE_TOOLCHAIN )
    390   #try to find Android NDK in one of the the default locations
    391   set( __ndkSearchPaths )
    392   foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} )
    393    foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} )
    394     list( APPEND __ndkSearchPaths "${__ndkSearchPath}/android-ndk${suffix}" )
    395    endforeach()
    396   endforeach()
    397   __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} )
    398   unset( __ndkSearchPaths )
    399 
    400   if( ANDROID_NDK )
    401    message( STATUS "Using default path for Android NDK: ${ANDROID_NDK}" )
    402    message( STATUS "  If you prefer to use a different location, please define a cmake or environment variable: ANDROID_NDK" )
    403   else()
    404    #try to find Android standalone toolchain in one of the the default locations
    405    __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH )
    406 
    407    if( ANDROID_STANDALONE_TOOLCHAIN )
    408     message( STATUS "Using default path for standalone toolchain ${ANDROID_STANDALONE_TOOLCHAIN}" )
    409     message( STATUS "  If you prefer to use a different location, please define the variable: ANDROID_STANDALONE_TOOLCHAIN" )
    410    endif( ANDROID_STANDALONE_TOOLCHAIN )
    411   endif( ANDROID_NDK )
    412  endif( NOT ANDROID_STANDALONE_TOOLCHAIN )
    413 endif( NOT ANDROID_NDK )
    414 
    415 # remember found paths
    416 if( ANDROID_NDK )
    417  get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE )
    418  set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE )
    419  set( BUILD_WITH_ANDROID_NDK True )
    420  if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" )
    421   file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX "r[0-9]+[a-z]?" )
    422   string( REGEX MATCH "r([0-9]+)([a-z]?)" ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" )
    423  else()
    424   set( ANDROID_NDK_RELEASE "r1x" )
    425   set( ANDROID_NDK_RELEASE_FULL "unreleased" )
    426  endif()
    427  string( REGEX REPLACE "r([0-9]+)([a-z]?)" "\\1*1000" ANDROID_NDK_RELEASE_NUM "${ANDROID_NDK_RELEASE}" )
    428  string( FIND " abcdefghijklmnopqastuvwxyz" "${CMAKE_MATCH_2}" __ndkReleaseLetterNum )
    429  math( EXPR ANDROID_NDK_RELEASE_NUM "${ANDROID_NDK_RELEASE_NUM}+${__ndkReleaseLetterNum}" )
    430 elseif( ANDROID_STANDALONE_TOOLCHAIN )
    431  get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE )
    432  # try to detect change
    433  if( CMAKE_AR )
    434   string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length )
    435   string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath )
    436   if( NOT __androidStandaloneToolchainPreviousPath STREQUAL ANDROID_STANDALONE_TOOLCHAIN )
    437    message( FATAL_ERROR "It is not possible to change path to the Android standalone toolchain on subsequent run." )
    438   endif()
    439   unset( __androidStandaloneToolchainPreviousPath )
    440   unset( __length )
    441  endif()
    442  set( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" CACHE INTERNAL "Path of the Android standalone toolchain" FORCE )
    443  set( BUILD_WITH_STANDALONE_TOOLCHAIN True )
    444 else()
    445  list(GET ANDROID_NDK_SEARCH_PATHS 0 ANDROID_NDK_SEARCH_PATH)
    446  message( FATAL_ERROR "Could not find neither Android NDK nor Android standalone toolchain.
    447     You should either set an environment variable:
    448       export ANDROID_NDK=~/my-android-ndk
    449     or
    450       export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain
    451     or put the toolchain or NDK in the default path:
    452       sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH}/android-ndk
    453       sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
    454 endif()
    455 
    456 # android NDK layout
    457 if( BUILD_WITH_ANDROID_NDK )
    458  if( NOT DEFINED ANDROID_NDK_LAYOUT )
    459   # try to automatically detect the layout
    460   if( EXISTS "${ANDROID_NDK}/RELEASE.TXT")
    461    set( ANDROID_NDK_LAYOUT "RELEASE" )
    462   elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" )
    463    set( ANDROID_NDK_LAYOUT "LINARO" )
    464   elseif( EXISTS "${ANDROID_NDK}/../../gcc/" )
    465    set( ANDROID_NDK_LAYOUT "ANDROID" )
    466   endif()
    467  endif()
    468  set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" )
    469  mark_as_advanced( ANDROID_NDK_LAYOUT )
    470  if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" )
    471   set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
    472   set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" )
    473   set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "" )
    474   set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
    475  elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" )
    476   set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
    477   set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" )
    478   set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "" )
    479   set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
    480  else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE"
    481   set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" )
    482   set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
    483   set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" )
    484  endif()
    485  get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE )
    486 
    487  # try to detect change of NDK
    488  if( CMAKE_AR )
    489   string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length )
    490   string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
    491   if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH )
    492    message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
    493    " )
    494   endif()
    495   unset( __androidNdkPreviousPath )
    496   unset( __length )
    497  endif()
    498 endif()
    499 
    500 
    501 # get all the details about standalone toolchain
    502 if( BUILD_WITH_STANDALONE_TOOLCHAIN )
    503  __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
    504  set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
    505  set( __availableToolchains "standalone" )
    506  __DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" )
    507  if( NOT __availableToolchainMachines )
    508   message( FATAL_ERROR "Could not determine machine name of your toolchain. Probably your Android standalone toolchain is broken." )
    509  endif()
    510  if( __availableToolchainMachines MATCHES x86_64 )
    511   set( __availableToolchainArchs "x86_64" )
    512  elseif( __availableToolchainMachines MATCHES i686 )
    513   set( __availableToolchainArchs "x86" )
    514  elseif( __availableToolchainMachines MATCHES aarch64 )
    515   set( __availableToolchainArchs "arm64" )
    516  elseif( __availableToolchainMachines MATCHES arm )
    517   set( __availableToolchainArchs "arm" )
    518  elseif( __availableToolchainMachines MATCHES mips64el )
    519   set( __availableToolchainArchs "mips64" )
    520  elseif( __availableToolchainMachines MATCHES mipsel )
    521   set( __availableToolchainArchs "mips" )
    522  endif()
    523  execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" -dumpversion
    524                   OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE )
    525  string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" )
    526  if( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${TOOL_OS_SUFFIX}" )
    527   list( APPEND __availableToolchains "standalone-clang" )
    528   list( APPEND __availableToolchainMachines ${__availableToolchainMachines} )
    529   list( APPEND __availableToolchainArchs ${__availableToolchainArchs} )
    530   list( APPEND __availableToolchainCompilerVersions ${__availableToolchainCompilerVersions} )
    531  endif()
    532 endif()
    533 
    534 macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath )
    535  foreach( __toolchain ${${__availableToolchainsLst}} )
    536   if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" )
    537    SET( __toolchainVersionRegex "^TOOLCHAIN_VERSION[\t ]+:=[\t ]+(.*)$" )
    538    FILE( STRINGS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}/setup.mk" __toolchainVersionStr REGEX "${__toolchainVersionRegex}" )
    539    if( __toolchainVersionStr )
    540     string( REGEX REPLACE "${__toolchainVersionRegex}" "\\1" __toolchainVersionStr "${__toolchainVersionStr}" )
    541     string( REGEX REPLACE "-clang3[.][0-9]$" "-${__toolchainVersionStr}" __gcc_toolchain "${__toolchain}" )
    542    else()
    543     string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" )
    544    endif()
    545    unset( __toolchainVersionStr )
    546    unset( __toolchainVersionRegex )
    547   else()
    548    set( __gcc_toolchain "${__toolchain}" )
    549   endif()
    550   __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" )
    551   if( __machine )
    552    string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" )
    553    if( __machine MATCHES x86_64 )
    554     set( __arch "x86_64" )
    555    elseif( __machine MATCHES i686 )
    556     set( __arch "x86" )
    557    elseif( __machine MATCHES aarch64 )
    558     set( __arch "arm64" )
    559    elseif( __machine MATCHES arm )
    560     set( __arch "arm" )
    561    elseif( __machine MATCHES mips64el )
    562     set( __arch "mips64" )
    563    elseif( __machine MATCHES mipsel )
    564     set( __arch "mips" )
    565    else()
    566     set( __arch "" )
    567    endif()
    568    #message("machine: !${__machine}!\narch: !${__arch}!\nversion: !${__version}!\ntoolchain: !${__toolchain}!\n")
    569    if (__arch)
    570     list( APPEND __availableToolchainMachines "${__machine}" )
    571     list( APPEND __availableToolchainArchs "${__arch}" )
    572     list( APPEND __availableToolchainCompilerVersions "${__version}" )
    573     list( APPEND ${__availableToolchainsVar} "${__toolchain}" )
    574    endif()
    575   endif()
    576   unset( __gcc_toolchain )
    577  endforeach()
    578 endmacro()
    579 
    580 # get all the details about NDK
    581 if( BUILD_WITH_ANDROID_NDK )
    582  file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" )
    583  string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" )
    584  set( __availableToolchains "" )
    585  set( __availableToolchainMachines "" )
    586  set( __availableToolchainArchs "" )
    587  set( __availableToolchainCompilerVersions "" )
    588  if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" )
    589   # do not go through all toolchains if we know the name
    590   set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" )
    591   __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
    592   if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
    593    __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
    594    if( __availableToolchains )
    595     set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
    596    endif()
    597   endif()
    598  endif()
    599  if( NOT __availableToolchains )
    600   file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" )
    601   if( __availableToolchainsLst )
    602    list(SORT __availableToolchainsLst) # we need clang to go after gcc
    603   endif()
    604   __LIST_FILTER( __availableToolchainsLst "^[.]" )
    605   __LIST_FILTER( __availableToolchainsLst "llvm" )
    606   __LIST_FILTER( __availableToolchainsLst "renderscript" )
    607   __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
    608   if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
    609    __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
    610    if( __availableToolchains )
    611     set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
    612    endif()
    613   endif()
    614  endif()
    615  if( NOT __availableToolchains )
    616   message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." )
    617  endif()
    618 endif()
    619 
    620 # build list of available ABIs
    621 set( ANDROID_SUPPORTED_ABIS "" )
    622 set( __uniqToolchainArchNames ${__availableToolchainArchs} )
    623 list( REMOVE_DUPLICATES __uniqToolchainArchNames )
    624 list( SORT __uniqToolchainArchNames )
    625 foreach( __arch ${__uniqToolchainArchNames} )
    626  list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
    627 endforeach()
    628 unset( __uniqToolchainArchNames )
    629 if( NOT ANDROID_SUPPORTED_ABIS )
    630  message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
    631 endif()
    632 
    633 # choose target ABI
    634 __INIT_VARIABLE( ANDROID_ABI VALUES ${ANDROID_SUPPORTED_ABIS} )
    635 # verify that target ABI is supported
    636 list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx )
    637 if( __androidAbiIdx EQUAL -1 )
    638  string( REPLACE ";" "\", \"" PRINTABLE_ANDROID_SUPPORTED_ABIS  "${ANDROID_SUPPORTED_ABIS}" )
    639  message( FATAL_ERROR "Specified ANDROID_ABI = \"${ANDROID_ABI}\" is not supported by this cmake toolchain or your NDK/toolchain.
    640    Supported values are: \"${PRINTABLE_ANDROID_SUPPORTED_ABIS}\"
    641    " )
    642 endif()
    643 unset( __androidAbiIdx )
    644 
    645 # set target ABI options
    646 if( ANDROID_ABI STREQUAL "x86" )
    647  set( X86 true )
    648  set( ANDROID_NDK_ABI_NAME "x86" )
    649  set( ANDROID_ARCH_NAME "x86" )
    650  set( ANDROID_LLVM_TRIPLE "i686-none-linux-android" )
    651  set( CMAKE_SYSTEM_PROCESSOR "i686" )
    652 elseif( ANDROID_ABI STREQUAL "x86_64" )
    653  set( X86 true )
    654  set( X86_64 true )
    655  set( ANDROID_NDK_ABI_NAME "x86_64" )
    656  set( ANDROID_ARCH_NAME "x86_64" )
    657  set( CMAKE_SYSTEM_PROCESSOR "x86_64" )
    658  set( ANDROID_LLVM_TRIPLE "x86_64-none-linux-android" )
    659 elseif( ANDROID_ABI STREQUAL "mips64" )
    660  set( MIPS64 true )
    661  set( ANDROID_NDK_ABI_NAME "mips64" )
    662  set( ANDROID_ARCH_NAME "mips64" )
    663  set( ANDROID_LLVM_TRIPLE "mips64el-none-linux-android" )
    664  set( CMAKE_SYSTEM_PROCESSOR "mips64" )
    665 elseif( ANDROID_ABI STREQUAL "mips" )
    666  set( MIPS true )
    667  set( ANDROID_NDK_ABI_NAME "mips" )
    668  set( ANDROID_ARCH_NAME "mips" )
    669  set( ANDROID_LLVM_TRIPLE "mipsel-none-linux-android" )
    670  set( CMAKE_SYSTEM_PROCESSOR "mips" )
    671 elseif( ANDROID_ABI STREQUAL "arm64-v8a" )
    672  set( ARM64_V8A true )
    673  set( ANDROID_NDK_ABI_NAME "arm64-v8a" )
    674  set( ANDROID_ARCH_NAME "arm64" )
    675  set( ANDROID_LLVM_TRIPLE "aarch64-none-linux-android" )
    676  set( CMAKE_SYSTEM_PROCESSOR "aarch64" )
    677  set( VFPV3 true )
    678  set( NEON true )
    679 elseif( ANDROID_ABI STREQUAL "armeabi" )
    680  set( ARMEABI true )
    681  set( ANDROID_NDK_ABI_NAME "armeabi" )
    682  set( ANDROID_ARCH_NAME "arm" )
    683  set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
    684  set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
    685 elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" )
    686  set( ARMEABI_V6 true )
    687  set( ANDROID_NDK_ABI_NAME "armeabi" )
    688  set( ANDROID_ARCH_NAME "arm" )
    689  set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
    690  set( CMAKE_SYSTEM_PROCESSOR "armv6" )
    691  # need always fallback to older platform
    692  set( ARMEABI true )
    693 elseif( ANDROID_ABI STREQUAL "armeabi-v7a")
    694  set( ARMEABI_V7A true )
    695  set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
    696  set( ANDROID_ARCH_NAME "arm" )
    697  set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
    698  set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
    699 elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" )
    700  set( ARMEABI_V7A true )
    701  set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
    702  set( ANDROID_ARCH_NAME "arm" )
    703  set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
    704  set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
    705  set( VFPV3 true )
    706 elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" )
    707  set( ARMEABI_V7A true )
    708  set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
    709  set( ANDROID_ARCH_NAME "arm" )
    710  set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
    711  set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
    712  set( VFPV3 true )
    713  set( NEON true )
    714 else()
    715  message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." )
    716 endif()
    717 
    718 if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" )
    719  # really dirty hack
    720  # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run...
    721  file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" )
    722 endif()
    723 
    724 if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 )
    725  __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD VALUES OFF )
    726  set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE )
    727  mark_as_advanced( ANDROID_FORCE_ARM_BUILD )
    728 else()
    729  unset( ANDROID_FORCE_ARM_BUILD CACHE )
    730 endif()
    731 
    732 # choose toolchain
    733 if( ANDROID_TOOLCHAIN_NAME )
    734  list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx )
    735  if( __toolchainIdx EQUAL -1 )
    736   list( SORT __availableToolchains )
    737   string( REPLACE ";" "\n  * " toolchains_list "${__availableToolchains}" )
    738   set( toolchains_list "  * ${toolchains_list}")
    739   message( FATAL_ERROR "Specified toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing in your NDK or broken. Please verify that your NDK is working or select another compiler toolchain.
    740 To configure the toolchain set CMake variable ANDROID_TOOLCHAIN_NAME to one of the following values:\n${toolchains_list}\n" )
    741  endif()
    742  list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch )
    743  if( NOT __toolchainArch STREQUAL ANDROID_ARCH_NAME )
    744   message( SEND_ERROR "Selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." )
    745  endif()
    746 else()
    747  set( __toolchainIdx -1 )
    748  set( __applicableToolchains "" )
    749  set( __toolchainMaxVersion "0.0.0" )
    750  list( LENGTH __availableToolchains __availableToolchainsCount )
    751  math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" )
    752  foreach( __idx RANGE ${__availableToolchainsCount} )
    753   list( GET __availableToolchainArchs ${__idx} __toolchainArch )
    754   if( __toolchainArch STREQUAL ANDROID_ARCH_NAME )
    755    list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion )
    756    string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}")
    757    if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion )
    758     set( __toolchainMaxVersion "${__toolchainVersion}" )
    759     set( __toolchainIdx ${__idx} )
    760    endif()
    761   endif()
    762  endforeach()
    763  unset( __availableToolchainsCount )
    764  unset( __toolchainMaxVersion )
    765  unset( __toolchainVersion )
    766 endif()
    767 unset( __toolchainArch )
    768 if( __toolchainIdx EQUAL -1 )
    769  message( FATAL_ERROR "No one of available compiler toolchains is able to compile for ${ANDROID_ARCH_NAME} platform." )
    770 endif()
    771 list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME )
    772 list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME )
    773 list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION )
    774 
    775 unset( __toolchainIdx )
    776 unset( __availableToolchains )
    777 unset( __availableToolchainMachines )
    778 unset( __availableToolchainArchs )
    779 unset( __availableToolchainCompilerVersions )
    780 
    781 # choose native API level
    782 __INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
    783 string( REPLACE "android-" "" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
    784 string( STRIP "${ANDROID_NATIVE_API_LEVEL}" ANDROID_NATIVE_API_LEVEL )
    785 # adjust API level
    786 set( __real_api_level ${ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME}} )
    787 foreach( __level ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
    788  if( (__level LESS ANDROID_NATIVE_API_LEVEL OR __level STREQUAL ANDROID_NATIVE_API_LEVEL) AND NOT __level LESS __real_api_level )
    789   set( __real_api_level ${__level} )
    790  endif()
    791 endforeach()
    792 if( __real_api_level AND NOT ANDROID_NATIVE_API_LEVEL STREQUAL __real_api_level )
    793  message( STATUS "Adjusting Android API level 'android-${ANDROID_NATIVE_API_LEVEL}' to 'android-${__real_api_level}'")
    794  set( ANDROID_NATIVE_API_LEVEL ${__real_api_level} )
    795 endif()
    796 unset(__real_api_level)
    797 # validate
    798 list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
    799 if( __levelIdx EQUAL -1 )
    800  message( SEND_ERROR "Specified Android native API level 'android-${ANDROID_NATIVE_API_LEVEL}' is not supported by your NDK/toolchain." )
    801 else()
    802  if( BUILD_WITH_ANDROID_NDK )
    803   __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
    804   if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL AND NOT __realApiLevel GREATER 9000 )
    805    message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." )
    806   endif()
    807   unset( __realApiLevel )
    808  endif()
    809  set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE )
    810  set( CMAKE_ANDROID_API ${ANDROID_NATIVE_API_LEVEL} )
    811  if( CMAKE_VERSION VERSION_GREATER "2.8" )
    812   list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS )
    813   set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
    814  endif()
    815 endif()
    816 unset( __levelIdx )
    817 
    818 
    819 # remember target ABI
    820 set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE )
    821 if( CMAKE_VERSION VERSION_GREATER "2.8" )
    822  list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME} )
    823  set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME}} )
    824 endif()
    825 
    826 
    827 # runtime choice (STL, rtti, exceptions)
    828 if( NOT ANDROID_STL )
    829   set( ANDROID_STL gnustl_static )
    830 endif()
    831 set( ANDROID_STL "${ANDROID_STL}" CACHE STRING "C++ runtime" )
    832 set( ANDROID_STL_FORCE_FEATURES ON CACHE BOOL "automatically configure rtti and exceptions support based on C++ runtime" )
    833 mark_as_advanced( ANDROID_STL ANDROID_STL_FORCE_FEATURES )
    834 
    835 if( BUILD_WITH_ANDROID_NDK )
    836  if( NOT "${ANDROID_STL}" MATCHES "^(none|system|system_re|gabi\\+\\+_static|gabi\\+\\+_shared|stlport_static|stlport_shared|gnustl_static|gnustl_shared)$")
    837   message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
    838 The possible values are:
    839   none           -> Do not configure the runtime.
    840   system         -> Use the default minimal system C++ runtime library.
    841   system_re      -> Same as system but with rtti and exceptions.
    842   gabi++_static  -> Use the GAbi++ runtime as a static library.
    843   gabi++_shared  -> Use the GAbi++ runtime as a shared library.
    844   stlport_static -> Use the STLport runtime as a static library.
    845   stlport_shared -> Use the STLport runtime as a shared library.
    846   gnustl_static  -> (default) Use the GNU STL as a static library.
    847   gnustl_shared  -> Use the GNU STL as a shared library.
    848 " )
    849  endif()
    850 elseif( BUILD_WITH_STANDALONE_TOOLCHAIN )
    851  if( NOT "${ANDROID_STL}" MATCHES "^(none|gnustl_static|gnustl_shared)$")
    852   message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
    853 The possible values are:
    854   none           -> Do not configure the runtime.
    855   gnustl_static  -> (default) Use the GNU STL as a static library.
    856   gnustl_shared  -> Use the GNU STL as a shared library.
    857 " )
    858  endif()
    859 endif()
    860 
    861 unset( ANDROID_RTTI )
    862 unset( ANDROID_EXCEPTIONS )
    863 unset( ANDROID_STL_INCLUDE_DIRS )
    864 unset( __libstl )
    865 unset( __libsupcxx )
    866 
    867 if( NOT _CMAKE_IN_TRY_COMPILE AND ANDROID_NDK_RELEASE STREQUAL "r7b" AND ARMEABI_V7A AND NOT VFPV3 AND ANDROID_STL MATCHES "gnustl" )
    868  message( WARNING  "The GNU STL armeabi-v7a binaries from NDK r7b can crash non-NEON devices. The files provided with NDK r7b were not configured properly, resulting in crashes on Tegra2-based devices and others when trying to use certain floating-point functions (e.g., cosf, sinf, expf).
    869 You are strongly recommended to switch to another NDK release.
    870 " )
    871 endif()
    872 
    873 if( NOT _CMAKE_IN_TRY_COMPILE AND X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" )
    874   message( WARNING  "The x86 system header file from NDK r6 has incorrect definition for ptrdiff_t. You are recommended to upgrade to a newer NDK release or manually patch the header:
    875 See https://android.googlesource.com/platform/development.git f907f4f9d4e56ccc8093df6fee54454b8bcab6c2
    876   diff --git a/ndk/platforms/android-9/arch-x86/include/machine/_types.h b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
    877   index 5e28c64..65892a1 100644
    878   --- a/ndk/platforms/android-9/arch-x86/include/machine/_types.h
    879   +++ b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
    880   @@ -51,7 +51,11 @@ typedef long int       ssize_t;
    881    #endif
    882    #ifndef _PTRDIFF_T
    883    #define _PTRDIFF_T
    884   -typedef long           ptrdiff_t;
    885   +#  ifdef __ANDROID__
    886   +     typedef int            ptrdiff_t;
    887   +#  else
    888   +     typedef long           ptrdiff_t;
    889   +#  endif
    890    #endif
    891 " )
    892 endif()
    893 
    894 
    895 # setup paths and STL for standalone toolchain
    896 if( BUILD_WITH_STANDALONE_TOOLCHAIN )
    897  set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
    898  set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
    899  set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
    900 
    901  if( NOT ANDROID_STL STREQUAL "none" )
    902   set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/include/c++/${ANDROID_COMPILER_VERSION}" )
    903   if( NOT EXISTS "${ANDROID_STL_INCLUDE_DIRS}" )
    904    # old location ( pre r8c )
    905    set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
    906   endif()
    907   if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" )
    908    list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" )
    909   elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" )
    910    list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" )
    911   else()
    912    list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" )
    913   endif()
    914   # always search static GNU STL to get the location of libsupc++.a
    915   if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" )
    916    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb" )
    917   elseif( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" )
    918    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}" )
    919   elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libstdc++.a" )
    920    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb" )
    921   elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libstdc++.a" )
    922    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" )
    923   endif()
    924   if( __libstl )
    925    set( __libsupcxx "${__libstl}/libsupc++.a" )
    926    set( __libstl    "${__libstl}/libstdc++.a" )
    927   endif()
    928   if( NOT EXISTS "${__libsupcxx}" )
    929    message( FATAL_ERROR "The required libstdsupc++.a is missing in your standalone toolchain.
    930  Usually it happens because of bug in make-standalone-toolchain.sh script from NDK r7, r7b and r7c.
    931  You need to either upgrade to newer NDK or manually copy
    932      $ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a
    933  to
    934      ${__libsupcxx}
    935    " )
    936   endif()
    937   if( ANDROID_STL STREQUAL "gnustl_shared" )
    938    if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" )
    939     set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" )
    940    elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" )
    941     set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" )
    942    elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" )
    943     set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" )
    944    endif()
    945   endif()
    946  endif()
    947 endif()
    948 
    949 # clang
    950 if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" )
    951  set( ANDROID_COMPILER_IS_CLANG 1 )
    952  execute_process( COMMAND "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/clang${TOOL_OS_SUFFIX}" --version OUTPUT_VARIABLE ANDROID_CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE )
    953  string( REGEX MATCH "[0-9]+[.][0-9]+" ANDROID_CLANG_VERSION "${ANDROID_CLANG_VERSION}")
    954 elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" )
    955  string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}")
    956  string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-${ANDROID_COMPILER_VERSION}" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
    957  if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" )
    958   message( FATAL_ERROR "Could not find the Clang compiler driver" )
    959  endif()
    960  set( ANDROID_COMPILER_IS_CLANG 1 )
    961  set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
    962 else()
    963  set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
    964  unset( ANDROID_COMPILER_IS_CLANG CACHE )
    965 endif()
    966 
    967 string( REPLACE "." "" _clang_name "clang${ANDROID_CLANG_VERSION}" )
    968 if( NOT EXISTS "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" )
    969  set( _clang_name "clang" )
    970 endif()
    971 
    972 
    973 # setup paths and STL for NDK
    974 if( BUILD_WITH_ANDROID_NDK )
    975  set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
    976  set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
    977 
    978  if( ANDROID_STL STREQUAL "none" )
    979   # do nothing
    980  elseif( ANDROID_STL STREQUAL "system" )
    981   set( ANDROID_RTTI             OFF )
    982   set( ANDROID_EXCEPTIONS       OFF )
    983   set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
    984  elseif( ANDROID_STL STREQUAL "system_re" )
    985   set( ANDROID_RTTI             ON )
    986   set( ANDROID_EXCEPTIONS       ON )
    987   set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
    988  elseif( ANDROID_STL MATCHES "gabi" )
    989   if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
    990    message( FATAL_ERROR "gabi++ is not available in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.")
    991   endif()
    992   set( ANDROID_RTTI             ON )
    993   set( ANDROID_EXCEPTIONS       OFF )
    994   set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/gabi++/include" )
    995   set( __libstl                 "${ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${ANDROID_NDK_ABI_NAME}/libgabi++_static.a" )
    996  elseif( ANDROID_STL MATCHES "stlport" )
    997   if( NOT ANDROID_NDK_RELEASE_NUM LESS 8004 ) # before r8d
    998    set( ANDROID_EXCEPTIONS       ON )
    999   else()
   1000    set( ANDROID_EXCEPTIONS       OFF )
   1001   endif()
   1002   if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
   1003    set( ANDROID_RTTI            OFF )
   1004   else()
   1005    set( ANDROID_RTTI            ON )
   1006   endif()
   1007   set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" )
   1008   set( __libstl                 "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
   1009  elseif( ANDROID_STL MATCHES "gnustl" )
   1010   set( ANDROID_EXCEPTIONS       ON )
   1011   set( ANDROID_RTTI             ON )
   1012   if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
   1013    if( ARMEABI_V7A AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.7" AND ANDROID_NDK_RELEASE STREQUAL "r8d" )
   1014     # gnustl binary for 4.7 compiler is buggy :(
   1015     # TODO: look for right fix
   1016     set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.6" )
   1017    else()
   1018     set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
   1019    endif()
   1020   else()
   1021    set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" )
   1022   endif()
   1023   set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" "${__libstl}/include/backward" )
   1024   if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
   1025    set( __libstl                "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
   1026   else()
   1027    set( __libstl                "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
   1028   endif()
   1029  else()
   1030   message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" )
   1031  endif()
   1032  # find libsupc++.a - rtti & exceptions
   1033  if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
   1034   set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer
   1035   if( NOT EXISTS "${__libsupcxx}" )
   1036    set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8
   1037   endif()
   1038   if( NOT EXISTS "${__libsupcxx}" ) # before r7
   1039    if( ARMEABI_V7A )
   1040     if( ANDROID_FORCE_ARM_BUILD )
   1041      set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
   1042     else()
   1043      set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" )
   1044     endif()
   1045    elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD )
   1046     set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" )
   1047    else()
   1048     set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" )
   1049    endif()
   1050   endif()
   1051   if( NOT EXISTS "${__libsupcxx}")
   1052    message( ERROR "Could not find libsupc++.a for a chosen platform. Either your NDK is not supported or is broken.")
   1053   endif()
   1054  endif()
   1055 endif()
   1056 
   1057 
   1058 # case of shared STL linkage
   1059 if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl )
   1060  string( REPLACE "_static.a" "_shared.so" __libstl "${__libstl}" )
   1061  # TODO: check if .so file exists before the renaming
   1062 endif()
   1063 
   1064 
   1065 # ccache support
   1066 __INIT_VARIABLE( _ndk_ccache NDK_CCACHE ENV_NDK_CCACHE )
   1067 if( _ndk_ccache )
   1068  if( DEFINED NDK_CCACHE AND NOT EXISTS NDK_CCACHE )
   1069   unset( NDK_CCACHE CACHE )
   1070  endif()
   1071  find_program( NDK_CCACHE "${_ndk_ccache}" DOC "The path to ccache binary")
   1072 else()
   1073  unset( NDK_CCACHE CACHE )
   1074 endif()
   1075 unset( _ndk_ccache )
   1076 
   1077 
   1078 # setup the cross-compiler
   1079 if( NOT CMAKE_C_COMPILER )
   1080  if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
   1081   set( CMAKE_C_COMPILER   "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" )
   1082   set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" )
   1083   if( ANDROID_COMPILER_IS_CLANG )
   1084    set( CMAKE_C_COMPILER_ARG1   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")
   1085    set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
   1086   else()
   1087    set( CMAKE_C_COMPILER_ARG1   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
   1088    set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
   1089   endif()
   1090  else()
   1091   if( ANDROID_COMPILER_IS_CLANG )
   1092    set( CMAKE_C_COMPILER   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")
   1093    set( CMAKE_CXX_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
   1094   else()
   1095    set( CMAKE_C_COMPILER   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}"    CACHE PATH "C compiler" )
   1096    set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}"    CACHE PATH "C++ compiler" )
   1097   endif()
   1098  endif()
   1099  set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}"     CACHE PATH "assembler" )
   1100  set( CMAKE_STRIP        "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}"   CACHE PATH "strip" )
   1101  if( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}" )
   1102   # Use gcc-ar if we have it for better LTO support.
   1103   set( CMAKE_AR           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}"      CACHE PATH "archive" )
   1104  else()
   1105   set( CMAKE_AR           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}"      CACHE PATH "archive" )
   1106  endif()
   1107  set( CMAKE_LINKER       "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}"      CACHE PATH "linker" )
   1108  set( CMAKE_NM           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}"      CACHE PATH "nm" )
   1109  set( CMAKE_OBJCOPY      "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" )
   1110  set( CMAKE_OBJDUMP      "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" )
   1111  set( CMAKE_RANLIB       "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}"  CACHE PATH "ranlib" )
   1112 endif()
   1113 
   1114 set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" )
   1115 if( CMAKE_VERSION VERSION_LESS 2.8.5 )
   1116  set( CMAKE_ASM_COMPILER_ARG1 "-c" )
   1117 endif()
   1118 if( APPLE )
   1119  find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool )
   1120  if( NOT CMAKE_INSTALL_NAME_TOOL )
   1121   message( FATAL_ERROR "Could not find install_name_tool, please check your installation." )
   1122  endif()
   1123  mark_as_advanced( CMAKE_INSTALL_NAME_TOOL )
   1124 endif()
   1125 
   1126 # Force set compilers because standard identification works badly for us
   1127 include( CMakeForceCompiler )
   1128 CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU )
   1129 if( ANDROID_COMPILER_IS_CLANG )
   1130  set( CMAKE_C_COMPILER_ID Clang )
   1131 endif()
   1132 set( CMAKE_C_PLATFORM_ID Linux )
   1133 if( X86_64 OR MIPS64 OR ARM64_V8A )
   1134  set( CMAKE_C_SIZEOF_DATA_PTR 8 )
   1135 else()
   1136  set( CMAKE_C_SIZEOF_DATA_PTR 4 )
   1137 endif()
   1138 set( CMAKE_C_HAS_ISYSROOT 1 )
   1139 set( CMAKE_C_COMPILER_ABI ELF )
   1140 CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU )
   1141 if( ANDROID_COMPILER_IS_CLANG )
   1142  set( CMAKE_CXX_COMPILER_ID Clang)
   1143 endif()
   1144 set( CMAKE_CXX_PLATFORM_ID Linux )
   1145 set( CMAKE_CXX_SIZEOF_DATA_PTR ${CMAKE_C_SIZEOF_DATA_PTR} )
   1146 set( CMAKE_CXX_HAS_ISYSROOT 1 )
   1147 set( CMAKE_CXX_COMPILER_ABI ELF )
   1148 set( CMAKE_CXX_SOURCE_FILE_EXTENSIONS cc cp cxx cpp CPP c++ C )
   1149 # force ASM compiler (required for CMake < 2.8.5)
   1150 set( CMAKE_ASM_COMPILER_ID_RUN TRUE )
   1151 set( CMAKE_ASM_COMPILER_ID GNU )
   1152 set( CMAKE_ASM_COMPILER_WORKS TRUE )
   1153 set( CMAKE_ASM_COMPILER_FORCED TRUE )
   1154 set( CMAKE_COMPILER_IS_GNUASM 1)
   1155 set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm )
   1156 
   1157 foreach( lang C CXX ASM )
   1158  if( ANDROID_COMPILER_IS_CLANG )
   1159   set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_CLANG_VERSION} )
   1160  else()
   1161   set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_COMPILER_VERSION} )
   1162  endif()
   1163 endforeach()
   1164 
   1165 # flags and definitions
   1166 remove_definitions( -DANDROID )
   1167 add_definitions( -DANDROID )
   1168 
   1169 if( ANDROID_SYSROOT MATCHES "[ ;\"]" )
   1170  if( CMAKE_HOST_WIN32 )
   1171   # try to convert path to 8.3 form
   1172   file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" )
   1173   execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}"
   1174                    OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE
   1175                    RESULT_VARIABLE __result ERROR_QUIET )
   1176   if( __result EQUAL 0 )
   1177    file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT )
   1178    set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
   1179   else()
   1180    set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
   1181   endif()
   1182  else()
   1183   set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" )
   1184  endif()
   1185  if( NOT _CMAKE_IN_TRY_COMPILE )
   1186   # quotes can break try_compile and compiler identification
   1187   message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n")
   1188  endif()
   1189 else()
   1190  set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
   1191 endif()
   1192 
   1193 # NDK flags
   1194 if (ARM64_V8A )
   1195  set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS} -funwind-tables" )
   1196  set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
   1197  set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer -fno-strict-aliasing" )
   1198  if( NOT ANDROID_COMPILER_IS_CLANG )
   1199   set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
   1200  endif()
   1201 elseif( ARMEABI OR ARMEABI_V7A)
   1202  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
   1203  if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
   1204   set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" )
   1205   set( ANDROID_CXX_FLAGS_DEBUG   "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
   1206   if( NOT ANDROID_COMPILER_IS_CLANG )
   1207    set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -finline-limit=64" )
   1208   endif()
   1209  else()
   1210   # always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI
   1211   set( ANDROID_CXX_FLAGS_RELEASE "-marm -fomit-frame-pointer -fstrict-aliasing" )
   1212   set( ANDROID_CXX_FLAGS_DEBUG   "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
   1213   if( NOT ANDROID_COMPILER_IS_CLANG )
   1214    set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
   1215   endif()
   1216  endif()
   1217 elseif( X86 OR X86_64 )
   1218  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
   1219  if( NOT ANDROID_COMPILER_IS_CLANG )
   1220   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
   1221  endif()
   1222  set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
   1223  set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer -fno-strict-aliasing" )
   1224 elseif( MIPS OR MIPS64 )
   1225  set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS} -fno-strict-aliasing -finline-functions -funwind-tables -fmessage-length=0" )
   1226  set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" )
   1227  set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer" )
   1228  if( NOT ANDROID_COMPILER_IS_CLANG )
   1229   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
   1230   set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
   1231  endif()
   1232 elseif()
   1233  set( ANDROID_CXX_FLAGS_RELEASE "" )
   1234  set( ANDROID_CXX_FLAGS_DEBUG   "" )
   1235 endif()
   1236 
   1237 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
   1238 
   1239 if( NOT X86 AND NOT ANDROID_COMPILER_IS_CLANG )
   1240  set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
   1241 endif()
   1242 
   1243 if( NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.6" )
   1244  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -no-canonical-prefixes" ) # see https://android-review.googlesource.com/#/c/47564/
   1245 endif()
   1246 
   1247 # ABI-specific flags
   1248 if( ARMEABI_V7A )
   1249  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" )
   1250  if( NEON )
   1251   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=neon" )
   1252  elseif( VFPV3 )
   1253   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" )
   1254  else()
   1255   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" )
   1256  endif()
   1257 elseif( ARMEABI_V6 )
   1258  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) # vfp == vfpv2
   1259 elseif( ARMEABI )
   1260  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" )
   1261 endif()
   1262 
   1263 if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") )
   1264  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
   1265  set( CMAKE_CXX_CREATE_SHARED_MODULE  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
   1266  set( CMAKE_CXX_LINK_EXECUTABLE       "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
   1267 else()
   1268  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
   1269  set( CMAKE_CXX_CREATE_SHARED_MODULE  "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
   1270  set( CMAKE_CXX_LINK_EXECUTABLE       "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
   1271 endif()
   1272 
   1273 # STL
   1274 if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
   1275  if( EXISTS "${__libstl}" )
   1276   set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" )
   1277   set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" )
   1278   set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libstl}\"" )
   1279  endif()
   1280  if( EXISTS "${__libsupcxx}" )
   1281   set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" )
   1282   set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" )
   1283   set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
   1284   # C objects:
   1285   set( CMAKE_C_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
   1286   set( CMAKE_C_CREATE_SHARED_MODULE  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
   1287   set( CMAKE_C_LINK_EXECUTABLE       "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
   1288   set( CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" )
   1289   set( CMAKE_C_CREATE_SHARED_MODULE  "${CMAKE_C_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" )
   1290   set( CMAKE_C_LINK_EXECUTABLE       "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
   1291  endif()
   1292  if( ANDROID_STL MATCHES "gnustl" )
   1293   if( NOT EXISTS "${ANDROID_LIBM_PATH}" )
   1294    set( ANDROID_LIBM_PATH -lm )
   1295   endif()
   1296   set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" )
   1297   set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" )
   1298   set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" )
   1299  endif()
   1300 endif()
   1301 
   1302 # variables controlling optional build flags
   1303 if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
   1304  # libGLESv2.so in NDK's prior to r7 refers to missing external symbols.
   1305  # So this flag option is required for all projects using OpenGL from native.
   1306  __INIT_VARIABLE( ANDROID_SO_UNDEFINED                      VALUES ON )
   1307 else()
   1308  __INIT_VARIABLE( ANDROID_SO_UNDEFINED                      VALUES OFF )
   1309 endif()
   1310 __INIT_VARIABLE( ANDROID_NO_UNDEFINED                       VALUES ON )
   1311 __INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING             VALUES ON )
   1312 __INIT_VARIABLE( ANDROID_GOLD_LINKER                        VALUES ON )
   1313 __INIT_VARIABLE( ANDROID_NOEXECSTACK                        VALUES ON )
   1314 __INIT_VARIABLE( ANDROID_RELRO                              VALUES ON )
   1315 
   1316 set( ANDROID_NO_UNDEFINED           ${ANDROID_NO_UNDEFINED}           CACHE BOOL "Show all undefined symbols as linker errors" )
   1317 set( ANDROID_SO_UNDEFINED           ${ANDROID_SO_UNDEFINED}           CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
   1318 set( ANDROID_FUNCTION_LEVEL_LINKING ${ANDROID_FUNCTION_LEVEL_LINKING} CACHE BOOL "Put each function in separate section and enable garbage collection of unused input sections at link time" )
   1319 set( ANDROID_GOLD_LINKER            ${ANDROID_GOLD_LINKER}            CACHE BOOL "Enables gold linker" )
   1320 set( ANDROID_NOEXECSTACK            ${ANDROID_NOEXECSTACK}            CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
   1321 set( ANDROID_RELRO                  ${ANDROID_RELRO}                  CACHE BOOL "Enables RELRO - a memory corruption mitigation technique" )
   1322 mark_as_advanced( ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_FUNCTION_LEVEL_LINKING ANDROID_GOLD_LINKER ANDROID_NOEXECSTACK ANDROID_RELRO )
   1323 
   1324 # linker flags
   1325 set( ANDROID_LINKER_FLAGS "" )
   1326 
   1327 if( ARMEABI_V7A )
   1328  # this is *required* to use the following linker flags that routes around
   1329  # a CPU bug in some Cortex-A8 implementations:
   1330  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--fix-cortex-a8" )
   1331 endif()
   1332 
   1333 if( ANDROID_NO_UNDEFINED )
   1334  if( MIPS )
   1335   # there is some sysroot-related problem in mips linker...
   1336   if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
   1337    set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" )
   1338   endif()
   1339  else()
   1340   set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
   1341  endif()
   1342 endif()
   1343 
   1344 if( ANDROID_SO_UNDEFINED )
   1345  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
   1346 endif()
   1347 
   1348 if( ANDROID_FUNCTION_LEVEL_LINKING )
   1349  set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
   1350  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" )
   1351 endif()
   1352 
   1353 if( ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" )
   1354  if( ANDROID_GOLD_LINKER AND (CMAKE_HOST_UNIX OR ANDROID_NDK_RELEASE_NUM GREATER 8002) AND (ARMEABI OR ARMEABI_V7A OR X86) )
   1355   set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" )
   1356  elseif( ANDROID_NDK_RELEASE_NUM GREATER 8002 ) # after r8b
   1357   set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=bfd" )
   1358  elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND NOT _CMAKE_IN_TRY_COMPILE )
   1359   message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342
   1360   On Linux and OS X host platform you can workaround this problem using gold linker (default).
   1361   Rerun cmake with -DANDROID_GOLD_LINKER=ON option in case of problems.
   1362 " )
   1363  endif()
   1364 endif() # version 4.6
   1365 
   1366 if( ANDROID_NOEXECSTACK )
   1367  if( ANDROID_COMPILER_IS_CLANG )
   1368   set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -Xclang -mnoexecstack" )
   1369  else()
   1370   set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" )
   1371  endif()
   1372  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,noexecstack" )
   1373 endif()
   1374 
   1375 if( ANDROID_RELRO )
   1376  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now" )
   1377 endif()
   1378 
   1379 if( ANDROID_COMPILER_IS_CLANG )
   1380  set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} -Qunused-arguments ${ANDROID_CXX_FLAGS}" )
   1381  if( BUILD_WITH_ANDROID_NDK )
   1382   set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" )
   1383  endif()
   1384 endif()
   1385 
   1386 # cache flags
   1387 set( CMAKE_CXX_FLAGS           ""                        CACHE STRING "c++ flags" )
   1388 set( CMAKE_C_FLAGS             ""                        CACHE STRING "c flags" )
   1389 set( CMAKE_CXX_FLAGS_RELEASE   "-O3 -DNDEBUG"            CACHE STRING "c++ Release flags" )
   1390 set( CMAKE_C_FLAGS_RELEASE     "-O3 -DNDEBUG"            CACHE STRING "c Release flags" )
   1391 set( CMAKE_CXX_FLAGS_DEBUG     "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c++ Debug flags" )
   1392 set( CMAKE_C_FLAGS_DEBUG       "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c Debug flags" )
   1393 set( CMAKE_SHARED_LINKER_FLAGS ""                        CACHE STRING "shared linker flags" )
   1394 set( CMAKE_MODULE_LINKER_FLAGS ""                        CACHE STRING "module linker flags" )
   1395 set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-z,nocopyreloc"      CACHE STRING "executable linker flags" )
   1396 
   1397 # put flags to cache (for debug purpose only)
   1398 set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS}"         CACHE INTERNAL "Android specific c/c++ flags" )
   1399 set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE}" CACHE INTERNAL "Android specific c/c++ Release flags" )
   1400 set( ANDROID_CXX_FLAGS_DEBUG   "${ANDROID_CXX_FLAGS_DEBUG}"   CACHE INTERNAL "Android specific c/c++ Debug flags" )
   1401 set( ANDROID_LINKER_FLAGS      "${ANDROID_LINKER_FLAGS}"      CACHE INTERNAL "Android specific c/c++ linker flags" )
   1402 
   1403 # finish flags
   1404 set( CMAKE_CXX_FLAGS           "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
   1405 set( CMAKE_C_FLAGS             "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
   1406 set( CMAKE_CXX_FLAGS_RELEASE   "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}" )
   1407 set( CMAKE_C_FLAGS_RELEASE     "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}" )
   1408 set( CMAKE_CXX_FLAGS_DEBUG     "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}" )
   1409 set( CMAKE_C_FLAGS_DEBUG       "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}" )
   1410 set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" )
   1411 set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" )
   1412 set( CMAKE_EXE_LINKER_FLAGS    "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
   1413 
   1414 if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
   1415  set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
   1416  set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
   1417  set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
   1418 endif()
   1419 
   1420 # pie/pic
   1421 if( NOT (ANDROID_NATIVE_API_LEVEL LESS 16) AND (NOT DEFINED ANDROID_APP_PIE OR ANDROID_APP_PIE) AND (CMAKE_VERSION VERSION_GREATER 2.8.8) )
   1422  set( CMAKE_POSITION_INDEPENDENT_CODE TRUE )
   1423  set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")
   1424 else()
   1425  set( CMAKE_POSITION_INDEPENDENT_CODE FALSE )
   1426  set( CMAKE_CXX_FLAGS "-fpic ${CMAKE_CXX_FLAGS}" )
   1427  set( CMAKE_C_FLAGS   "-fpic ${CMAKE_C_FLAGS}" )
   1428 endif()
   1429 
   1430 # configure rtti
   1431 if( DEFINED ANDROID_RTTI AND ANDROID_STL_FORCE_FEATURES )
   1432  if( ANDROID_RTTI )
   1433   set( CMAKE_CXX_FLAGS "-frtti ${CMAKE_CXX_FLAGS}" )
   1434  else()
   1435   set( CMAKE_CXX_FLAGS "-fno-rtti ${CMAKE_CXX_FLAGS}" )
   1436  endif()
   1437 endif()
   1438 
   1439 # configure exceptios
   1440 if( DEFINED ANDROID_EXCEPTIONS AND ANDROID_STL_FORCE_FEATURES )
   1441  if( ANDROID_EXCEPTIONS )
   1442   set( CMAKE_CXX_FLAGS "-fexceptions ${CMAKE_CXX_FLAGS}" )
   1443   set( CMAKE_C_FLAGS "-fexceptions ${CMAKE_C_FLAGS}" )
   1444  else()
   1445   set( CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}" )
   1446   set( CMAKE_C_FLAGS "-fno-exceptions ${CMAKE_C_FLAGS}" )
   1447  endif()
   1448 endif()
   1449 
   1450 # global includes and link directories
   1451 include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} )
   1452 get_filename_component(__android_install_path "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ABSOLUTE) # avoid CMP0015 policy warning
   1453 link_directories( "${__android_install_path}" )
   1454 
   1455 # detect if need link crtbegin_so.o explicitly
   1456 if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK )
   1457  set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" )
   1458  string( REPLACE "<CMAKE_CXX_COMPILER>" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" )
   1459  string( REPLACE "<CMAKE_C_COMPILER>"   "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"   __cmd "${__cmd}" )
   1460  string( REPLACE "<CMAKE_SHARED_LIBRARY_CXX_FLAGS>" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" )
   1461  string( REPLACE "<LANGUAGE_COMPILE_FLAGS>" "" __cmd "${__cmd}" )
   1462  string( REPLACE "<LINK_FLAGS>" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" )
   1463  string( REPLACE "<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>" "-shared" __cmd "${__cmd}" )
   1464  string( REPLACE "<CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG>" "" __cmd "${__cmd}" )
   1465  string( REPLACE "<TARGET_SONAME>" "" __cmd "${__cmd}" )
   1466  string( REPLACE "<TARGET>" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" )
   1467  string( REPLACE "<OBJECTS>" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" )
   1468  string( REPLACE "<LINK_LIBRARIES>" "" __cmd "${__cmd}" )
   1469  separate_arguments( __cmd )
   1470  foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN )
   1471   if( ${__var} )
   1472    set( __tmp "${${__var}}" )
   1473    separate_arguments( __tmp )
   1474    string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}")
   1475   endif()
   1476  endforeach()
   1477  string( REPLACE "'" "" __cmd "${__cmd}" )
   1478  string( REPLACE "\"" "" __cmd "${__cmd}" )
   1479  execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET )
   1480  if( __cmd_result EQUAL 0 )
   1481   set( ANDROID_EXPLICIT_CRT_LINK ON )
   1482  else()
   1483   set( ANDROID_EXPLICIT_CRT_LINK OFF )
   1484  endif()
   1485 endif()
   1486 
   1487 if( ANDROID_EXPLICIT_CRT_LINK )
   1488  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
   1489  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
   1490 endif()
   1491 
   1492 # setup output directories
   1493 set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
   1494 
   1495 if( DEFINED LIBRARY_OUTPUT_PATH_ROOT
   1496       OR EXISTS "${CMAKE_SOURCE_DIR}/AndroidManifest.xml"
   1497       OR (EXISTS "${CMAKE_SOURCE_DIR}/../AndroidManifest.xml" AND EXISTS "${CMAKE_SOURCE_DIR}/../jni/") )
   1498   set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "Root for binaries output, set this to change where Android libs are installed to" )
   1499   if( NOT _CMAKE_IN_TRY_COMPILE )
   1500     if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
   1501       set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
   1502     else()
   1503       set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
   1504     endif()
   1505     set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for Android libs" )
   1506   endif()
   1507 endif()
   1508 
   1509 # copy shaed stl library to build directory
   1510 if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" AND DEFINED LIBRARY_OUTPUT_PATH )
   1511   get_filename_component( __libstlname "${__libstl}" NAME )
   1512   execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess )
   1513   if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}")
   1514     message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" )
   1515   endif()
   1516   unset( __fileCopyProcess )
   1517   unset( __libstlname )
   1518 endif()
   1519 
   1520 
   1521 # set these global flags for cmake client scripts to change behavior
   1522 set( ANDROID True )
   1523 set( BUILD_ANDROID True )
   1524 
   1525 # where is the target environment
   1526 set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" )
   1527 
   1528 # only search for libraries and includes in the ndk toolchain
   1529 set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
   1530 set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
   1531 set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
   1532 
   1533 
   1534 # macro to find packages on the host OS
   1535 macro( find_host_package )
   1536  set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
   1537  set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
   1538  set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
   1539  if( CMAKE_HOST_WIN32 )
   1540   SET( WIN32 1 )
   1541   SET( UNIX )
   1542  elseif( CMAKE_HOST_APPLE )
   1543   SET( APPLE 1 )
   1544   SET( UNIX )
   1545  endif()
   1546  find_package( ${ARGN} )
   1547  SET( WIN32 )
   1548  SET( APPLE )
   1549  SET( UNIX 1 )
   1550  set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
   1551  set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
   1552  set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
   1553 endmacro()
   1554 
   1555 
   1556 # macro to find programs on the host OS
   1557 macro( find_host_program )
   1558  set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
   1559  set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
   1560  set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
   1561  if( CMAKE_HOST_WIN32 )
   1562   SET( WIN32 1 )
   1563   SET( UNIX )
   1564  elseif( CMAKE_HOST_APPLE )
   1565   SET( APPLE 1 )
   1566   SET( UNIX )
   1567  endif()
   1568  find_program( ${ARGN} )
   1569  SET( WIN32 )
   1570  SET( APPLE )
   1571  SET( UNIX 1 )
   1572  set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
   1573  set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
   1574  set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
   1575 endmacro()
   1576 
   1577 
   1578 # export toolchain settings for the try_compile() command
   1579 if( NOT _CMAKE_IN_TRY_COMPILE )
   1580  set( __toolchain_config "")
   1581  foreach( __var NDK_CCACHE  LIBRARY_OUTPUT_PATH_ROOT  ANDROID_FORBID_SYGWIN
   1582                 ANDROID_NDK_HOST_X64
   1583                 ANDROID_NDK
   1584                 ANDROID_NDK_LAYOUT
   1585                 ANDROID_STANDALONE_TOOLCHAIN
   1586                 ANDROID_TOOLCHAIN_NAME
   1587                 ANDROID_ABI
   1588                 ANDROID_NATIVE_API_LEVEL
   1589                 ANDROID_STL
   1590                 ANDROID_STL_FORCE_FEATURES
   1591                 ANDROID_FORCE_ARM_BUILD
   1592                 ANDROID_NO_UNDEFINED
   1593                 ANDROID_SO_UNDEFINED
   1594                 ANDROID_FUNCTION_LEVEL_LINKING
   1595                 ANDROID_GOLD_LINKER
   1596                 ANDROID_NOEXECSTACK
   1597                 ANDROID_RELRO
   1598                 ANDROID_LIBM_PATH
   1599                 ANDROID_EXPLICIT_CRT_LINK
   1600                 ANDROID_APP_PIE
   1601                 )
   1602   if( DEFINED ${__var} )
   1603    if( ${__var} MATCHES " ")
   1604     set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" )
   1605    else()
   1606     set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" )
   1607    endif()
   1608   endif()
   1609  endforeach()
   1610  file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" )
   1611  unset( __toolchain_config )
   1612 endif()
   1613 
   1614 
   1615 # force cmake to produce / instead of \ in build commands for Ninja generator
   1616 if( CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_HOST_WIN32 )
   1617  # it is a bad hack after all
   1618  # CMake generates Ninja makefiles with UNIX paths only if it thinks that we are going to build with MinGW
   1619  set( CMAKE_COMPILER_IS_MINGW TRUE ) # tell CMake that we are MinGW
   1620  set( CMAKE_CROSSCOMPILING TRUE )    # stop recursion
   1621  enable_language( C )
   1622  enable_language( CXX )
   1623  # unset( CMAKE_COMPILER_IS_MINGW ) # can't unset because CMake does not convert back-slashes in response files without it
   1624  unset( MINGW )
   1625 endif()
   1626 
   1627 
   1628 # Variables controlling behavior or set by cmake toolchain:
   1629 #   ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips", "arm64-v8a", "x86_64", "mips64"
   1630 #   ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14,15,16,17,18,19,21 (depends on NDK version)
   1631 #   ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none
   1632 #   ANDROID_FORBID_SYGWIN : ON/OFF
   1633 #   ANDROID_NO_UNDEFINED : ON/OFF
   1634 #   ANDROID_SO_UNDEFINED : OFF/ON  (default depends on NDK version)
   1635 #   ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF
   1636 #   ANDROID_GOLD_LINKER : ON/OFF
   1637 #   ANDROID_NOEXECSTACK : ON/OFF
   1638 #   ANDROID_RELRO : ON/OFF
   1639 #   ANDROID_FORCE_ARM_BUILD : ON/OFF
   1640 #   ANDROID_STL_FORCE_FEATURES : ON/OFF
   1641 #   ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
   1642 # Can be set only at the first run:
   1643 #   ANDROID_NDK : path to your NDK install
   1644 #   NDK_CCACHE : path to your ccache executable
   1645 #   ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
   1646 #   ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems)
   1647 #   ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID)
   1648 #   LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
   1649 #   ANDROID_STANDALONE_TOOLCHAIN
   1650 #
   1651 # Primary read-only variables:
   1652 #   ANDROID : always TRUE
   1653 #   ARMEABI : TRUE for arm v6 and older devices
   1654 #   ARMEABI_V6 : TRUE for arm v6
   1655 #   ARMEABI_V7A : TRUE for arm v7a
   1656 #   ARM64_V8A : TRUE for arm64-v8a
   1657 #   NEON : TRUE if NEON unit is enabled
   1658 #   VFPV3 : TRUE if VFP version 3 is enabled
   1659 #   X86 : TRUE if configured for x86
   1660 #   X86_64 : TRUE if configured for x86_64
   1661 #   MIPS : TRUE if configured for mips
   1662 #   MIPS64 : TRUE if configured for mips64
   1663 #   BUILD_WITH_ANDROID_NDK : TRUE if NDK is used
   1664 #   BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
   1665 #   ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
   1666 #   ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "x86_64", "mips64" depending on ANDROID_ABI
   1667 #   ANDROID_NDK_RELEASE : from r5 to r10d; set only for NDK
   1668 #   ANDROID_NDK_RELEASE_NUM : numeric ANDROID_NDK_RELEASE version (1000*major+minor)
   1669 #   ANDROID_ARCH_NAME : "arm", "x86", "mips", "arm64", "x86_64", "mips64" depending on ANDROID_ABI
   1670 #   ANDROID_SYSROOT : path to the compiler sysroot
   1671 #   TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
   1672 #   ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used
   1673 #
   1674 # Secondary (less stable) read-only variables:
   1675 #   ANDROID_COMPILER_VERSION : GCC version used (not Clang version)
   1676 #   ANDROID_CLANG_VERSION : version of clang compiler if clang is used
   1677 #   ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform
   1678 #   ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI
   1679 #   ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux"
   1680 #   ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK)
   1681 #   ANDROID_CLANG_TOOLCHAIN_ROOT : path to clang tools
   1682 #   ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK
   1683 #   ANDROID_STL_INCLUDE_DIRS : stl include paths
   1684 #   ANDROID_RTTI : if rtti is enabled by the runtime
   1685 #   ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
   1686 #   ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
   1687 #
   1688 # Defaults:
   1689 #   ANDROID_DEFAULT_NDK_API_LEVEL
   1690 #   ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH}
   1691 #   ANDROID_NDK_SEARCH_PATHS
   1692 #   ANDROID_SUPPORTED_ABIS_${ARCH}
   1693 #   ANDROID_SUPPORTED_NDK_VERSIONS
   1694