OpenCVDetectAndroidSDK.cmake 6.7 KB
Newer Older
1 2 3 4
if(EXISTS "${ANDROID_EXECUTABLE}")
  set(ANDROID_SDK_DETECT_QUIET TRUE)
endif()

A
Andrey Kamaev 已提交
5
file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH)
6
file(TO_CMAKE_PATH "$ENV{HOME}" HOME_ENV_PATH)
A
Andrey Kamaev 已提交
7

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
if(CMAKE_HOST_WIN32)
  set(ANDROID_SDK_OS windows)
elseif(CMAKE_HOST_APPLE)
  set(ANDROID_SDK_OS mac)
else()
  set(ANDROID_SDK_OS linux)
endif()

#find android SDK: search in ANDROID_SDK first
find_host_program(ANDROID_EXECUTABLE
  NAMES android.bat android
  PATH_SUFFIXES tools
  PATHS
    ENV ANDROID_SDK
  DOC "Android SDK location"
  NO_DEFAULT_PATH
  )

# Now search default paths
A
Andrey Kamaev 已提交
27 28
find_host_program(ANDROID_EXECUTABLE
  NAMES android.bat android
29 30 31 32 33 34 35 36 37
  PATH_SUFFIXES android-sdk-${ANDROID_SDK_OS}/tools
                android-sdk-${ANDROID_SDK_OS}_x86/tools
                android-sdk-${ANDROID_SDK_OS}_86/tools
                android-sdk/tools
  PATHS /opt
        "${HOME_ENV_PATH}/NVPACK"
        "$ENV{SystemDrive}/NVPACK"
        "${ProgramFiles_ENV_PATH}/Android"
  DOC "Android SDK location"
A
Andrey Kamaev 已提交
38 39 40
  )

if(ANDROID_EXECUTABLE)
41 42 43 44
  if(NOT ANDROID_SDK_DETECT_QUIET)
    message(STATUS "    Found android tool: ${ANDROID_EXECUTABLE}")
  endif()

A
Andrey Kamaev 已提交
45 46 47 48 49 50 51 52 53 54 55
  get_filename_component(ANDROID_SDK_TOOLS_PATH "${ANDROID_EXECUTABLE}" PATH)

  #read source.properties
  if(EXISTS "${ANDROID_SDK_TOOLS_PATH}/source.properties")
    file(STRINGS "${ANDROID_SDK_TOOLS_PATH}/source.properties" ANDROID_SDK_TOOLS_SOURCE_PROPERTIES_LINES REGEX "^[ ]*[^#].*$")
    foreach(line ${ANDROID_SDK_TOOLS_SOURCE_PROPERTIES_LINES})
      string(REPLACE "\\:" ":" line ${line})
      string(REPLACE "=" ";" line ${line})
      list(GET line 0 line_name)
      list(GET line 1 line_value)
      string(REPLACE "." "_" line_name ${line_name})
56
      SET(ANDROID_TOOLS_${line_name} "${line_value}" CACHE INTERNAL "from ${ANDROID_SDK_TOOLS_PATH}/source.properties")
A
Andrey Kamaev 已提交
57 58 59 60
      MARK_AS_ADVANCED(ANDROID_TOOLS_${line_name})
    endforeach()
  endif()

61
  #fix missing revision (SDK tools before r9 don't set revision number correctly)
A
Andrey Kamaev 已提交
62
  if(NOT ANDROID_TOOLS_Pkg_Revision)
63
    SET(ANDROID_TOOLS_Pkg_Revision "Unknown" CACHE INTERNAL "")
A
Andrey Kamaev 已提交
64 65 66
    MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Revision)
  endif()

67
  #fix missing description
A
Andrey Kamaev 已提交
68
  if(NOT ANDROID_TOOLS_Pkg_Desc)
69
    SET(ANDROID_TOOLS_Pkg_Desc "Android SDK Tools, revision ${ANDROID_TOOLS_Pkg_Revision}." CACHE INTERNAL "")
A
Andrey Kamaev 已提交
70 71 72
    MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Desc)
  endif()

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
  #warn about outdated SDK
  if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 13)
    SET(ANDROID_TOOLS_Pkg_Desc "${ANDROID_TOOLS_Pkg_Desc} It is recommended to update your SDK tools to revision 14 or newer." CACHE INTERNAL "")
  endif()

  if(ANDROID_TOOLS_Pkg_Revision GREATER 13)
    SET(ANDROID_PROJECT_PROPERTIES_FILE project.properties)
    SET(ANDROID_ANT_PROPERTIES_FILE ant.properties)
  else()
    SET(ANDROID_PROJECT_PROPERTIES_FILE default.properties)
    SET(ANDROID_ANT_PROPERTIES_FILE build.properties)
  endif()

  set(ANDROID_MANIFEST_FILE AndroidManifest.xml)
  set(ANDROID_LIB_PROJECT_FILES build.xml local.properties proguard-project.txt ${ANDROID_PROJECT_PROPERTIES_FILE})
  set(ANDROID_PROJECT_FILES ${ANDROID_ANT_PROPERTIES_FILE} ${ANDROID_LIB_PROJECT_FILES})

