diff --git a/apps/createsamples/CMakeLists.txt b/apps/createsamples/CMakeLists.txt index 591a0b8bca..8acd288ac1 100644 --- a/apps/createsamples/CMakeLists.txt +++ b/apps/createsamples/CMakeLists.txt @@ -35,5 +35,5 @@ if(INSTALL_CREATE_DISTRIB) install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev) endif() else() - install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev) + install(TARGETS ${the_target} OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev) endif() diff --git a/apps/traincascade/CMakeLists.txt b/apps/traincascade/CMakeLists.txt index 59d48172da..78101c0bc5 100644 --- a/apps/traincascade/CMakeLists.txt +++ b/apps/traincascade/CMakeLists.txt @@ -35,5 +35,5 @@ if(INSTALL_CREATE_DISTRIB) install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev) endif() else() - install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev) + install(TARGETS ${the_target} OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev) endif() diff --git a/cmake/OpenCVGenPkgconfig.cmake b/cmake/OpenCVGenPkgconfig.cmake index fa57db9d3c..a8686e89cd 100644 --- a/cmake/OpenCVGenPkgconfig.cmake +++ b/cmake/OpenCVGenPkgconfig.cmake @@ -37,6 +37,7 @@ ocv_list_reverse(OpenCV_EXTRA_COMPONENTS) #build the list of components set(OpenCV_LIB_COMPONENTS_ "") foreach(CVLib ${OpenCV_LIB_COMPONENTS}) + if (TARGET ${CVLib}) get_target_property(libpath ${CVLib} LOCATION_${CMAKE_BUILD_TYPE}) get_filename_component(libname "${libpath}" NAME) @@ -52,6 +53,7 @@ foreach(CVLib ${OpenCV_LIB_COMPONENTS}) endif() set(OpenCV_LIB_COMPONENTS_ "${OpenCV_LIB_COMPONENTS_} \${exec_prefix}/${installDir}/${libname}") + endif() endforeach() # add extra dependencies required for OpenCV diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index fa02919633..90068dedef 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -19,6 +19,8 @@ # OPENCV_MODULE_${the_module}_PRIVATE_REQ_DEPS # OPENCV_MODULE_${the_module}_PRIVATE_OPT_DEPS # OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD +# OPENCV_MODULE_${the_module}_CUDA_OBJECTS - compiled CUDA objects list +# OPENCV_MODULE_${the_module}_CHILDREN - list of submodules for compound modules # HAVE_${the_module} - for fast check of module availability # To control the setup of the module you could also set: @@ -26,6 +28,7 @@ # OPENCV_MODULE_TYPE - STATIC|SHARED - set to force override global settings for current module # OPENCV_MODULE_IS_PART_OF_WORLD - ON|OFF (default ON) - should the module be added to the opencv_world? # BUILD_${the_module}_INIT - ON|OFF (default ON) - initial value for BUILD_${the_module} +# OPENCV_MODULE_CHILDREN - list of submodules # The verbose template for OpenCV module: # @@ -158,13 +161,9 @@ macro(ocv_add_module _name) endif() # add self to the world dependencies - # add to world only extra modules (ON) or only main modules (OFF) - set(__expected_extra 0) - if (OPENCV_EXTRA_WORLD) - set(__expected_extra 1) - endif() - if((NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" - AND __expected_extra EQUAL OPENCV_PROCESSING_EXTRA_MODULES) + if((NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD + AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" + AND NOT OPENCV_PROCESSING_EXTRA_MODULES) OR OPENCV_MODULE_IS_PART_OF_WORLD ) set(OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD ON CACHE INTERNAL "") @@ -179,7 +178,8 @@ macro(ocv_add_module _name) 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 + # add submodules if any + set(OPENCV_MODULE_${the_module}_CHILDREN "${OPENCV_MODULE_CHILDREN}" CACHE INTERNAL "List of ${the_module} submodules") # stop processing of current file return() @@ -306,27 +306,42 @@ endfunction() # sort modules by dependencies function(__ocv_sort_modules_by_deps __lst) ocv_list_sort(${__lst}) - set(${__lst}_ORDERED ${${__lst}} CACHE INTERNAL "") - set(__result "") - foreach (m ${${__lst}}) - list(LENGTH __result __lastindex) - set(__index ${__lastindex}) - foreach (__d ${__result}) - set(__deps "${OPENCV_MODULE_${__d}_DEPS}") - if(";${__deps};" MATCHES ";${m};") - list(FIND __result "${__d}" __i) - if(__i LESS "${__index}") - set(__index "${__i}") + set(input ${${__lst}}) + set(result "") + while(input) + list(LENGTH input length_before) + foreach (m ${input}) + # check if module is in the result already + if (NOT ";${result};" MATCHES ";${m};") + # scan through module dependencies... + set(unresolved_deps_found FALSE) + foreach (d ${OPENCV_MODULE_${m}_CHILDREN} ${OPENCV_MODULE_${m}_DEPS}) + # ... which are not already in the result and are enabled + if ((NOT ";${result};" MATCHES ";${d};") AND HAVE_${d}) + set(unresolved_deps_found TRUE) + break() + endif() + endforeach() + # chek if all dependencies for this module has been resolved + if (NOT unresolved_deps_found) + list(APPEND result ${m}) + list(REMOVE_ITEM input ${m}) endif() endif() endforeach() - if(__index STREQUAL __lastindex) - list(APPEND __result "${m}") - else() - list(INSERT __result ${__index} "${m}") + list(LENGTH input length_after) + # check for infinite loop or unresolved dependencies + if (NOT length_after LESS length_before) + message(WARNING "Unresolved dependencies or loop in dependency graph (${length_after})\n" + "Processed ${__lst}: ${${__lst}}\n" + "Good modules: ${result}\n" + "Bad modules: ${input}" + ) + list(APPEND result ${input}) + break() endif() - endforeach() - set(${__lst} "${__result}" PARENT_SCOPE) + endwhile() + set(${__lst} "${result}" PARENT_SCOPE) endfunction() # resolve dependensies @@ -645,9 +660,43 @@ macro(_ocv_create_module) get_native_precompiled_header(${the_module} precomp.hpp) endif() + set(sub_objs "") + set(sub_links "") + set(cuda_objs "") + if (DEFINED OPENCV_MODULE_${the_module}_CHILDREN) + status("Complex module ${the_module}") + foreach (m ${OPENCV_MODULE_${the_module}_CHILDREN}) + if (BUILD_${m} AND TARGET ${m}_object) # ambigous? + get_target_property(_sub_links ${m} LINK_LIBRARIES) + list(APPEND sub_objs $) + list(APPEND sub_links ${_sub_links}) + status(" + ${m}") + else() + status(" - ${m}") + endif() + list(APPEND cuda_objs ${OPENCV_MODULE_${m}_CUDA_OBJECTS}) + endforeach() + endif() + ocv_add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" - ${${the_module}_pch}) + ${${the_module}_pch} ${sub_objs}) + + if (cuda_objs) + target_link_libraries(${the_module} ${cuda_objs}) + endif() + + # TODO: is it needed? + if (sub_links) + ocv_list_filterout(sub_links "^opencv_") + ocv_list_unique(sub_links) + target_link_libraries(${the_module} ${sub_links}) + endif() + + unset(sub_objs) + unset(sub_links) + unset(cuda_objs) + if(NOT the_module STREQUAL opencv_ts) set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS OPENCV_NOSTL) endif() @@ -686,6 +735,7 @@ macro(_ocv_create_module) if((NOT DEFINED OPENCV_MODULE_TYPE AND BUILD_SHARED_LIBS) OR (DEFINED OPENCV_MODULE_TYPE AND OPENCV_MODULE_TYPE STREQUAL SHARED)) + set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS CVAPI_EXPORTS) set_target_properties(${the_module} PROPERTIES DEFINE_SYMBOL CVAPI_EXPORTS) endif() @@ -696,22 +746,35 @@ macro(_ocv_create_module) set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libc /DEBUG") endif() - ocv_install_target(${the_module} EXPORT OpenCVModules + ocv_install_target(${the_module} EXPORT OpenCVModules OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs ARCHIVE DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT dev ) - # only "public" headers need to be installed - if(OPENCV_MODULE_${the_module}_HEADERS AND ";${OPENCV_MODULES_PUBLIC};" MATCHES ";${the_module};") - foreach(hdr ${OPENCV_MODULE_${the_module}_HEADERS}) - string(REGEX REPLACE "^.*opencv2/" "opencv2/" hdr2 "${hdr}") - if(NOT hdr2 MATCHES "opencv2/${the_module}/private.*" AND hdr2 MATCHES "^(opencv2/?.*)/[^/]+.h(..)?$" ) - install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT dev) - endif() - endforeach() - endif() + foreach(m ${OPENCV_MODULE_${the_module}_CHILDREN} ${the_module}) + # only "public" headers need to be installed + if(OPENCV_MODULE_${m}_HEADERS AND ";${OPENCV_MODULES_PUBLIC};" MATCHES ";${m};") + foreach(hdr ${OPENCV_MODULE_${m}_HEADERS}) + string(REGEX REPLACE "^.*opencv2/" "opencv2/" hdr2 "${hdr}") + if(NOT hdr2 MATCHES "opencv2/${m}/private.*" AND hdr2 MATCHES "^(opencv2/?.*)/[^/]+.h(..)?$" ) + install(FILES ${hdr} OPTIONAL DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT dev) + endif() + endforeach() + endif() + endforeach() + _ocv_add_precompiled_headers(${the_module}) + + if (TARGET ${the_module}_object) + # copy COMPILE_DEFINITIONS + get_target_property(main_defs ${the_module} COMPILE_DEFINITIONS) + set_target_properties(${the_module}_object PROPERTIES COMPILE_DEFINITIONS ${main_defs}) + # use same PCH + if (TARGET pch_Generate_${the_module}) + add_dependencies(${the_module}_object pch_Generate_${the_module} ) + endif() + endif() endmacro() # opencv precompiled headers macro (can add pch to modules and tests) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 60d862efca..40112d5fbd 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -756,6 +756,9 @@ endfunction() function(_ocv_append_target_includes target) if(DEFINED OCV_TARGET_INCLUDE_DIRS_${target}) target_include_directories(${target} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}}) + if (TARGET ${target}_object) + target_include_directories(${target}_object PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}}) + endif() unset(OCV_TARGET_INCLUDE_DIRS_${target} CACHE) endif() endfunction() @@ -780,8 +783,22 @@ function(ocv_add_library target) ocv_include_directories(${CUDA_INCLUDE_DIRS}) ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs}) endif() + set(OPENCV_MODULE_${target}_CUDA_OBJECTS ${cuda_objs} CACHE INTERNAL "Compiled CUDA object files") endif() add_library(${target} ${ARGN} ${cuda_objs}) + + # Add OBJECT library to use in compound modules + if (NOT OPENCV_MODULE_${target}_CHILDREN + AND NOT OPENCV_MODULE_${target}_CLASS STREQUAL "BINDINGS" + AND NOT ${target} STREQUAL "opencv_ts" + ) + set(sources ${ARGN}) + ocv_list_filterout(sources "\\\\.(cl|inc)$") + add_library(${target}_object OBJECT EXCLUDE_FROM_ALL ${sources}) + set_target_properties(${target}_object PROPERTIES POSITION_INDEPENDENT_CODE True) + unset(sources) + endif() + _ocv_append_target_includes(${target}) endfunction() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index cb0d40d949..a9d6e22a47 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -38,7 +38,7 @@ endif(HAVE_DOC_GENERATOR) if(BUILD_DOCS AND DOXYGEN_FOUND) # not documented modules list - list(APPEND blacklist "ts" "java" "python2" "python3" "world") + list(APPEND blacklist "ts" "java" "python2" "python3" "world" "contrib_world") # gathering headers set(paths_include) diff --git a/modules/java/CMakeLists.txt b/modules/java/CMakeLists.txt index 25c05bc646..8eb2e89382 100644 --- a/modules/java/CMakeLists.txt +++ b/modules/java/CMakeLists.txt @@ -242,7 +242,7 @@ else(ANDROID) else(WIN32) set(JAR_INSTALL_DIR share/OpenCV/java) endif(WIN32) - install(FILES ${JAR_FILE} DESTINATION ${JAR_INSTALL_DIR} COMPONENT java) + install(FILES ${JAR_FILE} OPTIONAL DESTINATION ${JAR_INSTALL_DIR} COMPONENT java) endif(ANDROID) # step 5: build native part @@ -312,16 +312,16 @@ if(ENABLE_SOLUTION_FOLDERS) endif() if(ANDROID) - ocv_install_target(${the_module} EXPORT OpenCVModules + ocv_install_target(${the_module} OPTIONAL EXPORT OpenCVModules LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT java ARCHIVE DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT java) else() if(NOT INSTALL_CREATE_DISTRIB) - ocv_install_target(${the_module} EXPORT OpenCVModules + ocv_install_target(${the_module} OPTIONAL EXPORT OpenCVModules RUNTIME DESTINATION ${JAR_INSTALL_DIR} COMPONENT java LIBRARY DESTINATION ${JAR_INSTALL_DIR} COMPONENT java) else() - ocv_install_target(${the_module} EXPORT OpenCVModules + ocv_install_target(${the_module} OPTIONAL EXPORT OpenCVModules RUNTIME DESTINATION ${JAR_INSTALL_DIR}/${OpenCV_ARCH} COMPONENT java LIBRARY DESTINATION ${JAR_INSTALL_DIR}/${OpenCV_ARCH} COMPONENT java) endif() diff --git a/modules/python/common.cmake b/modules/python/common.cmake index 593fee4069..dca4e56a9a 100644 --- a/modules/python/common.cmake +++ b/modules/python/common.cmake @@ -20,6 +20,7 @@ ocv_list_filterout(candidate_deps "^opencv_adas$") ocv_list_filterout(candidate_deps "^opencv_tracking$") ocv_list_filterout(candidate_deps "^opencv_bioinspired$") ocv_list_filterout(candidate_deps "^opencv_java$") +ocv_list_filterout(candidate_deps "^opencv_contrib_world$") ocv_add_module(${MODULE_NAME} BINDINGS OPTIONAL ${candidate_deps}) @@ -113,7 +114,7 @@ else() endif() if(NOT INSTALL_CREATE_DISTRIB) - install(TARGETS ${the_module} + install(TARGETS ${the_module} OPTIONAL ${PYTHON_INSTALL_CONFIGURATIONS} RUNTIME DESTINATION ${PYTHON_PACKAGES_PATH} COMPONENT python LIBRARY DESTINATION ${PYTHON_PACKAGES_PATH} COMPONENT python diff --git a/platforms/ios/build_framework.py b/platforms/ios/build_framework.py index 0846e0f589..1acd2b25e8 100755 --- a/platforms/ios/build_framework.py +++ b/platforms/ios/build_framework.py @@ -52,7 +52,6 @@ def build_opencv(srcroot, buildroot, target, arch): cmakeargs = ("-GXcode " + "-DCMAKE_BUILD_TYPE=Release " + "-DCMAKE_TOOLCHAIN_FILE=%s/platforms/ios/cmake/Toolchains/Toolchain-%s_Xcode.cmake " + - "-DBUILD_opencv_world=ON " + "-DCMAKE_C_FLAGS=\"-Wno-implicit-function-declaration\" " + "-DCMAKE_INSTALL_PREFIX=install") % (srcroot, target) @@ -60,7 +59,13 @@ def build_opencv(srcroot, buildroot, target, arch): cmakeargs += " -DENABLE_NEON=ON" if opencv_contrib_path is not None: - cmakeargs += " -DOPENCV_EXTRA_MODULES_PATH=%s -DOPENCV_EXTRA_WORLD=ON" % opencv_contrib_path + cmakeargs += " -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON -DOPENCV_EXTRA_MODULES_PATH=%s -DBUILD_opencv_contrib_world=ON" % opencv_contrib_path + build_target = "opencv_contrib_world" + libname = "libopencv_contrib_world.a" + else: + cmakeargs += " -DBUILD_opencv_world=ON" + build_target = "ALL_BUILD" + libname = "libopencv_world.a" # if cmake cache exists, just rerun cmake to update OpenCV.xcodeproj if necessary if os.path.isfile(os.path.join(builddir, "CMakeCache.txt")): @@ -68,12 +73,12 @@ def build_opencv(srcroot, buildroot, target, arch): else: execute("cmake %s %s" % (cmakeargs, srcroot)) - for wlib in [builddir + "/modules/world/UninstalledProducts/libopencv_world.a", - builddir + "/lib/Release/libopencv_world.a"]: + for wlib in [builddir + "/modules/world/UninstalledProducts/" + libname, + builddir + "/lib/Release/" + libname]: if os.path.isfile(wlib): os.remove(wlib) - execute("xcodebuild IPHONEOS_DEPLOYMENT_TARGET=6.0 -parallelizeTargets ARCHS=%s -jobs 8 -sdk %s -configuration Release -target ALL_BUILD" % (arch, target.lower())) + execute("xcodebuild IPHONEOS_DEPLOYMENT_TARGET=6.0 -parallelizeTargets ARCHS=%s -jobs 8 -sdk %s -configuration Release -target %s" % (arch, target.lower(), build_target)) execute("xcodebuild IPHONEOS_DEPLOYMENT_TARGET=6.0 ARCHS=%s -sdk %s -configuration Release -target install install" % (arch, target.lower())) os.chdir(currdir) @@ -81,6 +86,7 @@ def put_framework_together(srcroot, dstroot): "constructs the framework directory after all the targets are built" name = "opencv2" if opencv_contrib_path is None else "opencv2_contrib" + libname = "libopencv_world.a" if opencv_contrib_path is None else "libopencv_contrib_world.a" # find the list of targets (basically, ["iPhoneOS", "iPhoneSimulator"]) targetlist = glob.glob(os.path.join(dstroot, "build", "*")) @@ -103,7 +109,7 @@ def put_framework_together(srcroot, dstroot): shutil.copytree(tdir0 + "/install/include/opencv2", dstdir + "/Headers") # make universal static lib - wlist = " ".join(["../build/" + t + "/lib/Release/libopencv_world.a" for t in targetlist]) + wlist = " ".join(["../build/" + t + "/lib/Release/" + libname for t in targetlist]) execute("lipo -create " + wlist + " -o " + dstdir + "/%s" % name) # copy Info.plist