# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This is a toolchain file for cross-compiling for Android, and the # configuration refers to the open-source resposity: # https://github.com/taka-no-me/android-cmake # Most of the variables are compatible with that used in # https://developer.android.com/ndk/guides/cmake.html # The supported variables are listed belows: # # ANDROID_STANDALONE_TOOLCHAIN # ANDROID_TOOLCHAIN # ANDROID_ABI # ANDROID_NATIVE_API_LEVEL # ANDROID_ARM_MODE # ANDROID_ARM_NEON # # For CMake >= 3.7.0, all the settings will be delivered to CMake system # variables to let CMake do the cross-compiling configurations itself. # More detail of cross-compiling settings # https://cmake.org/cmake/help/v3.7/manual/cmake-toolchains.7.html IF(NOT ANDROID) return() ENDIF() # check the exist of android standalone toolchain IF(NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN) SET(ANDROID_STANDALONE_TOOLCHAIN $ENV{ANDROID_STANDALONE_TOOLCHAIN} CACHE PATH "Folder holds the standalone toolchain of Android NDK") ENDIF() IF(NOT ANDROID_STANDALONE_TOOLCHAIN) MESSAGE(WARNING "It is recommended to set ANDROID_STANDALONE_TOOLCHAIN to " "use a standalone toolchain.\n" "To cross-compile for Android, you need to:\n" "1. Download an Android NDK from" " https://developer.android.com/ndk/downloads/index.html\n" "2. Setup a standalone toolchain" "https://developer.android.google.cn/ndk/guides/standalone_toolchain.html?hl=zh-cn\n") ENDIF() IF(NOT DEFINED CMAKE_SYSTEM_VERSION AND ANDROID_NATIVE_API_LEVEL) IF(ANDROID_NATIVE_API_LEVEL MATCHES "^android-[0-9]+$") STRING(REPLACE "android-" "" CMAKE_SYSTEM_VERSION "${CMAKE_MATCH_0}") ELSEIF(ANDROID_NATIVE_API_LEVEL MATCHES "^[0-9]+$") SET(CMAKE_SYSTEM_VERSION ${ANDROID_NATIVE_API_LEVEL}) ENDIF() ENDIF() IF(NOT DEFINED ANDROID_TOOLCHAIN) SET(ANDROID_TOOLCHAIN clang) ENDIF() IF(NOT DEFINED ANDROID_ABI) SET(ANDROID_ABI "armeabi-v7a") ENDIF() IF(NOT DEFINED ANDROID_ARM_MODE) SET(ANDROID_ARM_MODE ON) ENDIF() IF(ANDROID_ARM_MODE) SET(ANDROID_ARM_MODE_NAME "arm") ELSE(ANDROID_ARM_MODE) SET(ANDROID_ARM_MODE_NAME "thumb") ENDIF(ANDROID_ARM_MODE) IF(NOT DEFINED ANDROID_ARM_NEON) SET(ANDROID_ARM_NEON ON) ENDIF() IF("${CMAKE_VERSION}" VERSION_LESS "3.7.0") IF("${CMAKE_VERSION}" VERSION_LESS "3.1.0") SET(CMAKE_SYSTEM_NAME "Linux") ENDIF() MESSAGE(WARNING "It is recommended to use CMake >= 3.7.0 (current version: " "${CMAKE_VERSION}), when cross-compiling for Android.") IF(ANDROID_STANDALONE_TOOLCHAIN) # Use standalone toolchain SET(CMAKE_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot") IF(NOT CMAKE_SYSTEM_VERSION) SET(ANDROID_STANDALONE_TOOLCHAIN_API "") SET(ANDROID_API_LEVEL_H_REGEX "^[\t ]*#[\t ]*define[\t ]+__ANDROID_API__[\t ]+([0-9]+)") FILE(STRINGS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" ANDROID_API_LEVEL_H_CONTENT REGEX "${ANDROID_API_LEVEL_H_REGEX}") IF(ANDROID_API_LEVEL_H_CONTENT MATCHES "${ANDROID_API_LEVEL_H_REGEX}") SET(ANDROID_STANDALONE_TOOLCHAIN_API "${CMAKE_MATCH_1}") ENDIF() SET(CMAKE_SYSTEM_VERSION ${ANDROID_STANDALONE_TOOLCHAIN_API}) ENDIF() # Toolchain SET(ANDROID_TOOLCHAIN_ROOT ${ANDROID_STANDALONE_TOOLCHAIN}) ELSE(ANDROID_NDK) # TODO: use android ndk ENDIF() IF(ANDROID_ABI MATCHES "^armeabi(-v7a)?$") SET(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi) IF(ANDROID_ABI STREQUAL "armeabi") SET(CMAKE_SYSTEM_PROCESSOR armv5te) SET(ANDROID_CLANG_TRIPLE armv5te-none-linux-androideabi) ELSEIF(ANDROID_ABI STREQUAL "armeabi-v7a") SET(CMAKE_SYSTEM_PROCESSOR armv7-a) SET(ANDROID_CLANG_TRIPLE armv7-none-linux-androideabi) ENDIF() ELSEIF(ANDROID_ABI STREQUAL "arm64-v8a") SET(ANDROID_TOOLCHAIN_NAME aarch64-linux-android) SET(CMAKE_SYSTEM_PROCESSOR aarch64) SET(ANDROID_CLANG_TRIPLE aarch64-none-linux-android) ELSE() MESSAGE(FATAL_ERROR "Invalid Android ABI: ${ANDROID_ABI}.") ENDIF() SET(ANDROID_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_NAME}-") IF(ANDROID_TOOLCHAIN STREQUAL clang) SET(ANDROID_C_COMPILER_NAME clang) SET(ANDROID_CXX_COMPILER_NAME clang++) SET(CMAKE_C_COMPILER_TARGET ${ANDROID_CLANG_TRIPLE}) SET(CMAKE_CXX_COMPILER_TARGET ${ANDROID_CLANG_TRIPLE}) ELSEIF(ANDROID_TOOLCHAIN STREQUAL gcc) SET(ANDROID_C_COMPILER_NAME gcc) SET(ANDROID_CXX_COMPILER_NAME g++) ELSE() MESSAGE(FATAL_ERROR "Invalid Android toolchain: ${ANDROID_TOOLCHAIN}") ENDIF() # C compiler IF(NOT CMAKE_C_COMPILER) SET(ANDROID_C_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}${ANDROID_C_COMPILER_NAME}") ELSE() GET_FILENAME_COMPONENT(ANDROID_C_COMPILER ${CMAKE_C_COMPILER} PROGRAM) ENDIF() IF(NOT EXISTS ${ANDROID_C_COMPILER}) MESSAGE(FATAL_ERROR "Cannot find C compiler: ${ANDROID_C_COMPILER}") ENDIF() # CXX compiler IF(NOT CMAKE_CXX_COMPILER) SET(ANDROID_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}${ANDROID_CXX_COMPILER_NAME}") ELSE() GET_FILENAME_COMPONENT(ANDROID_CXX_COMPILER ${CMAKE_CXX_COMPILER} PROGRAM) ENDIF() IF(NOT EXISTS ${ANDROID_CXX_COMPILER}) MESSAGE(FATAL_ERROR "Cannot find CXX compiler: ${ANDROID_CXX_COMPILER}") ENDIF() SET(CMAKE_C_COMPILER ${ANDROID_C_COMPILER} CACHE PATH "C compiler" FORCE) SET(CMAKE_CXX_COMPILER ${ANDROID_CXX_COMPILER} CACHE PATH "CXX compiler" FORCE) # Toolchain and ABI specific flags. SET(ANDROID_COMPILER_FLAGS "-ffunction-sections -fdata-sections") SET(ANDROID_LINKER_FLAGS "-Wl,--gc-sections") IF(ANDROID_ABI STREQUAL "armeabi") LIST(APPEND ANDROID_COMPILER_FLAGS -march=armv5te -mtune=xscale -msoft-float) ELSEIF(ANDROID_ABI STREQUAL "armeabi-v7a") LIST(APPEND ANDROID_COMPILER_FLAGS -march=armv7-a -mfloat-abi=softfp) IF(ANDROID_ARM_NEON) LIST(APPEND ANDROID_COMPILER_FLAGS -mfpu=neon) ELSE() LIST(APPEND ANDROID_COMPILER_FLAGS -mfpu=vfpv3-d16) ENDIF() LIST(APPEND ANDROID_LINKER_FLAGS -Wl,--fix-cortex-a8) ELSEIF(ANDROID_ABI STREQUAL "arm64-v8a") LIST(APPEND ANDROID_COMPILER_FLAGS -march=armv8-a) ENDIF() IF(ANDROID_ABI MATCHES "^armeabi(-v7a)?$") IF(ANDROID_ARM_MODE) LIST(APPEND ANDROID_COMPILER_FLAGS -marm) ELSE() LIST(APPEND ANDROID_COMPILER_FLAGS -mthumb) ENDIF() IF(ANDROID_TOOLCHAIN STREQUAL clang) # Disable integrated-as for better compatibility. LIST(APPEND ANDROID_COMPILER_FLAGS -fno-integrated-as) ENDIF() ENDIF() IF(ANDROID_TOOLCHAIN STREQUAL clang) # CMake automatically forwards all compiler flags to the linker, # and clang doesn't like having -Wa flags being used for linking. # To prevent CMake from doing this would require meddling with # the CMAKE__COMPILE_OBJECT rules, which would get quite messy. LIST(APPEND ANDROID_LINKER_FLAGS -Qunused-arguments) ENDIF() STRING(REPLACE ";" " " ANDROID_COMPILER_FLAGS "${ANDROID_COMPILER_FLAGS}") STRING(REPLACE ";" " " ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}") SET(CMAKE_C_FLAGS "${ANDROID_COMPILER_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "C flags") SET(CMAKE_CXX_FLAGS "${ANDROID_COMPILER_FLAGS} ${CMAKE_CXX_FLAGS}" CACHE STRING "CXX flags") SET(CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" CACHE STRING "shared linker flags") SET(CMAKE_POSITION_INDEPENDENT_CODE TRUE) SET(CMAKE_EXE_LINKER_FLAGS "-pie -fPIE ${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "executable linker flags") MESSAGE(STATUS "Android: Targeting API '${CMAKE_SYSTEM_VERSION}' " "with architecture '${ANDROID_ARM_MODE_NAME}', " "ABI '${ANDROID_ABI}', and processor '${CMAKE_SYSTEM_PROCESSOR}'") MESSAGE(STATUS "System CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS}) MESSAGE(STATUS "System CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS}) ELSE() IF(ANDROID_STANDALONE_TOOLCHAIN) SET(CMAKE_ANDROID_STANDALONE_TOOLCHAIN ${ANDROID_STANDALONE_TOOLCHAIN}) ENDIF() SET(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI}) IF(ANDROID_ABI MATCHES "^armeabi(-v7a)?$") SET(CMAKE_ANDROID_ARM_MODE ${ANDROID_ARM_MODE}) IF(ANDROID_ABI STREQUAL "armeabi-v7a") SET(CMAKE_ANDROID_ARM_NEON ${ANDROID_ARM_NEON}) ENDIF() ENDIF() ENDIF()