A
Andrey Kamaev 已提交
90
  #get installed targets
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
  if(ANDROID_TOOLS_Pkg_Revision GREATER 11)
    execute_process(COMMAND ${ANDROID_EXECUTABLE} list target -c
      RESULT_VARIABLE ANDROID_PROCESS
      OUTPUT_VARIABLE ANDROID_SDK_TARGETS
      ERROR_VARIABLE ANDROID_PROCESS_ERRORS
      OUTPUT_STRIP_TRAILING_WHITESPACE
      )
    string(REGEX MATCHALL "[^\n]+" ANDROID_SDK_TARGETS "${ANDROID_SDK_TARGETS}")
  else()
    #old SDKs (r11 and older) don't provide compact list
    execute_process(COMMAND ${ANDROID_EXECUTABLE} list target
      RESULT_VARIABLE ANDROID_PROCESS
      OUTPUT_VARIABLE ANDROID_SDK_TARGETS_FULL
      ERROR_VARIABLE ANDROID_PROCESS_ERRORS
      OUTPUT_STRIP_TRAILING_WHITESPACE
      )
    string(REGEX MATCHALL "(^|\n)id: [0-9]+ or \"([^\n]+[0-9+])\"(\n|$)" ANDROID_SDK_TARGETS_FULL "${ANDROID_SDK_TARGETS_FULL}")

    SET(ANDROID_SDK_TARGETS "")
    if(ANDROID_PROCESS EQUAL 0)
      foreach(line ${ANDROID_SDK_TARGETS_FULL})
        string(REGEX REPLACE "(^|\n)id: [0-9]+ or \"([^\n]+[0-9+])\"(\n|$)" "\\2" line "${line}")
        list(APPEND ANDROID_SDK_TARGETS "${line}")
      endforeach()
    endif()
  endif()

  if(NOT ANDROID_PROCESS EQUAL 0)
    message(ERROR "Failed to get list of installed Android targets.")
    set(ANDROID_EXECUTABLE "ANDROID_EXECUTABLE-NOTFOUND")
A
Andrey Kamaev 已提交
121 122 123
  endif()

  # detect ANDROID_SDK_TARGET if no target is provided by user
124
  #TODO: remove this block
A
Andrey Kamaev 已提交
125 126
  if(NOT ANDROID_SDK_TARGET)
    set(desired_android_target_level ${ANDROID_NATIVE_API_LEVEL})
127 128
    if(desired_android_target_level LESS 11)
      set(desired_android_target_level 11)
A
Andrey Kamaev 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
    endif()
    if(ANDROID_PROCESS EQUAL 0)
      math(EXPR desired_android_target_level_1 "${desired_android_target_level}-1")

      foreach(target ${ANDROID_SDK_TARGETS})
        string(REGEX MATCH "[0-9]+$" target_level "${target}")
        if(target_level GREATER desired_android_target_level_1)
          set(ANDROID_SDK_TARGET "${target}")
          break()
        endif()
      endforeach()
    else()
      set(ANDROID_SDK_TARGET android-${desired_android_target_level})
      message(WARNING "Could not retrieve list of installed Android targets. Will try to use \"${ANDROID_SDK_TARGET}\" target")
    endif()
  endif(NOT ANDROID_SDK_TARGET)

  SET(ANDROID_SDK_TARGET "${ANDROID_SDK_TARGET}" CACHE STRING "SDK target for Android tests and samples")
  string(REGEX MATCH "[0-9]+$" ANDROID_SDK_TARGET_LEVEL "${ANDROID_SDK_TARGET}")
endif(ANDROID_EXECUTABLE)
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

# finds minimal installed SDK target compatible with provided names or API levels
# usage:
#   get_compatible_android_api_level(VARIABLE [level1] [level2] ...)
macro(android_get_compatible_target VAR)
  set(${VAR} "${VAR}-NOTFOUND")
  if(ANDROID_SDK_TARGETS)
    list(GET ANDROID_SDK_TARGETS 1 __lvl)
    string(REGEX MATCH "[0-9]+$" __lvl "${__lvl}")

    #find minimal level mathing to all provided levels
    foreach(lvl ${ARGN})
      string(REGEX MATCH "[0-9]+$" __level "${lvl}")
      if(__level GREATER __lvl)
        set(__lvl ${__level})
      endif()
    endforeach()

    #search for compatible levels
    foreach(lvl ${ANDROID_SDK_TARGETS})
      string(REGEX MATCH "[0-9]+$" __level "${lvl}")
      if(__level EQUAL __lvl)
        #look for exact match
        foreach(usrlvl ${ARGN})
          if("${usrlvl}" STREQUAL "${lvl}")
            set(${VAR} "${lvl}")
            break()
          endif()
        endforeach()
        if("${${VAR}}" STREQUAL "${lvl}")
          break() #exact match was found
        elseif(NOT ${VAR})
          set(${VAR} "${lvl}")
        endif()
      elseif(__level GREATER __lvl)
        if(NOT ${VAR})
          set(${VAR} "${lvl}")
        endif()
        break()
      endif()
    endforeach()

    unset(__lvl)
    unset(__level)
  endif()
endmacro()