diff --git a/CMakeLists.txt b/CMakeLists.txt index 657a9207fe7e..e99a3458f292 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,6 +285,7 @@ OCV_OPTION(WITH_ITT "Include Intel ITT support" ON OCV_OPTION(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" NOT (ANDROID OR APPLE_FRAMEWORK) ) OCV_OPTION(BUILD_opencv_apps "Build utility applications (used for example to train classifiers)" (NOT ANDROID AND NOT WINRT) IF (NOT APPLE_FRAMEWORK) ) OCV_OPTION(BUILD_opencv_js "Build JavaScript bindings by Emscripten" OFF ) +OCV_OPTION(BUILD_ANDROID_PROJECTS "Build Android projects providing .apk files" ON IF ANDROID ) OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform" ON IF ANDROID ) OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" OFF IF (NOT WINRT AND NOT APPLE_FRAMEWORK)) OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF ) @@ -644,14 +645,10 @@ include(cmake/OpenCVFindProtobuf.cmake) # --- Java Support --- if(BUILD_JAVA) - include(cmake/OpenCVDetectApacheAnt.cmake) if(ANDROID) - include(cmake/OpenCVDetectAndroidSDK.cmake) - - if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 13) - message(WARNING "OpenCV requires Android SDK tools revision 14 or newer. Otherwise tests and samples will no be compiled.") - endif() + include(cmake/android/OpenCVDetectAndroidSDK.cmake) else() + include(cmake/OpenCVDetectApacheAnt.cmake) find_package(JNI) endif() endif() @@ -1083,18 +1080,39 @@ status(" Non-free algorithms:" OPENCV_ENABLE_NONFREE THEN "YES" ELSE "NO") # ========================== Android details ========================== if(ANDROID) status("") - status(" Android: ") + if(DEFINED ANDROID_NDK_REVISION) + set(__msg "${ANDROID_NDK} (ver ${ANDROID_NDK_REVISION})") + else() + set(__msg "location: ${ANDROID_NDK}") + endif() + status(" Android NDK: " ${__msg}) status(" Android ABI:" ${ANDROID_ABI}) + if(BUILD_WITH_STANDALONE_TOOLCHAIN) + status(" NDK toolchain:" "standalone: ${ANDROID_STANDALONE_TOOLCHAIN}") + elseif(BUILD_WITH_ANDROID_NDK OR DEFINED ANDROID_TOOLCHAIN_NAME) + status(" NDK toolchain:" "${ANDROID_TOOLCHAIN_NAME}") + endif() status(" STL type:" ${ANDROID_STL}) - status(" Native API level:" android-${ANDROID_NATIVE_API_LEVEL}) - android_get_compatible_target(android_sdk_target_status ${ANDROID_NATIVE_API_LEVEL} ${ANDROID_SDK_TARGET} 11) - status(" SDK target:" "${android_sdk_target_status}") - if(BUILD_WITH_ANDROID_NDK) - status(" Android NDK:" "${ANDROID_NDK} (toolchain: ${ANDROID_TOOLCHAIN_NAME})") - elseif(BUILD_WITH_STANDALONE_TOOLCHAIN) - status(" Android toolchain:" "${ANDROID_STANDALONE_TOOLCHAIN}") + status(" Native API level:" ${ANDROID_NATIVE_API_LEVEL}) + + if(BUILD_ANDROID_PROJECTS) + status(" Android SDK: " "${ANDROID_SDK} (tools: ${ANDROID_SDK_TOOLS_VERSION} build tools: ${ANDROID_SDK_BUILD_TOOLS_VERSION})") + if(ANDROID_EXECUTABLE) + status(" android tool:" "${ANDROID_EXECUTABLE}") + endif() + else() + status(" Android SDK: " "not used, projects are not built") + endif() + if(DEFINED ANDROID_SDK_COMPATIBLE_TARGET) + status(" SDK target:" "${ANDROID_SDK_COMPATIBLE_TARGET}") + endif() + if(DEFINED ANDROID_PROJECTS_BUILD_TYPE) + if(ANDROID_PROJECTS_BUILD_TYPE STREQUAL "ANT") + status(" Projects build scripts:" "Ant/Eclipse compatible") + elseif(ANDROID_PROJECTS_BUILD_TYPE STREQUAL "ANT") + status(" Projects build scripts:" "Gradle") + endif() endif() - status(" android tool:" ANDROID_EXECUTABLE THEN "${ANDROID_EXECUTABLE} (${ANDROID_TOOLS_Pkg_Desc})" ELSE NO) endif() # ================== Windows RT features ================== diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index c804fba29f25..a43d39df6666 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -154,6 +154,61 @@ macro(ocv_path_join result_var P1 P2_) #message(STATUS "'${P1}' '${P2_}' => '${${result_var}}'") endmacro() + +# Used to parse Android SDK 'source.properties' files +# File lines format: +# - '=' (with possible 'space' symbols around '=') +# - '#' +# Parsed values are saved into CMake variables: +# - '${var_prefix}_${var_name}' +# Flags: +# - 'CACHE_VAR ' - put these properties into CMake internal cache +# - 'MSG_PREFIX ' - prefix string for emitted messages +# - flag 'VALIDATE' - emit messages about missing values from required cached variables +# - flag 'WARNING' - emit CMake WARNING instead of STATUS messages +function(ocv_parse_properties_file file var_prefix) + cmake_parse_arguments(PARSE_PROPERTIES_PARAM "VALIDATE;WARNING" "" "CACHE_VAR;MSG_PREFIX" ${ARGN}) + + set(__msg_type STATUS) + if(PARSE_PROPERTIES_PARAM_WARNING) + set(__msg_type WARNING) + endif() + + if(EXISTS "${file}") + set(SOURCE_PROPERTIES_REGEX "^[ ]*([^=:\n\"' ]+)[ ]*=[ ]*(.*)$") + file(STRINGS "${file}" SOURCE_PROPERTIES_LINES REGEX "^[ ]*[^#].*$") + foreach(line ${SOURCE_PROPERTIES_LINES}) + if(line MATCHES "${SOURCE_PROPERTIES_REGEX}") + set(__name "${CMAKE_MATCH_1}") + set(__value "${CMAKE_MATCH_2}") + string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" __name ${__name}) + if(";${PARSE_PROPERTIES_PARAM_CACHE_VAR};" MATCHES ";${__name};") + set(${var_prefix}_${__name} "${__value}" CACHE INTERNAL "from ${file}") + else() + set(${var_prefix}_${__name} "${__value}" PARENT_SCOPE) + endif() + else() + message(${__msg_type} "${PARSE_PROPERTIES_PARAM_MSG_PREFIX}Can't parse source property: '${line}' (from ${file})") + endif() + endforeach() + if(PARSE_PROPERTIES_PARAM_VALIDATE) + set(__missing "") + foreach(__name ${PARSE_PROPERTIES_PARAM_CACHE_VAR}) + if(NOT DEFINED ${var_prefix}_${__name}) + list(APPEND __missing ${__name}) + endif() + endforeach() + if(__missing) + message(${__msg_type} "${PARSE_PROPERTIES_PARAM_MSG_PREFIX}Can't read properties '${__missing}' from '${file}'") + endif() + endif() + else() + message(${__msg_type} "${PARSE_PROPERTIES_PARAM_MSG_PREFIX}Can't find file: ${file}") + endif() +endfunction() + + + # rename modules target to world if needed macro(_ocv_fix_target target_var) if(BUILD_opencv_world) diff --git a/cmake/android/OpenCVDetectAndroidSDK.cmake b/cmake/android/OpenCVDetectAndroidSDK.cmake new file mode 100644 index 000000000000..f2f21f5f70ec --- /dev/null +++ b/cmake/android/OpenCVDetectAndroidSDK.cmake @@ -0,0 +1,210 @@ +if(EXISTS "${ANDROID_EXECUTABLE}") + set(ANDROID_SDK_DETECT_QUIET TRUE) +endif() + +# fixup for https://github.com/android-ndk/ndk/issues/596 +if(DEFINED ANDROID_NDK_REVISION AND ANDROID_NDK_REVISION MATCHES "(1[56])([0-9]+)\\.([^\n]+)\n") + set(ANDROID_NDK_REVISION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + set(ANDROID_NDK_REVISION "${ANDROID_NDK_REVISION}" CACHE INTERNAL "Android NDK revision") +endif() + +# https://developer.android.com/studio/command-line/variables.html +ocv_check_environment_variables(ANDROID_SDK_ROOT ANDROID_HOME ANDROID_SDK) + +set(__msg_BUILD_ANDROID_PROJECTS "Use BUILD_ANDROID_PROJECTS=OFF to prepare Android project files without building them") + +macro(ocv_detect_android_sdk) + if(NOT DEFINED ANDROID_SDK) + if(DEFINED ANDROID_SDK AND EXISTS "${ANDROID_SDK}") + set(ANDROID_SDK "${ANDROID_SDK}" CACHE INTERNAL "Android SDK path") + elseif(DEFINED ANDROID_HOME AND EXISTS "${ANDROID_HOME}") + set(ANDROID_SDK "${ANDROID_HOME}" CACHE INTERNAL "Android SDK path") + elseif(DEFINED ANDROID_SDK_ROOT AND EXISTS "${ANDROID_SDK_ROOT}") + set(ANDROID_SDK "${ANDROID_SDK_ROOT}" CACHE INTERNAL "Android SDK path") + endif() + if(DEFINED ANDROID_SDK) + message(STATUS "Android SDK: using location: ${ANDROID_SDK}") + endif() + endif() + if(NOT DEFINED ANDROID_SDK) + message(FATAL_ERROR "Android SDK: specify path to Android SDK via ANDROID_SDK_ROOT / ANDROID_HOME / ANDROID_SDK variables") + endif() + if(NOT EXISTS "${ANDROID_SDK}") + message(FATAL_ERROR "Android SDK: specified path doesn't exist: ${ANDROID_SDK}") + endif() +endmacro() + +macro(ocv_detect_android_sdk_tools) + # https://developer.android.com/studio/releases/sdk-tools.html + if(NOT DEFINED ANDROID_SDK_TOOLS) + if(DEFINED ANDROID_SDK AND EXISTS "${ANDROID_SDK}/tools") + set(ANDROID_SDK_TOOLS "${ANDROID_SDK}/tools" CACHE INTERNAL "Android SDK Tools path") + endif() + endif() + if(NOT DEFINED ANDROID_SDK_TOOLS) + message(FATAL_ERROR "Android SDK Tools: can't automatically find Android SDK Tools. Specify path via ANDROID_SDK_TOOLS variable") + endif() + if(NOT EXISTS "${ANDROID_SDK_TOOLS}") + message(FATAL_ERROR "Android SDK Tools: specified path doesn't exist: ${ANDROID_SDK_TOOLS}") + endif() + + if(NOT DEFINED ANDROID_SDK_TOOLS_VERSION) + ocv_parse_properties_file("${ANDROID_SDK_TOOLS}/source.properties" + ANDROID_TOOLS CACHE Pkg_Revision + MSG_PREFIX "Android SDK Tools: " + ) + + if(NOT DEFINED ANDROID_TOOLS_Pkg_Revision) + message(FATAL_ERROR "Android SDK Tools: Can't determine package version: ANDROID_SDK_TOOLS=${ANDROID_SDK_TOOLS}\n" + "Check specified parameters or force version via 'ANDROID_SDK_TOOLS_VERSION' variable.\n" + "${__msg_BUILD_ANDROID_PROJECTS}") + elseif(NOT ANDROID_SDK_DETECT_QUIET) + set(__info "") + if(DEFINED ANDROID_TOOLS_Pkg_Desc) + set(__info " (description: '${ANDROID_TOOLS_Pkg_Desc}')") + endif() + message(STATUS "Android SDK Tools: ver. ${ANDROID_TOOLS_Pkg_Revision}${__info}") + endif() + set(ANDROID_SDK_TOOLS_VERSION "${ANDROID_TOOLS_Pkg_Revision}" CACHE INTERNAL "Android SDK Tools version") + endif() + if(NOT DEFINED ANDROID_TOOLS_Pkg_Revision) + set(ANDROID_TOOLS_Pkg_Revision "${ANDROID_SDK_TOOLS_VERSION}" CACHE INTERNAL "Android SDK Tools version (deprecated)") + endif() + set(ANDROID_SDK_TOOLS_PATH "${ANDROID_SDK_TOOLS}" CACHE INTERNAL "Android SDK Tools path (deprecated)") +endmacro() # ocv_detect_android_sdk_tools + +macro(ocv_detect_android_sdk_build_tools) + # https://developer.android.com/studio/releases/build-tools.html + if(NOT DEFINED ANDROID_SDK_BUILD_TOOLS_VERSION) + if(NOT DEFINED ANDROID_SDK_BUILD_TOOLS) + set(__search_dir ${ANDROID_SDK}/build-tools) + if(NOT EXISTS "${__search_dir}") + message(FATAL_ERROR "Android SDK Build Tools: directory doesn't exist: ${__search_dir} " + "${__msg_BUILD_ANDROID_PROJECTS}") + endif() + + if(NOT DEFINED ANDROID_SDK_BUILD_TOOLS_SUBDIR) + file(GLOB __found RELATIVE "${__search_dir}" ${__search_dir}/*) + set(__dirlist "") + set(__selected 0) + set(__versions "") + foreach(d ${__found}) + if(IS_DIRECTORY "${__search_dir}/${d}") + list(APPEND __dirlist ${d}) + if(d MATCHES "[0-9]+(\\.[0-9]+)*") + list(APPEND __versions "${d}") + endif() + if(__selected VERSION_LESS d) + set(__selected "${d}") + endif() + endif() + endforeach() + if(__selected VERSION_GREATER 0) + set(ANDROID_SDK_BUILD_TOOLS_SUBDIR "${__selected}") + elseif(__dirlist) + set(__versions "") + foreach(d ${__dirlist}) + if(EXISTS "${__search_dir}/${d}/source.properties") + ocv_clear_vars(ANDROID_BUILD_TOOLS_Pkg_Revision) + ocv_parse_properties_file("${__search_dir}/${d}/source.properties" + ANDROID_BUILD_TOOLS + MSG_PREFIX "Android SDK Tools: " + ) + if(DEFINED ANDROID_BUILD_TOOLS_Pkg_Revision) + list(APPEND __versions "${ANDROID_BUILD_TOOLS_Pkg_Revision}") + if(__selected VERSION_LESS ANDROID_BUILD_TOOLS_Pkg_Revision) + set(ANDROID_SDK_BUILD_TOOLS_SUBDIR "${d}") + set(__selected "${ANDROID_BUILD_TOOLS_Pkg_Revision}") + endif() + endif() + endif() + endforeach() + endif() + if(DEFINED ANDROID_SDK_BUILD_TOOLS_SUBDIR) + set(ANDROID_SDK_BUILD_TOOLS_VERSION "${__selected}" CACHE STRING "Android SDK Build Tools version") + set_property(CACHE ANDROID_SDK_BUILD_TOOLS_VERSION PROPERTY STRINGS ${__versions}) + set(ANDROID_SDK_BUILD_TOOLS "${__search_dir}/${d}" CACHE INTERNAL "Android SDK Build Tools path") + message(STATUS "Android SDK Build Tools: ver. ${ANDROID_SDK_BUILD_TOOLS_VERSION} (subdir ${ANDROID_SDK_BUILD_TOOLS_SUBDIR} from ${__dirlist})") + else() + message(FATAL_ERROR "Android SDK Build Tools: autodetection failed. " + "Specify ANDROID_SDK_BUILD_TOOLS_VERSION / ANDROID_SDK_BUILD_TOOLS_SUBDIR / ANDROID_SDK_BUILD_TOOLS variable to bypass autodetection.\n" + "${__msg_BUILD_ANDROID_PROJECTS}") + endif() + endif() + else() + ocv_parse_properties_file("${ANDROID_SDK_BUILD_TOOLS}/source.properties" + ANDROID_BUILD_TOOLS + MSG_PREFIX "Android SDK Tools: " + ) + if(NOT DEFINED ANDROID_BUILD_TOOLS_Pkg_Revision) + message(FATAL_ERROR "Android SDK Build Tools: Can't detect version: ANDROID_SDK_BUILD_TOOLS=${ANDROID_SDK_BUILD_TOOLS}\n" + "Specify ANDROID_SDK_BUILD_TOOLS_VERSION variable to bypass autodetection.\n" + "${__msg_BUILD_ANDROID_PROJECTS}") + else() + set(ANDROID_SDK_BUILD_TOOLS_VERSION "${ANDROID_BUILD_TOOLS_Pkg_Revision}" CACHE INTERNAL "Android SDK Build Tools version") + message(STATUS "Android SDK Build Tools: ver. ${ANDROID_SDK_BUILD_TOOLS_VERSION} (ANDROID_SDK_BUILD_TOOLS=${ANDROID_SDK_BUILD_TOOLS})") + endif() + endif() # ANDROID_SDK_BUILD_TOOLS + endif() # ANDROID_SDK_BUILD_TOOLS_VERSION +endmacro() # ocv_detect_android_sdk_build_tools + + +if(BUILD_ANDROID_PROJECTS) + ocv_detect_android_sdk() + ocv_detect_android_sdk_tools() + ocv_detect_android_sdk_build_tools() + + if(ANDROID_SDK_TOOLS_VERSION VERSION_LESS 14) + message(FATAL_ERROR "Android SDK Tools: OpenCV requires Android SDK Tools revision 14 or newer.\n" + "${__msg_BUILD_ANDROID_PROJECTS}") + endif() + + if(NOT ANDROID_SDK_TOOLS_VERSION VERSION_LESS 25.3.0) + message(STATUS "Android SDK Tools: Ant (Eclipse) builds are NOT supported by Android SDK") + ocv_update(ANDROID_PROJECTS_SUPPORT_ANT OFF) + if(NOT ANDROID_SDK_BUILD_TOOLS_VERSION VERSION_LESS 26.0.2) + # https://developer.android.com/studio/releases/gradle-plugin.html + message(STATUS "Android SDK Build Tools: Gradle 3.0.0+ builds support is available") + ocv_update(ANDROID_PROJECTS_SUPPORT_GRADLE ON) + endif() + else() + include(${CMAKE_CURRENT_LIST_DIR}/../OpenCVDetectApacheAnt.cmake) + if(ANT_EXECUTABLE AND NOT ANT_VERSION VERSION_LESS 1.7) + message(STATUS "Android SDK Tools: Ant (Eclipse) builds are supported") + ocv_update(ANDROID_PROJECTS_SUPPORT_ANT ON) + endif() + endif() + + if(NOT DEFINED ANDROID_PROJECTS_BUILD_TYPE) + if(ANDROID_PROJECTS_SUPPORT_ANT) + ocv_update(ANDROID_PROJECTS_BUILD_TYPE "ANT") + elseif(ANDROID_PROJECTS_SUPPORT_GRADLE) + ocv_update(ANDROID_PROJECTS_BUILD_TYPE "GRADLE") + else() + message(FATAL_ERROR "Android SDK: Can't build Android projects as requested by BUILD_ANDROID_PROJECTS=ON variable.\n" + "${__msg_BUILD_ANDROID_PROJECTS}") + endif() + endif() + + if(ANDROID_PROJECTS_BUILD_TYPE STREQUAL "ANT") + message(STATUS "Android SDK Tools: Prepare Android projects for using Ant build scripts (deprecated)") + elseif(ANDROID_PROJECTS_BUILD_TYPE STREQUAL "GRADLE") + message(STATUS "Android SDK Tools: Prepare Android projects for using Gradle 3.0.0+ build scripts") + endif() + +else() + message("Android: Projects builds are DISABLED") + macro(add_android_project) + endmacro() +endif() # BUILD_ANDROID_PROJECTS + +if(ANDROID_PROJECTS_BUILD_TYPE STREQUAL "ANT") + include(${CMAKE_CURRENT_LIST_DIR}/android_ant_projects.cmake) +elseif(ANDROID_PROJECTS_BUILD_TYPE STREQUAL "GRADLE") + include(${CMAKE_CURRENT_LIST_DIR}/android_gradle_projects.cmake) +elseif(BUILD_ANDROID_PROJECTS) + message(FATAL_ERROR "Internal error") +else() + # TODO + #include(${CMAKE_CURRENT_LIST_DIR}/android_disabled_projects.cmake) +endif() diff --git a/cmake/OpenCVDetectAndroidSDK.cmake b/cmake/android/android_ant_projects.cmake similarity index 71% rename from cmake/OpenCVDetectAndroidSDK.cmake rename to cmake/android/android_ant_projects.cmake index fb11714733dd..ed9ce43582e5 100644 --- a/cmake/OpenCVDetectAndroidSDK.cmake +++ b/cmake/android/android_ant_projects.cmake @@ -1,133 +1,44 @@ -if(EXISTS "${ANDROID_EXECUTABLE}") - set(ANDROID_SDK_DETECT_QUIET TRUE) -endif() - -file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH) -file(TO_CMAKE_PATH "$ENV{HOME}" HOME_ENV_PATH) - -if(CMAKE_HOST_WIN32) - set(ANDROID_SDK_OS windows) -elseif(CMAKE_HOST_APPLE) - set(ANDROID_SDK_OS macosx) -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 find_host_program(ANDROID_EXECUTABLE NAMES android.bat android - 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" - ) - -if(ANDROID_EXECUTABLE) - if(NOT ANDROID_SDK_DETECT_QUIET) - message(STATUS "Found android tool: ${ANDROID_EXECUTABLE}") - endif() - - 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}) - SET(ANDROID_TOOLS_${line_name} "${line_value}" CACHE INTERNAL "from ${ANDROID_SDK_TOOLS_PATH}/source.properties") - MARK_AS_ADVANCED(ANDROID_TOOLS_${line_name}) - endforeach() - endif() - - #fix missing revision (SDK tools before r9 don't set revision number correctly) - if(NOT ANDROID_TOOLS_Pkg_Revision) - SET(ANDROID_TOOLS_Pkg_Revision "Unknown" CACHE INTERNAL "") - MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Revision) - endif() - - #fix missing description - if(NOT ANDROID_TOOLS_Pkg_Desc) - SET(ANDROID_TOOLS_Pkg_Desc "Android SDK Tools, revision ${ANDROID_TOOLS_Pkg_Revision}." CACHE INTERNAL "") - MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Desc) - endif() + PATHS "${ANDROID_SDK_TOOLS}" + DOC "Android 'android' tool location" +) - #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(NOT ANDROID_EXECUTABLE) + message(FATAL_ERROR "Android SDK Tools: Can't find 'android' tool") +elseif(NOT ANDROID_SDK_DETECT_QUIET) + message(STATUS "Android SDK Tools: Found 'android' tool: ${ANDROID_EXECUTABLE}") +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_PROJECT_PROPERTIES_FILE project.properties) +set(ANDROID_ANT_PROPERTIES_FILE ant.properties) - 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_LIB_PROJECT_FILES}) - - #get installed targets - 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() +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_LIB_PROJECT_FILES}) - if(NOT ANDROID_PROCESS EQUAL 0) - message(ERROR "Failed to get list of installed Android targets.") - set(ANDROID_EXECUTABLE "ANDROID_EXECUTABLE-NOTFOUND") - endif() +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 + ) +if(NOT ANDROID_PROCESS EQUAL 0) + set(ANDROID_EXECUTABLE "ANDROID_EXECUTABLE-NOTFOUND" CACHE INTERNAL) + message(FATAL_ERROR "Android: Failed to get list of installed Android targets.") +endif() +string(REGEX MATCHALL "[^\n]+" ANDROID_SDK_TARGETS "${ANDROID_SDK_TARGETS}") - # clear ANDROID_SDK_TARGET if no target is provided by user - if(NOT ANDROID_SDK_TARGET) - set(ANDROID_SDK_TARGET "" CACHE STRING "Android SDK target for the OpenCV Java API and samples") - endif() - if(ANDROID_SDK_TARGETS) - set_property( CACHE ANDROID_SDK_TARGET PROPERTY STRINGS ${ANDROID_SDK_TARGETS} ) - endif() -endif(ANDROID_EXECUTABLE) +# clear ANDROID_SDK_TARGET if no target is provided by user +if(NOT ANDROID_SDK_TARGET) + set(ANDROID_SDK_TARGET "" CACHE STRING "Android SDK target for the OpenCV Java API and samples") +endif() +if(ANDROID_SDK_TARGETS) + message(STATUS "Android SDK Tools: Available targets: ${ANDROID_SDK_TARGETS}") + set_property(CACHE ANDROID_SDK_TARGET PROPERTY STRINGS ${ANDROID_SDK_TARGETS} ) +else() + message(FATAL_ERROR "Android: List of installed Android targets is empty") +endif() # finds minimal installed SDK target compatible with provided names or API levels # usage: diff --git a/cmake/android/android_gradle_projects.cmake b/cmake/android/android_gradle_projects.cmake new file mode 100644 index 000000000000..1ca752f8b250 --- /dev/null +++ b/cmake/android/android_gradle_projects.cmake @@ -0,0 +1,5 @@ +message(FATAL_ERROR " +Android gradle-based build/projects are not supported in this version of OpenCV. +You need to downgrade Android SDK Tools to version 25.2.5. +Details: https://github.com/opencv/opencv/issues/8460 +") diff --git a/modules/java/android_sdk/CMakeLists.txt b/modules/java/android_sdk/CMakeLists.txt index 0bee8d03bb9f..e57b0394a3bf 100644 --- a/modules/java/android_sdk/CMakeLists.txt +++ b/modules/java/android_sdk/CMakeLists.txt @@ -18,8 +18,11 @@ ocv_copyfiles_append_dir(JAVA_SRC_COPY "${OPENCV_JAVA_BINDINGS_DIR}/gen/java" "$ ocv_copyfiles_append_dir(JAVA_SRC_COPY "${OPENCV_JAVA_BINDINGS_DIR}/gen/android/java" "${java_src_dir}") # calc default SDK Target -android_get_compatible_target(android_sdk_target ${ANDROID_NATIVE_API_LEVEL} ${ANDROID_SDK_TARGET} 14) -string(REGEX REPLACE "android-" "" android_sdk_target_num ${android_sdk_target}) +android_get_compatible_target(ANDROID_SDK_COMPATIBLE_TARGET ${ANDROID_NATIVE_API_LEVEL} ${ANDROID_SDK_TARGET} 14) +if(ANDROID_SDK_COMPATIBLE_TARGET) + set(ANDROID_SDK_COMPATIBLE_TARGET "${ANDROID_SDK_COMPATIBLE_TARGET}" CACHE INTERNAL "") +endif() +string(REGEX REPLACE "android-" "" android_sdk_target_num ${ANDROID_SDK_COMPATIBLE_TARGET}) if( (ANDROID_SDK_TARGET AND ANDROID_SDK_TARGET LESS 21) OR (android_sdk_target_num LESS 21) ) message(STATUS "[OpenCV for Android SDK]: A new OpenGL Camera Bridge (CameraGLSurfaceView, CameraGLRendererBase, CameraRenderer, Camera2Renderer) is disabled, because ANDROID_SDK_TARGET (${android_sdk_target_num}) < 21") else() @@ -52,7 +55,7 @@ add_custom_command( OUTPUT ${android_sdk_project_files} "${OPENCV_JAVA_DIR}/${ANDROID_MANIFEST_FILE}" COMMAND ${CMAKE_COMMAND} -E remove ${android_sdk_project_files} COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/${ANDROID_MANIFEST_FILE}" "${OPENCV_JAVA_DIR}/${ANDROID_MANIFEST_FILE}" - COMMAND ${ANDROID_EXECUTABLE} --silent create lib-project --path \"${OPENCV_JAVA_DIR}\" --target \"${android_sdk_target}\" --name OpenCV --package org.opencv 2>\"${CMAKE_CURRENT_BINARY_DIR}/create_lib_project.log\" + COMMAND ${ANDROID_EXECUTABLE} --silent create lib-project --path \"${OPENCV_JAVA_DIR}\" --target \"${ANDROID_SDK_COMPATIBLE_TARGET}\" --name OpenCV --package org.opencv 2>\"${CMAKE_CURRENT_BINARY_DIR}/create_lib_project.log\" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/${ANDROID_MANIFEST_FILE}" "${OPENCV_JAVA_DIR}/${ANDROID_MANIFEST_FILE}" WORKING_DIRECTORY "${OPENCV_JAVA_DIR}" MAIN_DEPENDENCY "${CMAKE_CURRENT_BINARY_DIR}/${ANDROID_MANIFEST_FILE}"