this repo has no description
at master 1280 lines 64 kB view raw
1# ------------------------------------------------------------------------------ 2# Android CMake toolchain file, for use with the Android NDK r5-r8 3# Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended). 4# See home page: http://code.google.com/p/android-cmake/ 5# 6# The file is mantained by the OpenCV project. And also can be found at 7# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake 8# 9# Note: There are now two flavors of this toolchain file: 32-bit toolchain and 64-bit toolchain. 10# 11# Usage Linux: 12# $ export ANDROID_NDK_ROOT=/absolute/path/to/the/android-ndk 13# $ mkdir build && cd build 14# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .. 15# $ make -j8 16# 17# Usage Linux (using standalone toolchain): 18# $ export ANDROID_STANDALONE_TOOLCHAIN=/absolute/path/to/android-toolchain 19# $ mkdir build && cd build 20# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .. 21# $ make -j8 22# 23# Usage Windows: 24# You need native port of make to build your project. 25# Android NDK r7 (or newer) already has make.exe on board. 26# For older NDK you have to install it separately. 27# For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm 28# 29# $ SET ANDROID_NDK_ROOT=C:\absolute\path\to\the\android-ndk 30# $ mkdir build && cd build 31# $ cmake.exe -G"MinGW Makefiles" 32# -DCMAKE_TOOLCHAIN_FILE=path\to\the\android.toolchain.cmake 33# -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK_ROOT%\prebuilt\windows\bin\make.exe" .. 34# $ "%ANDROID_NDK_ROOT%\prebuilt\windows\bin\make.exe" 35# 36# 37# Options (can be set as cmake parameters: -D<option_name>=<value>): 38# ANDROID_NDK=/opt/android-ndk - path to the NDK root. 39# Can be set as environment variable ANDROID_NDK_ROOT. Can be set only at first cmake run. 40# 41# ANDROID_STANDALONE_TOOLCHAIN=/opt/android-toolchain - path to the 42# standalone toolchain. This option overrides ANDROID_NDK 43# (and subsequentally the enviroment variable ANDROID_NDK_ROOT). 44# Can be set as environment variable. Can be set only at first cmake run. 45# 46# ANDROID_ABI=armeabi-v7a - specifies the target Application Binary 47# Interface (ABI). This option nearly matches to the APP_ABI variable 48# used by ndk-build tool from Android NDK. 49# 50# Possible targets are: 51# "armeabi" - matches to the NDK ABI with the same name. 52# See ${ANDROID_NDK_ROOT}/docs/CPU-ARCH-ABIS.html for the documentation. 53# "armeabi-v7a" - matches to the NDK ABI with the same name. 54# See ${ANDROID_NDK_ROOT}/docs/CPU-ARCH-ABIS.html for the documentation. 55# "armeabi-v7a with NEON" - same as armeabi-v7a, but 56# sets NEON as floating-point unit 57# "armeabi-v7a with VFPV3" - same as armeabi-v7a, but 58# sets VFPV3 as floating-point unit (has 32 registers instead of 16). 59# "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP. 60# "x86" - matches to the NDK ABI with the same name. 61# See ${ANDROID_NDK_ROOT}/docs/CPU-ARCH-ABIS.html for the documentation. 62# "mips" - matches to the NDK ABI with the same name 63# (not testes on real devices) 64# 65# ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for. 66# Option is read-only when standalone toolchain used. 67# 68# ANDROID_FORCE_ARM_BUILD=OFF - set true to generate 32-bit ARM instructions 69# instead of Thumb-1. Is not available for "x86" (inapplicable) and 70# "armeabi-v6 with VFP" (forced) ABIs. 71# 72# ANDROID_NO_UNDEFINED=ON - set true to show all undefined symbols as linker 73# errors even if they are not used. 74# 75# ANDROID_SO_UNDEFINED=OFF - set true to allow undefined symbols in shared 76# libraries. Automatically turned on for NDK r5x and r6x due to GLESv2 77# problems. 78# 79# LIBRARY_OUTPUT_PATH_ROOT=${CMAKE_SOURCE_DIR} - where to output binary 80# files. See additional details below. 81# 82# ANDROID_SET_OBSOLETE_VARIABLES=ON - it set, then toolchain defines some 83# obsolete variables which were set by previous versions of this file for 84# backward compatibility. 85# 86# 87# What?: 88# android-cmake toolchain searches for NDK/toolchain in the following order: 89# ANDROID_NDK - cmake parameter 90# ANDROID_NDK_ROOT - environment variable 91# (ANDROID_NDK - environment variable as legacy fallback) 92# ANDROID_STANDALONE_TOOLCHAIN - cmake parameter 93# ANDROID_STANDALONE_TOOLCHAIN - environment variable 94# ANDROID_NDK - default locations 95# ANDROID_STANDALONE_TOOLCHAIN - default locations 96# 97# Make sure to do the following in your scripts: 98# SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}" ) 99# SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}" ) 100# The flags will be prepopulated with critical flags, so don't loose them. 101# Also be aware that toolchain also sets configuration-specific compiler 102# flags and linker flags. 103# 104# ANDROID and BUILD_ANDROID will be set to true, you may test any of these 105# variables to make necessary Android-specific configuration changes. 106# 107# Also ARMEABI or ARMEABI_V7A or X86 will be set true, mutually exclusive. 108# NEON option will be set true if VFP is set to NEON. 109# 110# LIBRARY_OUTPUT_PATH_ROOT should be set in cache to determine where Android 111# libraries will be installed. 112# Default is ${CMAKE_SOURCE_DIR}, and the android libs will always be 113# under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME} 114# (depending on the target ABI). This is convenient for Android packaging. 115# 116# Authors: 117# Ethan Rublee ethan.ruble@gmail.com 118# Andrey Kamaev andrey.kamaev@itseez.com 119# Eric Wing <ewing . public |-at-| gmail . com> 120# 121# Change Log: 122# - initial version December 2010 123# - modified April 2011 124# [+] added possibility to build with NDK (without standalone toolchain) 125# [+] support cross-compilation on Windows (native, no cygwin support) 126# [+] added compiler option to force "char" type to be signed 127# [+] added toolchain option to compile to 32-bit ARM instructions 128# [+] added toolchain option to disable SWIG search 129# [+] added platform "armeabi-v7a with VFPV3" 130# [~] ARM_TARGETS renamed to ARM_TARGET 131# [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows) 132# [~] Fixed bug with ANDROID_API_LEVEL variable 133# [~] turn off SWIG search if it is not found first time 134# - modified May 2011 135# [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL 136# [+] ANDROID_API_LEVEL is detected by toolchain if not specified 137# [~] added guard to prevent changing of output directories on the first 138# cmake pass 139# [~] toolchain exits with error if ARM_TARGET is not recognized 140# - modified June 2011 141# [~] default NDK path is updated for version r5c 142# [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET 143# [~] toolchain install directory is added to linker paths 144# [-] removed SWIG-related stuff from toolchain 145# [+] added macro find_host_package, find_host_program to search 146# packages/programs on the host system 147# [~] fixed path to STL library 148# - modified July 2011 149# [~] fixed options caching 150# [~] search for all supported NDK versions 151# [~] allowed spaces in NDK path 152# - modified September 2011 153# [~] updated for NDK r6b 154# - modified November 2011 155# [*] rewritten for NDK r7 156# [+] x86 toolchain support (experimental) 157# [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors. 158# [~] improved compiler and linker flags management 159# [+] support different build flags for Release and Debug configurations 160# [~] by default compiler flags the same as used by ndk-build (but only 161# where reasonable) 162# [~] ANDROID_NDK_TOOLCHAIN_ROOT is splitted to ANDROID_STANDALONE_TOOLCHAIN 163# and ANDROID_TOOLCHAIN_ROOT 164# [~] ARM_TARGET is renamed to ANDROID_ABI 165# [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME 166# [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL 167# - modified January 2012 168# [+] added stlport_static support (experimental) 169# [+] added special check for cygwin 170# [+] filtered out hidden files (starting with .) while globbing inside NDK 171# [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6 172# [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags 173# - modified February 2012 174# [+] updated for NDK r7b 175# [~] fixed cmake try_compile() command 176# [~] Fix for missing install_name_tool on OS X 177# - modified March 2012 178# [~] fixed incorrect C compiler flags 179# [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change 180# [+] improved toolchain loading speed 181# [+] added assembler language support (.S) 182# [+] allowed preset search paths and extra search suffixes 183# - modified April 2012 184# [+] updated for NDK r7c 185# [~] fixed most of problems with compiler/linker flags and caching 186# [+] added option ANDROID_FUNCTION_LEVEL_LINKING 187# - modified May 2012 188# [+] updated for NDK r8 189# [+] added mips architecture support 190# - modified August 2012 191# [+] updated for NDK r8b 192# [~] all intermediate files generated by toolchain are moved into CMakeFiles 193# [~] libstdc++ and libsupc are removed from explicit link libraries 194# - modified August 2013 (EW) 195# [+] updated for NDK r9 (standalone) 196# [+] Addded Perl helper scripts to make it easier to build multiple architectures in one shot. 197# [~] Breaking change of behavior to so that ANDROID_STANDALONE_TOOLCHAIN overrides ANDROID_NDK because the latter uses semi-standard environmental variables that people may already have defined for other conflicting purposes. 198# [~] Changed environmental variable to look for ANDROID_NDK_ROOT because this is the semi-official/blessed one according to Google via the NDK mailing list. ANDROID_NDK is still checked for backwards compatibility. 199# [~] Changed a lot of flags to try to match stock Android more closely due build problems I was trying to track down. In the end, I lost track of which specific flags were the problem. See Additional Notes for flag differences between this and stock. 200# [~] Changed armeabi-v7a to use -mfpu=vfpv3-d16 instead of -mfpu=vfp to conform with stock Android. 201# [~] Changed VFPV3 mode to use -mfpu=vfpv3-d32 202# [~] Use --sysroot=${ANDROID_SYSROOT} to match stock Android 203# [~] Use -fstack-protector -no-canonical-prefixes -Wa,--noexecstack to match stock Android 204# [~] Use -no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now to match stock Android 205# [~] Use -lc -lm to match stock Android 206# [~] Removed -fsigned-char and -Wno-psabi because these don't appear in stock Android 207# [~] Removed -f[no]exceptions flags from C flags because those are C++ options 208# [~] Changed arm debug optimization level to O0 from Os 209# [~] Added -funswitch-loops -finline-limit=300 to match stock Android 210# [~] Changed arm debug optimization level to O0 from Os 211# [~] Separated ANDROID_CXX_FLAGS into ANDROID_CXX_FLAGS and ANDROID_C_FLAGS 212# [*] Note: MIPs settings were not changed/tested. 213# 214# 215# (EW) Additional Notes: 216# Looking at the switches used by compiling the hello-jni example from ndk-build V=1 in r8d, I see the following compiler flags: 217# armeabi 218# -MMD -MP -MF /foo/hello-jni.o.d 219# -fpic -ffunction-sections -funwind-tables -fstack-protector 220# -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -no-canonical-prefixes 221# -march=armv5te -mtune=xscale -msoft-float 222# -mthumb 223# -Os -g -DNDEBUG 224# -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 225# 226# -O0 -UNDEBUG (debug only, not in release) 227# -marm -fno-omit-frame-pointer (debug only, not in release) 228# 229# -DANDROID -Wa,--noexecstack 230 231 232# armeabi-v7a 233# -MMD -MP -MF /foo/hello-jni.o.d 234# -fpic -ffunction-sections -funwind-tables -fstack-protector 235# -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -no-canonical-prefixes 236# -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 237# -mthumb 238# -Os -g -DNDEBUG 239# -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 240# 241# -O0 -UNDEBUG (debug only, not in release) 242# -marm -fno-omit-frame-pointer (debug only, not in release) 243# 244# -DANDROID -Wa,--noexecstack 245 246# x86 247# -MMD -MP -MF /foo/hello-jni.o.d 248# -ffunction-sections -funwind-tables -no-canonical-prefixes -fstack-protector 249# -O2 -g -DNDEBUG 250# -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 251# 252# -O0 -UNDEBUG (debug only, not in release) 253# -fno-omit-frame-pointer -fno-strict-aliasing (debug only, not in release) 254# 255# -DANDROID -Wa,--noexecstack 256 257# The link flags are: 258 259 260# armeabi 261# -Wl,-soname,libhello-jni.so -shared 262# --sysroot=/fee/android-ndk/platforms/android-14/arch-arm 263# /foo/hello-jni.o 264# -no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -lc -lm 265 266# armeabi-v7a 267# -Wl,-soname,libhello-jni.so -shared 268# --sysroot=/fee/android-ndk/platforms/android-14/arch-arm 269# /foo/hello-jni.o 270# -no-canonical-prefixes -march=armv7-a -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -lc -lm 271 272# x86 273# -Wl,-soname,libhello-jni.so -shared 274# --sysroot=/fee/android-ndk/platforms/android-14/arch-x86 275# /foo/hello-jni.o 276# -no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -lc -lm 277 278 279# Some interesting observations are that debug doesn't have different flags, but overrides set flags with additional switches. 280 281# Differences from Stock Android: 282# This toolchain has deviated from the stock flags. 283# 284# I don't do the override technique as described directly above. 285# 286# -ffunction-sections has been separated into the option ANDROID_FUNCTION_LEVEL_LINKING. 287# But this also brings in -fdata-sections and the linker flags -Wl,--gc-sections which are not in the Android defaults 288# 289# -funwind-tables has been completely removed for arm by this file. It looks like the author intentionally did this for performance. 290# 291# Optimization flags are using O3 in this file as opposed to stock 02 for Release. It looks like the original authors have done some benchmarking so I am deferring to them. 292# I am however changing the Os to O0 for debug. 293# 294# ------------------------------------------------------------------------------ 295 296cmake_minimum_required( VERSION 2.6.3 ) 297 298if( DEFINED CMAKE_CROSSCOMPILING ) 299 # subsequent toolchain loading is not really needed 300 return() 301endif() 302 303get_property(_CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) 304if( _CMAKE_IN_TRY_COMPILE ) 305 include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL ) 306endif() 307 308# this one is important 309set( CMAKE_SYSTEM_NAME Linux ) 310# this one not so much 311set( CMAKE_SYSTEM_VERSION 1 ) 312 313# There was an Android NDK bug with armv7 and vfpv3 in r7b which caused crashes according to 314# http://stackoverflow.com/questions/11831648/android-ndk-arm-build-settings-to-run-on-most-devices 315# Not supporting r7b or below seems wiser. Supporting ancient Android NDKs is rather pointless since part of the reason for the updates is to fix bugs. 316#set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8d -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) 317set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r9 -r8d -r8b -r8 -r7c "" ) 318if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS) 319 if( CMAKE_HOST_WIN32 ) 320 file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS ) 321 set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}/android-ndk" "$ENV{SystemDrive}/NVPACK/android-ndk" ) 322 else() 323 file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS ) 324 set( ANDROID_NDK_SEARCH_PATHS /opt/android-ndk "${ANDROID_NDK_SEARCH_PATHS}/NVPACK/android-ndk" ) 325 endif() 326endif() 327if(NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH) 328 set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain ) 329endif() 330 331set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" ) 332set( ANDROID_SUPPORTED_ABIS_x86 "x86" ) 333set( ANDROID_SUPPORTED_ABIS_mipsel "mips" ) 334 335set( ANDROID_DEFAULT_NDK_API_LEVEL 8 ) 336set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 ) 337set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 ) 338 339 340macro( __LIST_FILTER listvar regex ) 341 if( ${listvar} ) 342 foreach( __val ${${listvar}} ) 343 if( __val MATCHES "${regex}" ) 344 list( REMOVE_ITEM ${listvar} "${__val}" ) 345 endif() 346 endforeach() 347 endif() 348endmacro() 349 350macro( __INIT_VARIABLE var_name ) 351 set( __test_path 0 ) 352 foreach( __var ${ARGN} ) 353 if( __var STREQUAL "PATH" ) 354 set( __test_path 1 ) 355 break() 356 endif() 357 endforeach() 358 if( __test_path AND NOT EXISTS "${${var_name}}" ) 359 unset( ${var_name} CACHE ) 360 endif() 361 if( "${${var_name}}" STREQUAL "" ) 362 set( __values 0 ) 363 foreach( __var ${ARGN} ) 364 if( __var STREQUAL "VALUES" ) 365 set( __values 1 ) 366 elseif( NOT __var STREQUAL "PATH" ) 367 set( __obsolete 0 ) 368 if( __var MATCHES "^OBSOLETE_.*$" ) 369 string( REPLACE "OBSOLETE_" "" __var "${__var}" ) 370 set( __obsolete 1 ) 371 endif() 372 if( __var MATCHES "^ENV_.*$" ) 373 string( REPLACE "ENV_" "" __var "${__var}" ) 374 set( __value "$ENV{${__var}}" ) 375 elseif( DEFINED ${__var} ) 376 set( __value "${${__var}}" ) 377 else() 378 if( __values ) 379 set( __value "${__var}" ) 380 else() 381 set( __value "" ) 382 endif() 383 endif() 384 if( NOT "${__value}" STREQUAL "" ) 385 if( __test_path ) 386 if( EXISTS "${__value}" ) 387 set( ${var_name} "${__value}" ) 388 if( __obsolete ) 389 message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." ) 390 endif() 391 break() 392 endif() 393 else() 394 set( ${var_name} "${__value}" ) 395 if( __obsolete ) 396 message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." ) 397 endif() 398 break() 399 endif() 400 endif() 401 endif() 402 endforeach() 403 unset( __value ) 404 unset( __values ) 405 unset( __obsolete ) 406 endif() 407 unset( __test_path ) 408endmacro() 409 410macro( __DETECT_NATIVE_API_LEVEL _var _path ) 411 SET( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*$" ) 412 FILE( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" ) 413 if( NOT __apiFileContent ) 414 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." ) 415 endif() 416 string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" ) 417 unset( __apiFileContent ) 418 unset( __ndkApiLevelRegex ) 419endmacro() 420 421macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root ) 422 file( GLOB __gccExePath "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" ) 423 __LIST_FILTER( __gccExePath "bin/[.].*-gcc${TOOL_OS_SUFFIX}$" ) 424 list( LENGTH __gccExePath __gccExePathsCount ) 425 if( NOT __gccExePathsCount EQUAL 1 ) 426 message( WARNING "Could not uniquely determine machine name for compiler from ${_root}." ) 427 set( ${_var} "" ) 428 else() 429 get_filename_component( __gccExeName "${__gccExePath}" NAME_WE ) 430 string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" ) 431 endif() 432 unset( __gccExePath ) 433 unset( __gccExePathsCount ) 434 unset( __gccExeName ) 435endmacro() 436 437macro( __COPY_IF_DIFFERENT _source _destination ) 438 execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${_source}" "${_destination}" RESULT_VARIABLE __fileCopyProcess ) 439 if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${_destination}") 440 message( SEND_ERROR "Failed copying of ${_source} to the ${_destination}" ) 441 endif() 442 unset( __fileCopyProcess ) 443endmacro() 444 445 446# stl version: by default gnustl_static will be used 447set( ANDROID_USE_STLPORT FALSE CACHE BOOL "Experimental: use stlport_static instead of gnustl_static") 448mark_as_advanced( ANDROID_USE_STLPORT ) 449 450# fight against cygwin 451set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools") 452mark_as_advanced( ANDROID_FORBID_SYGWIN ) 453if( ANDROID_FORBID_SYGWIN ) 454 if( CYGWIN ) 455 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." ) 456 endif() 457 458 if( CMAKE_HOST_WIN32 ) 459 # remove cygwin from PATH 460 set( __new_path "$ENV{PATH}") 461 __LIST_FILTER( __new_path "cygwin" ) 462 set(ENV{PATH} "${__new_path}") 463 unset(__new_path) 464 endif() 465endif() 466 467# detect current host platform 468set( TOOL_OS_SUFFIX "" ) 469if( CMAKE_HOST_APPLE ) 470 set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86" ) 471elseif( CMAKE_HOST_WIN32 ) 472 set( ANDROID_NDK_HOST_SYSTEM_NAME "windows" ) 473 set( TOOL_OS_SUFFIX ".exe" ) 474elseif( CMAKE_HOST_UNIX ) 475 set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86" ) 476else() 477 message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" ) 478endif() 479 480# see if we have path to Android NDK 481# but only if the user hasn't tried to provide a standalone toolchain as an override. 482if( NOT ANDROID_STANDALONE_TOOLCHAIN ) 483 __INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK ) 484 # According to a Google engineer on the Android NDK mailing list, the semi-official/blessed environmental variable is ANDROID_NDK_ROOT, not ANDROID_NDK. 485 if ( NOT ANDROID_NDK ) 486 __INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK_ROOT ) 487 endif( NOT ANDROID_NDK ) 488endif( NOT ANDROID_STANDALONE_TOOLCHAIN ) 489 490if( NOT ANDROID_NDK ) 491 # see if we have path to Android standalone toolchain 492 __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN OBSOLETE_ANDROID_NDK_TOOLCHAIN_ROOT OBSOLETE_ENV_ANDROID_NDK_TOOLCHAIN_ROOT ) 493 494 if( NOT ANDROID_STANDALONE_TOOLCHAIN ) 495 #try to find Android NDK in one of the the default locations 496 set( __ndkSearchPaths ) 497 foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} ) 498 foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} ) 499 list( APPEND __ndkSearchPaths "${__ndkSearchPath}${suffix}" ) 500 endforeach() 501 endforeach() 502 __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} ) 503 unset( __ndkSearchPaths ) 504 505 if( ANDROID_NDK ) 506 message( STATUS "Using default path for Android NDK: ${ANDROID_NDK}" ) 507 message( STATUS " If you prefer to use a different location, please define a cmake or environment variable: ANDROID_NDK" ) 508 else() 509 #try to find Android standalone toolchain in one of the the default locations 510 __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH ) 511 512 if( ANDROID_STANDALONE_TOOLCHAIN ) 513 message( STATUS "Using default path for standalone toolchain ${ANDROID_STANDALONE_TOOLCHAIN}" ) 514 message( STATUS " If you prefer to use a different location, please define the variable: ANDROID_STANDALONE_TOOLCHAIN" ) 515 endif( ANDROID_STANDALONE_TOOLCHAIN ) 516 endif( ANDROID_NDK ) 517 endif( NOT ANDROID_STANDALONE_TOOLCHAIN ) 518endif( NOT ANDROID_NDK ) 519 520# remember found paths 521if( ANDROID_NDK ) 522 get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE ) 523 # try to detect change 524 if( CMAKE_AR ) 525 string( LENGTH "${ANDROID_NDK}" __length ) 526 string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) 527 if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK ) 528 message( FATAL_ERROR "It is not possible to change path to the NDK on subsequent run." ) 529 endif() 530 unset( __androidNdkPreviousPath ) 531 unset( __length ) 532 endif() 533 set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" ) 534 set( BUILD_WITH_ANDROID_NDK True ) 535elseif( ANDROID_STANDALONE_TOOLCHAIN ) 536 get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE ) 537 # try to detect change 538 if( CMAKE_AR ) 539 string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length ) 540 string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath ) 541 if( NOT __androidStandaloneToolchainPreviousPath STREQUAL ANDROID_STANDALONE_TOOLCHAIN ) 542 message( FATAL_ERROR "It is not possible to change path to the Android standalone toolchain on subsequent run." ) 543 endif() 544 unset( __androidStandaloneToolchainPreviousPath ) 545 unset( __length ) 546 endif() 547 set( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" CACHE INTERNAL "Path of the Android standalone toolchain" ) 548 set( BUILD_WITH_STANDALONE_TOOLCHAIN True ) 549else() 550 list(GET ANDROID_NDK_SEARCH_PATHS 0 ANDROID_NDK_SEARCH_PATH) 551 message( FATAL_ERROR "Could not find neither Android NDK nor Android standalone toolcahin. 552 You should either set an environment variable: 553 export ANDROID_NDK=~/my-android-ndk 554 or 555 export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain 556 or put the toolchain or NDK in the default path: 557 sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH} 558 sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" ) 559endif() 560 561# get all the details about standalone toolchain 562if( BUILD_WITH_STANDALONE_TOOLCHAIN ) 563 __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" ) 564 set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) 565 set( __availableToolchains "standalone" ) 566 __DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" ) 567 if( NOT __availableToolchainMachines ) 568 message( FATAL_ERROR "Could not determine machine name of your toolchain. Probably your Android standalone toolchain is broken." ) 569 endif() 570 if( __availableToolchainMachines MATCHES i686 ) 571 set( __availableToolchainArchs "x86" ) 572 elseif( __availableToolchainMachines MATCHES arm ) 573 set( __availableToolchainArchs "arm" ) 574 elseif( __availableToolchainMachines MATCHES mipsel ) 575 set( __availableToolchainArchs "mipsel" ) 576 endif() 577 if( ANDROID_COMPILER_VERSION ) 578 # do not run gcc every time because it is relatevely expencive 579 set( __availableToolchainCompilerVersions "${ANDROID_COMPILER_VERSION}" ) 580 else() 581 execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" --version 582 OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE ) 583 # arm-linux-androideabi-gcc (GCC) 4.6 20120106 (prerelease) 584 string( REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" ) 585 if( NOT __availableToolchainCompilerVersions ) 586 # arm-linux-androideabi-gcc (GCC) 4.8 587 execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" --version 588 OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE ) 589 string( REGEX MATCH "[0-9]+.[0-9]+" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" ) 590 endif() 591 endif() 592endif() 593 594# get all the details about NDK 595if( BUILD_WITH_ANDROID_NDK ) 596 file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" ) 597 string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" ) 598 file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" ) 599 __LIST_FILTER( __availableToolchains "^[.]" ) 600 set( __availableToolchainMachines "" ) 601 set( __availableToolchainArchs "" ) 602 set( __availableToolchainCompilerVersions "" ) 603 foreach( __toolchain ${__availableToolchains} ) 604 __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) 605 if( __machine ) 606 string( REGEX MATCH "[0-9]+[.][0-9]+[.]*[0-9]*$" __version "${__toolchain}" ) 607 string( REGEX MATCH "^[^-]+" __arch "${__toolchain}" ) 608 list( APPEND __availableToolchainMachines "${__machine}" ) 609 list( APPEND __availableToolchainArchs "${__arch}" ) 610 list( APPEND __availableToolchainCompilerVersions "${__version}" ) 611 else() 612 list( REMOVE_ITEM __availableToolchains "${__toolchain}" ) 613 endif() 614 endforeach() 615 if( NOT __availableToolchains ) 616 message( FATAL_ERROR "Could not any working toolchain in the NDK. Probably your Android NDK is broken." ) 617 endif() 618endif() 619 620# build list of available ABIs 621if( NOT ANDROID_SUPPORTED_ABIS ) 622 set( ANDROID_SUPPORTED_ABIS "" ) 623 set( __uniqToolchainArchNames ${__availableToolchainArchs} ) 624 list( REMOVE_DUPLICATES __uniqToolchainArchNames ) 625 list( SORT __uniqToolchainArchNames ) 626 foreach( __arch ${__uniqToolchainArchNames} ) 627 list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} ) 628 endforeach() 629 unset( __uniqToolchainArchNames ) 630 if( NOT ANDROID_SUPPORTED_ABIS ) 631 message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." ) 632 endif() 633endif() 634 635# choose target ABI 636__INIT_VARIABLE( ANDROID_ABI OBSOLETE_ARM_TARGET OBSOLETE_ARM_TARGETS VALUES ${ANDROID_SUPPORTED_ABIS} ) 637# verify that target ABI is supported 638list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx ) 639if( __androidAbiIdx EQUAL -1 ) 640 string( REPLACE ";" "\", \"", PRINTABLE_ANDROID_SUPPORTED_ABIS "${ANDROID_SUPPORTED_ABIS}" ) 641 message( FATAL_ERROR "Specified ANDROID_ABI = \"${ANDROID_ABI}\" is not supported by this cmake toolchain or your NDK/toolchain. 642 Supported values are: \"${PRINTABLE_ANDROID_SUPPORTED_ABIS}\" 643 " ) 644endif() 645unset( __androidAbiIdx ) 646 647# remember target ABI 648set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE ) 649 650# set target ABI options 651if( ANDROID_ABI STREQUAL "x86" ) 652 set( X86 true ) 653 set( ANDROID_NDK_ABI_NAME "x86" ) 654 set( ANDROID_ARCH_NAME "x86" ) 655 set( ANDROID_ARCH_FULLNAME "x86" ) 656 set( CMAKE_SYSTEM_PROCESSOR "i686" ) 657elseif( ANDROID_ABI STREQUAL "mips" ) 658 set( MIPS true ) 659 set( ANDROID_NDK_ABI_NAME "mips" ) 660 set( ANDROID_ARCH_NAME "mips" ) 661 set( ANDROID_ARCH_FULLNAME "mipsel" ) 662 set( CMAKE_SYSTEM_PROCESSOR "mips" ) 663elseif( ANDROID_ABI STREQUAL "armeabi" ) 664 set( ARMEABI true ) 665 set( ANDROID_NDK_ABI_NAME "armeabi" ) 666 set( ANDROID_ARCH_NAME "arm" ) 667 set( ANDROID_ARCH_FULLNAME "arm" ) 668 set( CMAKE_SYSTEM_PROCESSOR "armv5te" ) 669elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" ) 670 set( ARMEABI_V6 true ) 671 set( ANDROID_NDK_ABI_NAME "armeabi" ) 672 set( ANDROID_ARCH_NAME "arm" ) 673 set( ANDROID_ARCH_FULLNAME "arm" ) 674 set( CMAKE_SYSTEM_PROCESSOR "armv6" ) 675 # need always fallback to older platform 676 set( ARMEABI true ) 677elseif( ANDROID_ABI STREQUAL "armeabi-v7a") 678 set( ARMEABI_V7A true ) 679 set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) 680 set( ANDROID_ARCH_NAME "arm" ) 681 set( ANDROID_ARCH_FULLNAME "arm" ) 682 set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) 683elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" ) 684 set( ARMEABI_V7A true ) 685 set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) 686 set( ANDROID_ARCH_NAME "arm" ) 687 set( ANDROID_ARCH_FULLNAME "arm" ) 688 set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) 689 set( VFPV3 true ) 690elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" ) 691 set( ARMEABI_V7A true ) 692 set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) 693 set( ANDROID_ARCH_NAME "arm" ) 694 set( ANDROID_ARCH_FULLNAME "arm" ) 695 set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) 696 set( VFPV3 true ) 697 set( NEON true ) 698else() 699 message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." ) 700endif() 701 702if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" ) 703 # really dirty hack 704 # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run... 705 file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" ) 706endif() 707 708set( ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} CACHE INTERNAL "ANDROID_ABI can be changed only to one of these ABIs. Changing to any other ABI requires to reset cmake cache." ) 709if( CMAKE_VERSION VERSION_GREATER "2.8" ) 710 list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} ) 711 set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} ) 712endif() 713 714if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 ) 715 __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD OBSOLETE_FORCE_ARM VALUES OFF ) 716 set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE ) 717 mark_as_advanced( ANDROID_FORCE_ARM_BUILD ) 718else() 719 unset( ANDROID_FORCE_ARM_BUILD CACHE ) 720endif() 721 722# choose toolchain 723if( ANDROID_TOOLCHAIN_NAME ) 724 list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx ) 725 if( __toolchainIdx EQUAL -1 ) 726 message( FATAL_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing. You need to remove CMakeCache.txt and rerun cmake manually to change the toolchain" ) 727 endif() 728 list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch ) 729 if( NOT __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) 730 message( SEND_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." ) 731 endif() 732else() 733 set( __toolchainIdx -1 ) 734 set( __applicableToolchains "" ) 735 set( __toolchainMaxVersion "0.0.0" ) 736 list( LENGTH __availableToolchains __availableToolchainsCount ) 737 math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" ) 738 foreach( __idx RANGE ${__availableToolchainsCount} ) 739 list( GET __availableToolchainArchs ${__idx} __toolchainArch ) 740 if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) 741 list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion ) 742 if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion ) 743 set( __toolchainMaxVersion "${__toolchainVersion}" ) 744 set( __toolchainIdx ${__idx} ) 745 endif() 746 endif() 747 endforeach() 748 unset( __availableToolchainsCount ) 749 unset( __toolchainMaxVersion ) 750 unset( __toolchainVersion ) 751endif() 752unset( __toolchainArch ) 753if( __toolchainIdx EQUAL -1 ) 754 message( FATAL_ERROR "No one of available compiler toolchains is able to compile for ${ANDROID_ARCH_NAME} platform." ) 755endif() 756list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME ) 757list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME ) 758list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION ) 759set( ANDROID_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" CACHE INTERNAL "Name of toolchain used" ) 760set( ANDROID_COMPILER_VERSION "${ANDROID_COMPILER_VERSION}" CACHE INTERNAL "compiler version from selected toolchain" ) 761unset( __toolchainIdx ) 762unset( __availableToolchains ) 763unset( __availableToolchainMachines ) 764unset( __availableToolchainArchs ) 765unset( __availableToolchainCompilerVersions ) 766 767# choose native API level 768__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 ) 769string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" ) 770# validate 771list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx ) 772if( __levelIdx EQUAL -1 ) 773 message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." ) 774endif() 775unset( __levelIdx ) 776if( BUILD_WITH_ANDROID_NDK ) 777 __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" ) 778 if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL ) 779 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." ) 780 endif() 781 unset( __realApiLevel ) 782endif() 783set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE ) 784if( CMAKE_VERSION VERSION_GREATER "2.8" ) 785 list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS ) 786 set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) 787endif() 788 789# setup paths 790if( BUILD_WITH_STANDALONE_TOOLCHAIN ) 791 set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) 792 set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" ) 793 set( __stlLibPath "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" ) 794endif() 795if( BUILD_WITH_ANDROID_NDK ) 796 set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) 797 set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" ) 798 if( ANDROID_USE_STLPORT ) 799 set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" ) 800 set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}" ) 801 else() 802 if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" ) 803 set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/include" ) 804 set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}" ) 805 else() 806 set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/include" ) 807 set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}" ) 808 endif() 809 endif() 810endif() 811 812# specify the cross compiler 813set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" ) 814set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" ) 815set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "Assembler" ) 816if( CMAKE_VERSION VERSION_LESS 2.8.5 ) 817 set( CMAKE_ASM_COMPILER_ARG1 "-c" ) 818endif() 819# there may be a way to make cmake deduce these TODO deduce the rest of the tools 820set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" ) 821set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" ) 822set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" ) 823set( CMAKE_NM "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" ) 824set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" ) 825set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" ) 826set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" ) 827set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" ) 828if( APPLE ) 829 find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool ) 830 if( NOT CMAKE_INSTALL_NAME_TOOL ) 831 message( FATAL_ERROR "Could not find install_name_tool, please check your installation." ) 832 endif() 833 mark_as_advanced( CMAKE_INSTALL_NAME_TOOL ) 834endif() 835 836# export directories 837set( ANDROID_SYSTEM_INCLUDE_DIRS "" ) 838set( ANDROID_SYSTEM_LIB_DIRS "" ) 839 840# setup output directories 841set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) 842set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) 843 844if(NOT _CMAKE_IN_TRY_COMPILE) 845 if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" ) 846 set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" ) 847 else() 848 set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" ) 849 endif() 850 set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" ) 851endif() 852 853# includes 854list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_SYSROOT}/usr/include" ) 855if( __stlIncludePath AND EXISTS "${__stlIncludePath}" ) 856 list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${__stlIncludePath}" ) 857endif() 858 859# c++ bits includes 860if( __stlLibPath AND EXISTS "${__stlLibPath}/include" ) 861 list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${__stlLibPath}/include" ) 862endif() 863if( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/thumb/bits" ) 864 list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/thumb" ) 865elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" ) 866 list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" ) 867elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" ) 868 list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" ) 869elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/bits" ) 870 list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" ) 871endif() 872 873# flags and definitions 874if(ANDROID_SYSROOT MATCHES "[ ;\"]") 875 set( ANDROID_C_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) 876 set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) 877 # quotes will break try_compile and compiler identification 878 message(WARNING "Your Android system root has non-alphanumeric symbols. It can break compiler features detection and the whole build.") 879else() 880 set( ANDROID_C_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) 881 set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) 882endif() 883 884remove_definitions( -DANDROID ) 885add_definitions( -DANDROID ) 886 887# Force set compilers because standard identification works badly for us 888include( CMakeForceCompiler ) 889CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU ) 890set( CMAKE_C_PLATFORM_ID Linux ) 891set( CMAKE_C_SIZEOF_DATA_PTR 4 ) 892set( CMAKE_C_HAS_ISYSROOT 1 ) 893set( CMAKE_C_COMPILER_ABI ELF ) 894CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU ) 895set( CMAKE_CXX_PLATFORM_ID Linux ) 896set( CMAKE_CXX_SIZEOF_DATA_PTR 4 ) 897set( CMAKE_CXX_HAS_ISYSROOT 1 ) 898set( CMAKE_CXX_COMPILER_ABI ELF ) 899# force ASM compiler (required for CMake < 2.8.5) 900set( CMAKE_ASM_COMPILER_ID_RUN TRUE ) 901set( CMAKE_ASM_COMPILER_ID GNU ) 902set( CMAKE_ASM_COMPILER_WORKS TRUE ) 903set( CMAKE_ASM_COMPILER_FORCED TRUE ) 904set( CMAKE_COMPILER_IS_GNUASM 1) 905 906# NDK flags 907if( ARMEABI OR ARMEABI_V7A ) 908 # NDK also defines -ffunction-sections -funwind-tables but they result in worse OpenCV performance 909 set( _CMAKE_CXX_FLAGS "-fpic -fstack-protector -no-canonical-prefixes -Wa,--noexecstack" ) 910 set( _CMAKE_C_FLAGS "-fpic -fstack-protector -no-canonical-prefixes -Wa,--noexecstack" ) 911 remove_definitions( -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ ) 912 add_definitions( -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ ) 913 # extra arm-specific flags 914 # The default Android build process does not pass -fsigned-char. 915 # set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -fsigned-char" ) 916 # set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) 917elseif( X86 ) 918 set( _CMAKE_CXX_FLAGS "-no-canonical-prefixes -funwind-tables -fstack-protector -Wa,--noexecstack" ) 919 set( _CMAKE_C_FLAGS "-no-canonical-prefixes -funwind-tables -fstack-protector -Wa,--noexecstack" ) 920elseif( MIPS ) 921 set( _CMAKE_CXX_FLAGS "-fpic -Wno-psabi -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" ) 922 set( _CMAKE_C_FLAGS "-fpic -Wno-psabi -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" ) 923 # The default Android build process does not pass -fsigned-char. 924 # set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -fsigned-char" ) 925 # set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) 926else() 927 set( _CMAKE_CXX_FLAGS "" ) 928 set( _CMAKE_C_FLAGS "" ) 929endif() 930 931if( ANDROID_USE_STLPORT ) 932 set( _CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" ) 933 # set( _CMAKE_C_FLAGS "${_CMAKE_C_FLAGS}" ) 934else() 935 set( _CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS} -frtti -fexceptions" ) 936 # set( _CMAKE_C_FLAGS "${_CMAKE_C_FLAGS}" ) 937endif() 938 939# release and debug flags 940if( ARMEABI OR ARMEABI_V7A ) 941 if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 ) 942 # It is recommended to use the -mthumb compiler flag to force the generation 943 # of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones). 944 # O3 instead of O2/Os in release mode - like cmake sets for desktop gcc 945 # EW: Note that Android's normal build process uses 946 # -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 947 # and for debug, appends: -O0 -UNDEBUG -marm -fno-omit-frame-pointer 948 set( _CMAKE_CXX_FLAGS_RELEASE "-mthumb -O3 -finline-limit=64" ) 949 set( _CMAKE_C_FLAGS_RELEASE "-mthumb -O3 -finline-limit=64" ) 950 set( _CMAKE_CXX_FLAGS_DEBUG "-marm -O0 -g -finline-limit=64" ) 951 set( _CMAKE_C_FLAGS_DEBUG "-marm -O0 -g -finline-limit=64" ) 952 else() 953 # always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI 954 # O3 instead of O2/Os in release mode - like cmake sets for desktop gcc 955 set( _CMAKE_CXX_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" ) 956 set( _CMAKE_C_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" ) 957 set( _CMAKE_CXX_FLAGS_DEBUG "-marm -O0 -finline-limit=300" ) 958 set( _CMAKE_C_FLAGS_DEBUG "-marm -O0 -finline-limit=300" ) 959 endif() 960elseif( X86 ) 961 set( _CMAKE_CXX_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" ) 962 set( _CMAKE_C_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" ) 963 set( _CMAKE_CXX_FLAGS_DEBUG "-O0 -g -funswitch-loops -finline-limit=300" ) 964 set( _CMAKE_C_FLAGS_DEBUG "-O0 -g -funswitch-loops -finline-limit=300" ) 965elseif( MIPS ) 966 set( _CMAKE_CXX_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" ) 967 set( _CMAKE_C_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" ) 968 set( _CMAKE_CXX_FLAGS_DEBUG "-O0 -g" ) 969 set( _CMAKE_C_FLAGS_DEBUG "-O0 -g" ) 970endif() 971set( _CMAKE_CXX_FLAGS_RELEASE "${_CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" ) 972set( _CMAKE_C_FLAGS_RELEASE "${_CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" ) 973set( _CMAKE_CXX_FLAGS_DEBUG "${_CMAKE_CXX_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" ) 974set( _CMAKE_C_FLAGS_DEBUG "${_CMAKE_C_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" ) 975 976# ABI-specific flags 977if( ARMEABI_V7A ) 978 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -march=armv7-a -mfloat-abi=softfp" ) 979 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" ) 980 if( NEON ) 981 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -mfpu=neon" ) 982 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=neon" ) 983 elseif( VFPV3 ) 984 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -mfpu=vfpv3-d32" ) 985 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d32" ) 986 else() 987 # Default Android armv7 builds with -mfpu=vfpv3-d16. 988 # According to this: 989 # http://stackoverflow.com/questions/11831648/android-ndk-arm-build-settings-to-run-on-most-devices 990 # there was a bug in r7b which caused crashes. 991 # But r9 is the current as of this writing so developers really need to upgrade their ndk. 992 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -mfpu=vfpv3-d16" ) 993 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" ) 994 endif() 995elseif( ARMEABI_V6 ) 996 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) 997 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) 998elseif( ARMEABI ) 999 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) 1000 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) 1001elseif( X86 ) 1002 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS}" )#sse? 1003 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" )#sse? 1004endif() 1005 1006# linker flags 1007if( NOT DEFINED __ndklibspath ) 1008 set( __ndklibspath "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/ndklibs/${ANDROID_NDK_ABI_NAME}" ) 1009endif() 1010list( APPEND ANDROID_SYSTEM_LIB_DIRS "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ) 1011set( ANDROID_LINKER_FLAGS "" ) 1012 1013# STL 1014if( ANDROID_USE_STLPORT ) 1015 if( EXISTS "${__stlLibPath}/libstlport_static.a" ) 1016 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> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> \"${__stlLibPath}/libstlport_static.a\"") 1017 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> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> \"${__stlLibPath}/libstlport_static.a\"") 1018 endif() 1019else( ANDROID_USE_STLPORT ) 1020 if( EXISTS "${__stlLibPath}/libgnustl_static.a" ) 1021 __COPY_IF_DIFFERENT( "${__stlLibPath}/libgnustl_static.a" "${__ndklibspath}/libstdc++.a" ) 1022 elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" ) 1023 __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) 1024 elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" ) 1025 __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) 1026 elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/thumb/libstdc++.a" ) 1027 __COPY_IF_DIFFERENT( "${__stlLibPath}/thumb/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) 1028 elseif( EXISTS "${__stlLibPath}/libstdc++.a" ) 1029 __COPY_IF_DIFFERENT( "${__stlLibPath}/libstdc++.a" "${__ndklibspath}/libstdc++.a" ) 1030 endif() 1031 if( EXISTS "${__stlLibPath}/libsupc++.a" ) 1032 __COPY_IF_DIFFERENT( "${__stlLibPath}/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) 1033 elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" ) 1034 __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) 1035 elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" ) 1036 __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) 1037 elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" ) 1038 __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) 1039 elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" ) 1040 __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" "${__ndklibspath}/libsupc++.a" ) 1041 endif() 1042 list( APPEND ANDROID_SYSTEM_LIB_DIRS "${__ndklibspath}" ) 1043endif( ANDROID_USE_STLPORT ) 1044 1045# cleanup for STL search 1046unset( __stlIncludePath ) 1047unset( __stlLibPath ) 1048 1049# other linker flags 1050__INIT_VARIABLE( ANDROID_NO_UNDEFINED OBSOLETE_NO_UNDEFINED VALUES ON ) 1051set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" FORCE ) 1052mark_as_advanced( ANDROID_NO_UNDEFINED ) 1053if( ANDROID_NO_UNDEFINED ) 1054 set( ANDROID_LINKER_FLAGS "-Wl,--no-undefined ${ANDROID_LINKER_FLAGS}" ) 1055endif() 1056 1057if (ANDROID_NDK MATCHES "-r[56].?$") 1058 # libGLESv2.so in NDK's prior to r7 refers to exteranal symbols. So this flag option is required for all projects using OpenGL from native. 1059 __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES ON ) 1060else() 1061 __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF ) 1062endif() 1063 1064set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE ) 1065mark_as_advanced( ANDROID_SO_UNDEFINED ) 1066if( ANDROID_SO_UNDEFINED ) 1067 set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" ) 1068endif() 1069 1070# Android by default passes --function-sections for C and C++ but does not pass -fdata-sections. 1071# Android also does not pass -Wl,--gc-sections 1072__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON ) 1073set( ANDROID_FUNCTION_LEVEL_LINKING ON CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE ) 1074mark_as_advanced( ANDROID_FUNCTION_LEVEL_LINKING ) 1075if( ANDROID_FUNCTION_LEVEL_LINKING ) 1076 set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS} -fdata-sections -ffunction-sections" ) 1077 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" ) 1078 set( ANDROID_LINKER_FLAGS "-Wl,--gc-sections ${ANDROID_LINKER_FLAGS}" ) 1079endif() 1080 1081if( ARMEABI_V7A ) 1082 # this is *required* to use the following linker flags that routes around 1083 # a CPU bug in some Cortex-A8 implementations: 1084 # set( ANDROID_LINKER_FLAGS "-Wl,--fix-cortex-a8 ${ANDROID_LINKER_FLAGS}" ) 1085 # Android passes all this stuff by default. 1086 set( ANDROID_LINKER_FLAGS "-no-canonical-prefixes -march=armv7-a -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${ANDROID_LINKER_FLAGS} -lc -lm" ) 1087elseif( ARMEABI ) 1088 set( ANDROID_LINKER_FLAGS "-no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${ANDROID_LINKER_FLAGS} -lc -lm" ) 1089elseif ( X86 ) 1090 set( ANDROID_LINKER_FLAGS "-no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${ANDROID_LINKER_FLAGS} -lc -lm" ) 1091endif() 1092 1093# cache flags 1094set( CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags" ) 1095set( CMAKE_C_FLAGS "${_CMAKE_C_FLAGS}" CACHE STRING "c flags" ) 1096set( CMAKE_CXX_FLAGS_RELEASE "${_CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c++ Release flags" ) 1097set( CMAKE_C_FLAGS_RELEASE "${_CMAKE_C_FLAGS_RELEASE}" CACHE STRING "c Release flags" ) 1098set( CMAKE_CXX_FLAGS_DEBUG "${_CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c++ Debug flags" ) 1099set( CMAKE_C_FLAGS_DEBUG "${_CMAKE_C_FLAGS_DEBUG}" CACHE STRING "c Debug flags" ) 1100set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "linker flags" ) 1101set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "linker flags" ) 1102set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "linker flags" ) 1103 1104include_directories( SYSTEM ${ANDROID_SYSTEM_INCLUDE_DIRS} ) 1105link_directories( ${ANDROID_SYSTEM_LIB_DIRS} ) 1106 1107# finish flags 1108set( ANDROID_C_FLAGS "${ANDROID_C_FLAGS}" CACHE INTERNAL "Extra Android C compiler flags") 1109set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Extra Android C++ compiler flags") 1110set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Extra Android linker flags") 1111set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" ) 1112set( CMAKE_C_FLAGS "${ANDROID_C_FLAGS} ${CMAKE_C_FLAGS}" ) 1113if( MIPS AND BUILD_WITH_ANDROID_NDK ) 1114 set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" ) 1115 set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" ) 1116 set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.x ${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) 1117else() 1118 set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" ) 1119 set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" ) 1120 set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) 1121endif() 1122 1123# set these global flags for cmake client scripts to change behavior 1124set( ANDROID True ) 1125set( BUILD_ANDROID True ) 1126 1127# where is the target environment 1128set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" "${CMAKE_FIND_ROOT_PATH}" ) 1129 1130# only search for libraries and includes in the ndk toolchain 1131set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) 1132set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) 1133set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) 1134 1135 1136# macro to find packages on the host OS 1137macro( find_host_package ) 1138 set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) 1139 set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER ) 1140 set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER ) 1141 if( CMAKE_HOST_WIN32 ) 1142 SET( WIN32 1 ) 1143 SET( UNIX ) 1144 elseif( CMAKE_HOST_APPLE ) 1145 SET( APPLE 1 ) 1146 SET( UNIX ) 1147 endif() 1148 find_package( ${ARGN} ) 1149 SET( WIN32 ) 1150 SET( APPLE ) 1151 SET( UNIX 1 ) 1152 set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) 1153 set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) 1154 set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) 1155endmacro() 1156 1157 1158# macro to find programs on the host OS 1159macro( find_host_program ) 1160 set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) 1161 set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER ) 1162 set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER ) 1163 if( CMAKE_HOST_WIN32 ) 1164 SET( WIN32 1 ) 1165 SET( UNIX ) 1166 elseif( CMAKE_HOST_APPLE ) 1167 SET( APPLE 1 ) 1168 SET( UNIX ) 1169 endif() 1170 find_program( ${ARGN} ) 1171 SET( WIN32 ) 1172 SET( APPLE ) 1173 SET( UNIX 1 ) 1174 set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) 1175 set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) 1176 set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) 1177endmacro() 1178 1179 1180macro( ANDROID_GET_ABI_RAWNAME TOOLCHAIN_FLAG VAR ) 1181 if( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI" ) 1182 set( ${VAR} "armeabi" ) 1183 elseif( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI_V7A" ) 1184 set( ${VAR} "armeabi-v7a" ) 1185 elseif( "${TOOLCHAIN_FLAG}" STREQUAL "X86" ) 1186 set( ${VAR} "x86" ) 1187 else() 1188 set( ${VAR} "unknown" ) 1189 endif() 1190endmacro() 1191 1192 1193# export toolchain settings for the try_compile() command 1194if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) 1195 set( __toolchain_config "") 1196 foreach( __var ANDROID_ABI ANDROID_FORCE_ARM_BUILD ANDROID_NATIVE_API_LEVEL ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_SET_OBSOLETE_VARIABLES LIBRARY_OUTPUT_PATH_ROOT ANDROID_USE_STLPORT ANDROID_FORBID_SYGWIN ANDROID_NDK ANDROID_STANDALONE_TOOLCHAIN ANDROID_FUNCTION_LEVEL_LINKING __ndklibspath ) 1197 if( DEFINED ${__var} ) 1198 if( "${__var}" MATCHES " ") 1199 set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" ) 1200 else() 1201 set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" ) 1202 endif() 1203 endif() 1204 endforeach() 1205 file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" ) 1206 unset( __toolchain_config ) 1207 unset( __ndklibspath ) 1208endif() 1209 1210 1211# set some obsolete variables for backward compatibility 1212set( ANDROID_SET_OBSOLETE_VARIABLES ON CACHE BOOL "Define obsolete Andrid-specific cmake variables" ) 1213mark_as_advanced( ANDROID_SET_OBSOLETE_VARIABLES ) 1214if( ANDROID_SET_OBSOLETE_VARIABLES ) 1215 set( ANDROID_API_LEVEL ${ANDROID_NATIVE_API_LEVEL} ) 1216 set( ARM_TARGET "${ANDROID_ABI}" ) 1217 set( ARMEABI_NDK_NAME "${ANDROID_NDK_ABI_NAME}" ) 1218endif() 1219 1220 1221# Variables controlling behavior or set by cmake toolchain: 1222# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips" 1223# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version) 1224# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF 1225# ANDROID_USE_STLPORT : OFF/ON - EXPERIMENTAL!!! 1226# ANDROID_FORBID_SYGWIN : ON/OFF 1227# ANDROID_NO_UNDEFINED : ON/OFF 1228# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version) 1229# ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF 1230# Variables that takes effect only at first run: 1231# ANDROID_FORCE_ARM_BUILD : ON/OFF 1232# LIBRARY_OUTPUT_PATH_ROOT : <any valid path> 1233# Can be set only at the first run: 1234# ANDROID_NDK 1235# ANDROID_STANDALONE_TOOLCHAIN 1236# ANDROID_TOOLCHAIN_NAME : "arm-linux-androideabi-4.4.3" or "arm-linux-androideabi-4.6" or "mipsel-linux-android-4.4.3" or "mipsel-linux-android-4.6" or "x86-4.4.3" or "x86-4.6" 1237# Obsolete: 1238# ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL 1239# ARM_TARGET : superseded by ANDROID_ABI 1240# ARM_TARGETS : superseded by ANDROID_ABI (can be set only) 1241# ANDROID_NDK_TOOLCHAIN_ROOT : superseded by ANDROID_STANDALONE_TOOLCHAIN (can be set only) 1242# ANDROID_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL (completely removed) 1243# 1244# Primary read-only variables: 1245# ANDROID : always TRUE 1246# ARMEABI : TRUE for arm v6 and older devices 1247# ARMEABI_V6 : TRUE for arm v6 1248# ARMEABI_V7A : TRUE for arm v7a 1249# NEON : TRUE if NEON unit is enabled 1250# VFPV3 : TRUE if VFP version 3 is enabled 1251# X86 : TRUE if configured for x86 1252# BUILD_ANDROID : always TRUE 1253# BUILD_WITH_ANDROID_NDK : TRUE if NDK is used 1254# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used 1255# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform 1256# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a" or "x86" depending on ANDROID_ABI 1257# ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI 1258# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform 1259# ANDROID_SYSROOT : path to the compiler sysroot 1260# ANDROID_SYSTEM_INCLUDE_DIRS 1261# ANDROID_SYSTEM_LIB_DIRS 1262# Obsolete: 1263# ARMEABI_NDK_NAME : superseded by ANDROID_NDK_ABI_NAME 1264# 1265# Secondary (less stable) read-only variables: 1266# ANDROID_COMPILER_VERSION : GCC version used 1267# ANDROID_C_FLAGS : C compiler flags required by Android platform 1268# ANDROID_CXX_FLAGS : C++ compiler flags required by Android platform 1269# ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI 1270# ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux" 1271# ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK) 1272# ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK 1273# 1274# Defaults: 1275# ANDROID_DEFAULT_NDK_API_LEVEL 1276# ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH} 1277# ANDROID_NDK_SEARCH_PATHS 1278# ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH 1279# ANDROID_SUPPORTED_ABIS_${ARCH} 1280# ANDROID_SUPPORTED_NDK_VERSIONS