diff --git a/CMakeLists.txt b/CMakeLists.txt index cf1d8f490..87210d88c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -847,9 +847,9 @@ endif() # samples and tests status("") status(" Tests and samples:") -status(" Tests:" BUILD_TESTS THEN YES ELSE NO) -status(" Performance tests:" BUILD_PERF_TESTS THEN YES ELSE NO) -status(" Examples:" BUILD_EXAMPLES THEN YES ELSE NO) +status(" Tests:" BUILD_TESTS AND HAVE_opencv_ts THEN YES ELSE NO) +status(" Performance tests:" BUILD_PERF_TESTS AND HAVE_opencv_ts THEN YES ELSE NO) +status(" Examples:" BUILD_EXAMPLES THEN YES ELSE NO) if(ANDROID) status(" Android tests:" BUILD_TESTS AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO) diff --git a/cmake/OpenCVDetectAndroidSDK.cmake b/cmake/OpenCVDetectAndroidSDK.cmake index bc3dc8718..4c630170a 100644 --- a/cmake/OpenCVDetectAndroidSDK.cmake +++ b/cmake/OpenCVDetectAndroidSDK.cmake @@ -1,31 +1,47 @@ +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{ANDROID_SDK}" ANDROID_SDK_ENV_PATH) file(TO_CMAKE_PATH "$ENV{HOME}" HOME_ENV_PATH) -#find android SDK +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 - PATHS "${ANDROID_SDK_ENV_PATH}/tools/" - "${ProgramFiles_ENV_PATH}/Android/android-sdk/tools/" - "${ProgramFiles_ENV_PATH}/Android/android-sdk-windows/tools/" - "/opt/android-sdk-linux/tools/" - "/opt/android-sdk-linux_x86/tools/" - "/opt/android-sdk-linux_86/tools/" - "/opt/android-sdk-mac/tools/" - "/opt/android-sdk-mac_x86/tools/" - "/opt/android-sdk-mac_86/tools/" - "/opt/android-sdk/tools/" - "${HOME_ENV_PATH}/NVPACK/android-sdk-linux_x86/tools/" - "${HOME_ENV_PATH}/NVPACK/android-sdk-linux_86/tools/" - "${HOME_ENV_PATH}/NVPACK/android-sdk-linux/tools/" - "${HOME_ENV_PATH}/NVPACK/android-sdk-mac_x86/tools/" - "${HOME_ENV_PATH}/NVPACK/android-sdk-mac_86/tools/" - "${HOME_ENV_PATH}/NVPACK/android-sdk-mac/tools/" - "$ENV{SystemDrive}/NVPACK/android-sdk-windows/tools/" + 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) - message(STATUS " Found android tool: ${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 @@ -42,37 +58,70 @@ if(ANDROID_EXECUTABLE) 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 "") - if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 11) - SET(ANDROID_TOOLS_Pkg_Desc "${ANDROID_TOOLS_Pkg_Desc} It is recommended to update your SDK tools to revision 12 or newer." CACHE INTERNAL "") - endif() MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Desc) endif() - #get installed targets - 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}") + #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() - 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() + 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}) + + #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() + + if(NOT ANDROID_PROCESS EQUAL 0) + message(ERROR "Failed to get list of installed Android targets.") + set(ANDROID_EXECUTABLE "ANDROID_EXECUTABLE-NOTFOUND") endif() # detect ANDROID_SDK_TARGET if no target is provided by user + #TODO: remove this block if(NOT ANDROID_SDK_TARGET) set(desired_android_target_level ${ANDROID_NATIVE_API_LEVEL}) if(desired_android_target_level LESS 11) @@ -95,8 +144,51 @@ if(ANDROID_EXECUTABLE) endif(NOT ANDROID_SDK_TARGET) SET(ANDROID_SDK_TARGET "${ANDROID_SDK_TARGET}" CACHE STRING "SDK target for Android tests and samples") - if(ANDROID_PROCESS EQUAL 0 AND CMAKE_VERSION VERSION_GREATER "2.8") - set_property( CACHE ANDROID_SDK_TARGET PROPERTY STRINGS ${ANDROID_SDK_TARGETS} ) - endif() string(REGEX MATCH "[0-9]+$" ANDROID_SDK_TARGET_LEVEL "${ANDROID_SDK_TARGET}") endif(ANDROID_EXECUTABLE) + +# 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() diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 4cf43ddb5..c73ec32eb 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -76,20 +76,20 @@ macro(ocv_add_dependencies full_modname) endif() set(OPENCV_MODULE_${full_modname}_REQ_DEPS ${OPENCV_MODULE_${full_modname}_REQ_DEPS} CACHE INTERNAL "Required dependencies of ${full_modname} module") set(OPENCV_MODULE_${full_modname}_OPT_DEPS ${OPENCV_MODULE_${full_modname}_OPT_DEPS} CACHE INTERNAL "Optional dependencies of ${full_modname} module") - + unset(__depsvar) endmacro() # declare new OpenCV module in current folder # Usage: -# ocv_add_module( [INTERNAL|BINDINGS] [REQUIRED] [] [OPTIONAL ]) +# ocv_add_module( [INTERNAL|BINDINGS] [REQUIRED] [] [OPTIONAL ]) # Example: # ocv_add_module(yaom INTERNAL opencv_core opencv_highgui NOLINK opencv_flann OPTIONAL opencv_gpu) macro(ocv_add_module _name) string(TOLOWER "${_name}" name) string(REGEX REPLACE "^opencv_" "" ${name} "${name}") set(the_module opencv_${name}) - + # the first pass - collect modules info, the second pass - create targets if(OPENCV_INITIAL_PASS) #guard agains redefinition @@ -108,7 +108,7 @@ macro(ocv_add_module _name) set(OPENCV_MODULE_${the_module}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${the_module} module sources") unset(OPENCV_MODULE_${the_module}_REQ_DEPS CACHE) unset(OPENCV_MODULE_${the_module}_OPT_DEPS CACHE) - + #create option to enable/disable this module option(BUILD_${the_module} "Include ${the_module} module into the OpenCV build" ON) @@ -129,7 +129,7 @@ macro(ocv_add_module _name) else() set(OPENCV_MODULES_DISABLED_USER ${OPENCV_MODULES_DISABLED_USER} "${the_module}" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user") endif() - + #TODO: add submodules if any #stop processing of current file @@ -170,7 +170,7 @@ macro(__ocv_flatten_module_required_dependencies the_module) set(__flattened_deps "") set(__resolved_deps "") set(__req_depends ${OPENCV_MODULE_${the_module}_REQ_DEPS}) - + while(__req_depends) list(GET __req_depends 0 __dep) list(REMOVE_AT __req_depends 0) @@ -206,7 +206,7 @@ macro(__ocv_flatten_module_required_dependencies the_module) else() set(OPENCV_MODULE_${the_module}_DEPS "") endif() - + unset(__resolved_deps) unset(__flattened_deps) unset(__req_depends) @@ -217,7 +217,7 @@ macro(__ocv_flatten_module_optional_dependencies the_module) set(__flattened_deps ${OPENCV_MODULE_${the_module}_DEPS}) set(__resolved_deps ${OPENCV_MODULE_${the_module}_DEPS}) set(__opt_depends ${OPENCV_MODULE_${the_module}_OPT_DEPS}) - + while(__opt_depends) list(GET __opt_depends 0 __dep) list(REMOVE_AT __opt_depends 0) @@ -244,7 +244,7 @@ macro(__ocv_flatten_module_optional_dependencies the_module) else() set(OPENCV_MODULE_${the_module}_DEPS "") endif() - + unset(__resolved_deps) unset(__flattened_deps) unset(__opt_depends) @@ -259,10 +259,10 @@ macro(__ocv_flatten_module_dependencies) set(HAVE_${m} ON CACHE INTERNAL "Module ${m} will not be built in current configuration") __ocv_flatten_module_required_dependencies(${m}) endforeach() - + foreach(m ${OPENCV_MODULES_BUILD}) __ocv_flatten_module_optional_dependencies(${m}) - + #dependencies from other modules set(OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module") #extra dependencies @@ -273,7 +273,7 @@ macro(__ocv_flatten_module_dependencies) ocv_list_filterout(OPENCV_MODULE_${m}_DEPS_EXT "^opencv_[^ ]+$") set(OPENCV_MODULE_${m}_DEPS_EXT ${OPENCV_MODULE_${m}_DEPS_EXT} CACHE INTERNAL "Extra dependencies of ${m} module") endforeach() - + set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} CACHE INTERNAL "List of OpenCV modules marked for export") set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD} CACHE INTERNAL "List of OpenCV modules included into the build") set(OPENCV_MODULES_DISABLED_AUTO ${OPENCV_MODULES_DISABLED_AUTO} CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies") @@ -322,7 +322,7 @@ macro(ocv_glob_modules) #resolve dependencies __ocv_flatten_module_dependencies() - + #order modules by dependencies set(OPENCV_MODULES_BUILD_ "") foreach(m ${OPENCV_MODULES_BUILD}) @@ -373,7 +373,7 @@ endmacro() macro(ocv_set_module_sources) set(OPENCV_MODULE_${the_module}_HEADERS "") set(OPENCV_MODULE_${the_module}_SOURCES "") - + foreach(f "HEADERS" ${ARGN}) if(f STREQUAL "HEADERS" OR f STREQUAL "SOURCES") set(__filesvar "OPENCV_MODULE_${the_module}_${f}") @@ -381,12 +381,15 @@ macro(ocv_set_module_sources) list(APPEND ${__filesvar} "${f}") endif() endforeach() - + # the hacky way to embeed any files into the OpenCV without modification of its build system if(COMMAND ocv_get_module_external_sources) ocv_get_module_external_sources() endif() + # use full paths for module to be independent from the module location + ocv_to_full_paths(OPENCV_MODULE_${the_module}_HEADERS) + set(OPENCV_MODULE_${the_module}_HEADERS ${OPENCV_MODULE_${the_module}_HEADERS} CACHE INTERNAL "List of header files for ${the_module}") set(OPENCV_MODULE_${the_module}_SOURCES ${OPENCV_MODULE_${the_module}_SOURCES} CACHE INTERNAL "List of source files for ${the_module}") endmacro() @@ -415,11 +418,11 @@ macro(ocv_create_module) add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}) target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN}) add_dependencies(opencv_modules ${the_module}) - + if(ENABLE_SOLUTION_FOLDERS) set_target_properties(${the_module} PROPERTIES FOLDER "modules") endif() - + set_target_properties(${the_module} PROPERTIES OUTPUT_NAME "${the_module}${OPENCV_DLLVERSION}" DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" @@ -427,7 +430,7 @@ macro(ocv_create_module) RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} INSTALL_NAME_DIR lib ) - + # For dynamic link numbering convenions if(NOT ANDROID) # Android SDK build scripts can include only .so files into final .apk @@ -483,7 +486,7 @@ macro(ocv_add_precompiled_headers the_target) SET(pch_path "src/") endif() set(pch_header "${CMAKE_CURRENT_SOURCE_DIR}/${pch_path}precomp.hpp") - + if(PCHSupport_FOUND AND ENABLE_PRECOMPILED_HEADERS AND EXISTS "${pch_header}") if(CMAKE_GENERATOR MATCHES Visual) set(${the_target}_pch "${CMAKE_CURRENT_SOURCE_DIR}/${pch_path}precomp.cpp") @@ -568,7 +571,7 @@ macro(ocv_add_perf_tests) if(OCV_DEPENDENCIES_FOUND) set(the_target "opencv_perf_${name}") #project(${the_target}) - + ocv_module_include_directories(${perf_deps} "${perf_path}") if(NOT OPENCV_PERF_${the_module}_SOURCES) @@ -619,7 +622,7 @@ macro(ocv_add_accuracy_tests) if(OCV_DEPENDENCIES_FOUND) set(the_target "opencv_test_${name}") #project(${the_target}) - + ocv_module_include_directories(${test_deps} "${test_path}") if(NOT OPENCV_TEST_${the_module}_SOURCES) @@ -629,7 +632,7 @@ macro(ocv_add_accuracy_tests) source_group("Include" FILES ${test_hdrs}) set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs}) endif() - + add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES}) target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS}) add_dependencies(opencv_tests ${the_target}) @@ -643,7 +646,7 @@ macro(ocv_add_accuracy_tests) if(ENABLE_SOLUTION_FOLDERS) set_target_properties(${the_target} PROPERTIES FOLDER "tests accuracy") endif() - + enable_testing() get_target_property(LOC ${the_target} LOCATION) add_test(${the_target} "${LOC}") @@ -698,7 +701,7 @@ macro(__ocv_track_module_link_dependencies the_module optkind) # get_target_property(__dep_location "${__dep}" LOCATION) endif() endwhile() - + ocv_list_unique(${the_module}_MODULE_DEPS_${optkind}) #ocv_list_reverse(${the_module}_MODULE_DEPS_${optkind}) ocv_list_unique(${the_module}_EXTRA_DEPS_${optkind}) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 7b5248557..ab6bb05a6 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -216,6 +216,28 @@ macro(ocv_list_sort __lst) endmacro() +# add prefix to each item in the list +macro(ocv_list_add_prefix LST PREFIX) + set(__tmp "") + foreach(item ${${LST}}) + list(APPEND __tmp "${PREFIX}${item}") + endforeach() + set(${LST} ${__tmp}) + unset(__tmp) +endmacro() + + +# add suffix to each item in the list +macro(ocv_list_add_suffix LST SUFFIX) + set(__tmp "") + foreach(item ${${LST}}) + list(APPEND __tmp "${item}${SUFFIX}") + endforeach() + set(${LST} ${__tmp}) + unset(__tmp) +endmacro() + + # simple regex escaping routine (does not cover all cases!!!) macro(ocv_regex_escape var regex) string(REGEX REPLACE "([+.*^$])" "\\\\1" ${var} "${regex}") @@ -230,3 +252,17 @@ macro(ocv_get_real_path VAR PATHSTR) get_filename_component(${VAR} "${PATHSTR}" REALPATH) endif() endmacro() + + +# convert list of paths to full paths +macro(ocv_to_full_paths VAR) + if(${VAR}) + set(__tmp "") + foreach(path ${${VAR}}) + get_filename_component(${VAR} "${path}" ABSOLUTE) + list(APPEND __tmp "${${VAR}}") + endforeach() + set(${VAR} ${__tmp}) + unset(__tmp) + endif() +endmacro() \ No newline at end of file diff --git a/modules/java/CMakeLists.txt b/modules/java/CMakeLists.txt index 1054095a4..194568666 100644 --- a/modules/java/CMakeLists.txt +++ b/modules/java/CMakeLists.txt @@ -1,16 +1,15 @@ # ---------------------------------------------------------------------------- # CMake file for java support # ---------------------------------------------------------------------------- -if(NOT ANDROID OR NOT PYTHON_EXECUTABLE) +if(NOT ANDROID OR NOT PYTHON_EXECUTABLE OR ANDROID_NATIVE_API_LEVEL LESS 8) ocv_module_disable(java) endif() -set(OPENCV_MODULES_EXPORTED_TO_JAVA opencv_objdetect opencv_features2d opencv_video opencv_highgui opencv_ml opencv_calib3d opencv_photo CACHE STRING "List of modules exported to Java API") -mark_as_advanced(OPENCV_MODULES_EXPORTED_TO_JAVA) - set(the_description "The java bindings") -ocv_add_module(java BINDINGS opencv_core opencv_imgproc OPTIONAL ${OPENCV_MODULES_EXPORTED_TO_JAVA}) +ocv_add_module(java BINDINGS opencv_core opencv_imgproc OPTIONAL opencv_objdetect opencv_features2d opencv_video opencv_highgui opencv_ml opencv_calib3d opencv_photo) +ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cpp") +# get list of modules to wrap string(REPLACE "opencv_" "" OPENCV_JAVA_MODULES "${OPENCV_MODULE_${the_module}_REQ_DEPS};${OPENCV_MODULE_${the_module}_OPT_DEPS}") foreach(module ${OPENCV_JAVA_MODULES}) if(NOT HAVE_opencv_${module}) @@ -18,78 +17,71 @@ foreach(module ${OPENCV_JAVA_MODULES}) endif() endforeach() -set(target ${the_module}) -ocv_include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp") - set(GEN_JAVA "${CMAKE_CURRENT_SOURCE_DIR}/gen_java.py") set(HDR_PARSER "${CMAKE_CURRENT_SOURCE_DIR}/../python/src2/hdr_parser.py") set(GEN_JAVADOC "${CMAKE_CURRENT_SOURCE_DIR}/gen_javadoc.py") set(RST_PARSER "${CMAKE_CURRENT_SOURCE_DIR}/rst_parser.py") set(CHECK_TEST_COVERAGE "${CMAKE_CURRENT_SOURCE_DIR}/check-tests.py") +# add dependencies to cmake (we should rerun cmake if any of these scripts is modified) +configure_file("${GEN_JAVA}" "${CMAKE_BINARY_DIR}/junk/gen_java.junk" COPYONLY) +configure_file("${HDR_PARSER}" "${CMAKE_BINARY_DIR}/junk/hdr_parser.junk" COPYONLY) + +set(java_hdr_deps "") +set(generated_cpp_sources "") +set(generated_java_sources "") + # setup raw java and cpp files generation (without javadoc and at temporary location) foreach(module ${OPENCV_JAVA_MODULES}) # get list of module headers if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/config/${module}.filelist") - file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/config/${module}.filelist" headers_to_parse) - set(module_cheaders "") - set(module_cppheaders "") - foreach(header ${headers_to_parse}) - list(APPEND module_cppheaders "${CMAKE_CURRENT_SOURCE_DIR}/../${module}/${header}") - endforeach() + file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/config/${module}.filelist" module_headers) + ocv_list_add_prefix(module_headers "${OPENCV_MODULE_opencv_${module}_LOCATION}/") else() - file(GLOB module_cheaders "${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include/opencv2/${module}/*.h") - file(GLOB module_cppheaders "${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include/opencv2/${module}/*.hpp") - list(SORT module_cheaders) - list(SORT module_cppheaders) + set(module_headers "${OPENCV_MODULE_opencv_${module}_HEADERS}") endif() + # C headers must go first + set(module_headers_cpp ${module_headers}) + ocv_list_filterout(module_headers_cpp "\\\\.h$") + if(module_headers_cpp) + list(REMOVE_ITEM module_headers ${module_headers_cpp}) + list(APPEND module_headers ${module_headers_cpp}) + endif() + unset(module_headers_cpp) + # add dependencies to cmake (we should rerun cmake if any of these headers is modified) - foreach(header ${module_cheaders} ${module_cppheaders}) + foreach(header ${module_headers}) get_filename_component(header_name "${header}" NAME_WE) configure_file("${header}" "${CMAKE_BINARY_DIR}/junk/${header_name}.junk" COPYONLY) endforeach() - # the same about gen_java.py and hdr_parser.py - configure_file("${GEN_JAVA}" "${CMAKE_BINARY_DIR}/junk/gen_java.junk" COPYONLY) - configure_file("${HDR_PARSER}" "${CMAKE_BINARY_DIR}/junk/hdr_parser.junk" COPYONLY) - # first run (to get list of generated files) + file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out") - execute_process(COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_cheaders} ${module_cppheaders} + execute_process(COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_headers} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out" OUTPUT_QUIET ERROR_QUIET) + file(GLOB_RECURSE ${module}_generated_java_sources RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/" "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/*.java") + ocv_list_add_prefix(${module}_generated_java_sources "${CMAKE_CURRENT_BINARY_DIR}/") - # create list of generated files - file(GLOB_RECURSE generated_java_sources RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/" "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/*.java") - file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/") - - set(${module}_generated_java_sources) - foreach(f ${generated_java_sources}) - list(APPEND ${module}_generated_java_sources "${CMAKE_CURRENT_BINARY_DIR}/${f}") - endforeach() + # second run (at build time) + add_custom_command(OUTPUT ${${module}_generated_java_sources} "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp" + COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_headers} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS "${GEN_JAVA}" "${HDR_PARSER}" ${module_headers}) - # second run - add_custom_command( - OUTPUT ${${module}_generated_java_sources} - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp" - COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_cheaders} ${module_cppheaders} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS "${GEN_JAVA}" - DEPENDS "${HDR_PARSER}" - DEPENDS ${module_cheaders} - DEPENDS ${module_cppheaders} - ) + list(APPEND java_hdr_deps ${module_headers}) + list(APPEND generated_cpp_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp") + list(APPEND generated_java_sources ${${module}_generated_java_sources}) endforeach() -file(GLOB handwrittren_cpp_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.cpp") +# get handwritten files used for wrappers generation file(GLOB handwrittren_h_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.hpp") +file(GLOB handwrittren_cpp_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.cpp") file(GLOB handwrittren_java_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/java/*.java") -set(generated_cpp_sources) -set(generated_java_sources) -set(documented_java_files) -set(undocumented_java_files) +# remove handwritten java files for disabled modules foreach(jfile ${handwrittren_java_sources}) string(REGEX REPLACE "^.*/([^+]+)\\+.*\\.java$" "\\1" jmodname "${jfile}") if(DEFINED HAVE_opencv_${jmodname} AND NOT HAVE_opencv_${jmodname}) @@ -97,42 +89,36 @@ foreach(jfile ${handwrittren_java_sources}) endif() endforeach() -foreach(module ${OPENCV_JAVA_MODULES}) - list(APPEND generated_cpp_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp") - list(APPEND generated_java_sources ${${module}_generated_java_sources}) -endforeach() +# remove VideoCapture wrapper if highgui is disabled +if(NOT HAVE_opencv_highgui) + list(REMOVE_ITEM handwrittren_cpp_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/VideoCapture.cpp") +endif() -# all needed includes -foreach(module ${OPENCV_MODULE_${the_module}_DEPS}) - string(REPLACE "opencv_" "" module "${module}") - ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include") -endforeach() - -# created list of documented files targets +# create list of javadoc documented files +unset(documented_java_files) foreach(java_file ${handwrittren_java_sources} ${generated_java_sources}) get_filename_component(java_file_name "${java_file}" NAME_WE) - if(NOT java_file_name MATCHES ".*-jdoc$") - list(APPEND documented_java_files "${CMAKE_CURRENT_BINARY_DIR}/${java_file_name}-jdoc.java") - list(APPEND undocumented_java_files "${java_file}") - endif() + list(APPEND documented_java_files "${CMAKE_CURRENT_BINARY_DIR}/${java_file_name}-jdoc.java") endforeach() # generate javadoc files file(GLOB_RECURSE refman_rst_headers "${CMAKE_CURRENT_SOURCE_DIR}/../*.rst") +set(java_documented_headers_deps ${handwrittren_java_sources} ${generated_java_sources} ${java_hdr_deps} ${refman_rst_headers} + "${GEN_JAVADOC}" "${RST_PARSER}" "${GEN_JAVA}" "${HDR_PARSER}") + +#TODO: pass list of modules add_custom_command( OUTPUT ${documented_java_files} COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVADOC}" "${CMAKE_CURRENT_SOURCE_DIR}/src/java" "${CMAKE_CURRENT_BINARY_DIR}" 2>"${CMAKE_CURRENT_BINARY_DIR}/get_javadoc_errors.log" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${undocumented_java_files} - DEPENDS "${GEN_JAVADOC}" - DEPENDS "${RST_PARSER}" - DEPENDS ${refman_rst_headers} + DEPENDS ${java_documented_headers_deps} ) # copy generated java files to the final location set(JAVA_OUTPUT_DIR "src/org/opencv") -set(java_files) +# copy each documented header to the final destination +set(java_files "") foreach(java_file ${documented_java_files}) get_filename_component(java_file_name "${java_file}" NAME) string(REPLACE "-jdoc.java" ".java" java_file_name "${java_file_name}") @@ -141,25 +127,24 @@ foreach(java_file ${documented_java_files}) add_custom_command( OUTPUT "${CMAKE_BINARY_DIR}/${JAVA_OUTPUT_DIR}/${java_file_name}" COMMAND ${CMAKE_COMMAND} -E copy "${java_file}" "${CMAKE_BINARY_DIR}/${JAVA_OUTPUT_DIR}/${java_file_name}" - DEPENDS "${java_file}" + MAIN_DEPENDENCY "${java_file}" + DEPENDS ${java_documented_headers_deps} COMMENT "Generating ${JAVA_OUTPUT_DIR}/${java_file_name}" ) list(APPEND java_files "${CMAKE_BINARY_DIR}/${JAVA_OUTPUT_DIR}/${java_file_name}") - + if(ANDROID) get_filename_component(install_subdir "${java_file_name}" PATH) install(FILES "${CMAKE_BINARY_DIR}/${JAVA_OUTPUT_DIR}/${java_file_name}" DESTINATION ${JAVA_OUTPUT_DIR}/${install_subdir} COMPONENT main) endif() endforeach() - # custom target for java API -set(api_target ${target}_api) -add_custom_target(${api_target} DEPENDS ${java_files}) - +set(api_target ${the_module}_api) +add_custom_target(${api_target} DEPENDS ${java_files} ${documented_java_files} ${java_documented_headers_deps}) # add opencv_java library -add_library(${target} SHARED ${handwrittren_h_sources} ${handwrittren_cpp_sources} ${generated_cpp_sources}) +add_library(${the_module} SHARED ${handwrittren_h_sources} ${handwrittren_cpp_sources} ${generated_cpp_sources}) if(BUILD_FAT_JAVA_LIB) set(__deps ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULES_BUILD}) list(REMOVE_ITEM __deps ${the_module}) @@ -170,51 +155,51 @@ if(BUILD_FAT_JAVA_LIB) list(REMOVE_ITEM __deps ${__extradeps}) endif() - target_link_libraries(${target} -Wl,-whole-archive ${__deps} -Wl,-no-whole-archive ${__extradeps} ${OPENCV_LINKER_LIBS}) + target_link_libraries(${the_module} -Wl,-whole-archive ${__deps} -Wl,-no-whole-archive ${__extradeps} ${OPENCV_LINKER_LIBS}) else() - target_link_libraries(${target} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS}) + target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS}) endif() -add_dependencies(${target} ${api_target}) +add_dependencies(${the_module} ${api_target}) # Additional target properties -set_target_properties(${target} PROPERTIES - OUTPUT_NAME "${target}" +set_target_properties(${the_module} PROPERTIES + OUTPUT_NAME "${the_module}" ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} INSTALL_NAME_DIR ${OPENCV_LIB_INSTALL_PATH} LINK_INTERFACE_LIBRARIES "" ) -install(TARGETS ${target} LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main) +install(TARGETS ${the_module} LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main) if(ANDROID) - target_link_libraries(${target} jnigraphics) + target_link_libraries(${the_module} jnigraphics) # for Mat <=> Bitmap converters - # force strip library after build command - # because samples and tests will make a copy of library before install + # force strip library after the build command + # because samples and tests will make a copy of the library before install + get_target_property(__opencv_java_location ${the_module} LOCATION) add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND ${CMAKE_STRIP} --strip-unneeded "${LIBRARY_OUTPUT_PATH}/lib${target}.so" + TARGET ${the_module} POST_BUILD + COMMAND ${CMAKE_STRIP} --strip-unneeded "${__opencv_java_location}" ) set(lib_proj_files "") - # library project blank - file(GLOB_RECURSE android_lib_project_files "${CMAKE_CURRENT_SOURCE_DIR}/android/*") - foreach(file ${android_lib_project_files}) - if(NOT file MATCHES "\\.svn") - file(RELATIVE_PATH file_rel "${CMAKE_CURRENT_SOURCE_DIR}/android/" "${file}") - add_custom_command( - OUTPUT "${CMAKE_BINARY_DIR}/${file_rel}" - COMMAND ${CMAKE_COMMAND} -E copy "${file}" "${CMAKE_BINARY_DIR}/${file_rel}" - DEPENDS "${file}" - COMMENT "Generating ${file_rel}" - ) - - list(APPEND lib_proj_files "${CMAKE_BINARY_DIR}/${file_rel}") - if(NOT file_rel MATCHES "jni/.+") - install(FILES "${CMAKE_BINARY_DIR}/${file_rel}" DESTINATION . COMPONENT main) + # manifest, jni, Eclipse project + file(GLOB_RECURSE android_lib_project_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/android/" "${CMAKE_CURRENT_SOURCE_DIR}/android/*") + foreach(f ${android_lib_project_files}) + if(NOT f MATCHES "\\.svn") + add_custom_command( + OUTPUT "${CMAKE_BINARY_DIR}/${f}" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/android/${f}" "${CMAKE_BINARY_DIR}/${f}" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/android/${f}" + COMMENT "Generating ${f}" + ) + + list(APPEND lib_proj_files "${CMAKE_BINARY_DIR}/${f}") + + if(NOT f MATCHES "jni/.+") + install(FILES "${CMAKE_BINARY_DIR}/${f}" DESTINATION . COMPONENT main) endif() endif() endforeach() @@ -226,30 +211,52 @@ if(ANDROID) OUTPUT "${CMAKE_BINARY_DIR}/jni/${jni_file_name}" COMMAND ${CMAKE_COMMAND} -E copy "${jni_file}" "${CMAKE_BINARY_DIR}/jni/${jni_file_name}" COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/jni/${jni_file_name}" - DEPENDS "${jni_file}" + DEPENDS "${jni_file}" ${java_hdr_deps} COMMENT "Generating jni/${jni_file_name}" ) list(APPEND lib_proj_files "${CMAKE_BINARY_DIR}/jni/${jni_file_name}") - endforeach() - - # create Android library project in build folder - set(lib_target ${target}_android_library) - add_custom_target(${lib_target} - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/res" - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/gen" - DEPENDS ${lib_proj_files} - ) - if(ANT_EXECUTABLE AND ANDROID_EXECUTABLE AND ANDROID_TOOLS_Pkg_Revision GREATER 13) - add_custom_command(TARGET ${target} - COMMAND ${ANDROID_EXECUTABLE} update lib-project --target "${ANDROID_SDK_TARGET}" --path "${CMAKE_BINARY_DIR}" - COMMAND ${ANT_EXECUTABLE} debug - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - DEPENDS ${lib_target} - ) - endif() + endforeach() - add_dependencies(${lib_target} ${api_target}) - add_dependencies(${target} ${lib_target}) + # create Android library project in build folder + if(ANDROID_EXECUTABLE) + set(lib_target ${the_module}_android_library) + + set(lib_target_files ${ANDROID_LIB_PROJECT_FILES}) + ocv_list_add_prefix(lib_target_files "${CMAKE_BINARY_DIR}/") + + android_get_compatible_target(lib_target_sdk_target 8) + + add_custom_command( + OUTPUT ${lib_target_files} + COMMAND ${CMAKE_COMMAND} -E remove ${lib_target_files} + COMMAND ${ANDROID_EXECUTABLE} --silent create lib-project --path \"${CMAKE_BINARY_DIR}\" --target \"${lib_target_sdk_target}\" --name OpenCV --package org.opencv 2>\"${CMAKE_CURRENT_BINARY_DIR}/create_lib_project.log\" + MAIN_DEPENDENCY "${CMAKE_BINARY_DIR}/${ANDROID_MANIFEST_FILE}" + DEPENDS ${lib_proj_files} + COMMENT "Generating OpenCV Android library project. SDK target: ${lib_target_sdk_target}" + ) + install(FILES "${CMAKE_BINARY_DIR}/${ANDROID_PROJECT_PROPERTIES_FILE}" DESTINATION . COMPONENT main) + + if(ANT_EXECUTABLE AND ANDROID_TOOLS_Pkg_Revision GREATER 13) + # build the library project + # normally we should do this after a native part, but for a library project we can build the java part first + add_custom_command( + OUTPUT "${CMAKE_BINARY_DIR}/bin/classes.jar" + COMMAND ${ANT_EXECUTABLE} -q -noinput -k debug + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + DEPENDS ${lib_proj_files} ${lib_target_files} ${java_files} + COMMENT "Building OpenCV Android library project" + ) + install(FILES "${CMAKE_BINARY_DIR}/bin/classes.jar" DESTINATION bin COMPONENT main) + list(APPEND lib_target_files "${CMAKE_BINARY_DIR}/bin/classes.jar") + endif() + + add_custom_target(${lib_target} + SOURCES ${lib_proj_files} ${lib_target_files} + ) + + add_dependencies(${lib_target} ${api_target}) + add_dependencies(${the_module} ${lib_target}) + endif() endif(ANDROID) #android test project @@ -257,9 +264,10 @@ ocv_check_dependencies(${OPENCV_MODULE_${the_module}_OPT_DEPS}) if(BUILD_TESTS AND OCV_DEPENDENCIES_FOUND) add_android_project(opencv_test_java "${CMAKE_CURRENT_SOURCE_DIR}/android_test") - add_custom_command( + if(PYTHON_EXECUTABLE) + add_custom_command( TARGET opencv_test_java_android_project POST_BUILD COMMAND ${PYTHON_EXECUTABLE} ${CHECK_TEST_COVERAGE} "${CMAKE_CURRENT_SOURCE_DIR}/android_test/src" "${CMAKE_BINARY_DIR}/src" > "${CMAKE_CURRENT_BINARY_DIR}/tests_coverage.log" ) + endif() endif() - diff --git a/modules/java/android/default.properties b/modules/java/android/default.properties deleted file mode 100644 index 863e85023..000000000 --- a/modules/java/android/default.properties +++ /dev/null @@ -1,12 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "build.properties", and override values to adapt the script to your -# project structure. - -android.library=true -# Project target. -target=android-8 diff --git a/modules/java/android/project.properties b/modules/java/android/project.properties deleted file mode 100644 index 863e85023..000000000 --- a/modules/java/android/project.properties +++ /dev/null @@ -1,12 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "build.properties", and override values to adapt the script to your -# project structure. - -android.library=true -# Project target. -target=android-8 diff --git a/modules/java/android_test/AndroidManifest.xml b/modules/java/android_test/AndroidManifest.xml index 337afabdc..c0f23c25d 100644 --- a/modules/java/android_test/AndroidManifest.xml +++ b/modules/java/android_test/AndroidManifest.xml @@ -3,16 +3,26 @@ package="org.opencv.test" android:versionCode="1" android:versionName="1.0"> - - - - + + + + + + - + \ No newline at end of file