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