diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cc936a83f..a8163b3338 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,16 @@ if(POLICY CMP0067) endif() include(cmake/OpenCVUtils.cmake) +ocv_cmake_reset_hooks() +ocv_check_environment_variables(OPENCV_CMAKE_HOOKS_DIR) +if(DEFINED OPENCV_CMAKE_HOOKS_DIR) + foreach(__dir ${OPENCV_CMAKE_HOOKS_DIR}) + get_filename_component(__dir "${__dir}" ABSOLUTE) + ocv_cmake_hook_register_dir(${__dir}) + endforeach() +endif() + +ocv_cmake_hook(CMAKE_INIT) # must go before the project command ocv_update(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) @@ -141,6 +151,7 @@ endif() # ---------------------------------------------------------------------------- OCV_OPTION(ENABLE_CXX11 "Enable C++11 compilation mode" "${OPENCV_CXX11}") include(cmake/OpenCVDetectCXXCompiler.cmake) +ocv_cmake_hook(POST_DETECT_COMPILER) # Add these standard paths to the search paths for FIND_LIBRARY # to find libraries from these locations first @@ -336,6 +347,7 @@ endif() # ---------------------------------------------------------------------------- include(cmake/OpenCVVersion.cmake) +ocv_cmake_hook(POST_OPTIONS) # ---------------------------------------------------------------------------- # Build & install layouts @@ -531,6 +543,8 @@ if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja" AND "${CMAKE_BUILD_TYPE}" STREQUAL set(CMAKE_BUILD_TYPE Release) endif() +ocv_cmake_hook(POST_CMAKE_BUILD_OPTIONS) + # --- Python Support --- if(NOT IOS) include(cmake/OpenCVDetectPython.cmake) @@ -538,6 +552,8 @@ endif() include(cmake/OpenCVCompilerOptions.cmake) +ocv_cmake_hook(POST_COMPILER_OPTIONS) + # ---------------------------------------------------------------------------- # CHECK FOR SYSTEM LIBRARIES, OPTIONS, ETC.. # ---------------------------------------------------------------------------- @@ -767,6 +783,7 @@ if(CV_TRACE) include(cmake/OpenCVDetectTrace.cmake) endif() +ocv_cmake_hook(POST_DETECT_DEPENDECIES) # ---------------------------------------------------------------------------- # Solution folders: @@ -816,6 +833,8 @@ endif() # Finalization: generate configuration-based files # ---------------------------------------------------------------------------- +ocv_cmake_hook(PRE_FINALIZE) + # Generate platform-dependent and configuration-dependent headers include(cmake/OpenCVGenHeaders.cmake) @@ -1459,6 +1478,8 @@ status("") ocv_finalize_status() +ocv_cmake_hook(POST_FINALIZE) + # ---------------------------------------------------------------------------- # CPack stuff # ---------------------------------------------------------------------------- diff --git a/cmake/OpenCVGenConfig.cmake b/cmake/OpenCVGenConfig.cmake index 57c79f213a..b2ca82bad0 100644 --- a/cmake/OpenCVGenConfig.cmake +++ b/cmake/OpenCVGenConfig.cmake @@ -59,6 +59,7 @@ else() set(USE_IPPIW FALSE) endif() +ocv_cmake_hook(PRE_CMAKE_CONFIG_BUILD) configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" @ONLY) #support for version checking when finding opencv. find_package(OpenCV 2.3.1 EXACT) should now work. configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig-version.cmake" @ONLY) @@ -84,6 +85,7 @@ function(ocv_gen_config TMP_DIR NESTED_PATH ROOT_NAME) file(RELATIVE_PATH OpenCV_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/${__install_nested}" "${CMAKE_INSTALL_PREFIX}/") + ocv_cmake_hook(PRE_CMAKE_CONFIG_INSTALL) configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${TMP_DIR}/OpenCVConfig-version.cmake" @ONLY) configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${__tmp_nested}/OpenCVConfig.cmake" @ONLY) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index fe3978613d..e720cf190c 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -163,16 +163,20 @@ macro(ocv_add_module _name) set(OPENCV_MODULE_${the_module}_LINK_DEPS "" CACHE INTERNAL "") + set(ADD_MODULE_ARGN ${ARGN}) + ocv_cmake_hook(PRE_ADD_MODULE) + ocv_cmake_hook(PRE_ADD_MODULE_${the_module}) + # parse list of dependencies if(" ${ARGV1}" STREQUAL " INTERNAL" OR " ${ARGV1}" STREQUAL " BINDINGS") set(OPENCV_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The category of the module") - set(__ocv_argn__ ${ARGN}) + set(__ocv_argn__ ${ADD_MODULE_ARGN}) list(REMOVE_AT __ocv_argn__ 0) ocv_add_dependencies(${the_module} ${__ocv_argn__}) unset(__ocv_argn__) else() set(OPENCV_MODULE_${the_module}_CLASS "PUBLIC" CACHE INTERNAL "The category of the module") - ocv_add_dependencies(${the_module} ${ARGN}) + ocv_add_dependencies(${the_module} ${ADD_MODULE_ARGN}) if(BUILD_${the_module}) set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of OpenCV modules marked for export") endif() @@ -212,6 +216,8 @@ macro(ocv_add_module _name) endforeach() # stop processing of current file + ocv_cmake_hook(POST_ADD_MODULE) + ocv_cmake_hook(POST_ADD_MODULE_${the_module}) return() else() set(OPENCV_MODULE_${the_module}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "") @@ -256,7 +262,8 @@ endmacro() # otherwise all first-level subfolders containing CMakeLists.txt are accepted. # Usage: _glob_locations( [ ...]) function(_glob_locations out_paths out_names) - foreach(path ${ARGN}) + set(PATHS ${ARGN}) + foreach(path ${PATHS}) #message(STATUS "Inspect: ${path}") list(LENGTH paths before) get_filename_component(path "${path}" ABSOLUTE) @@ -313,6 +320,7 @@ endfunction() function(_add_modules_2) foreach(m ${ARGN}) set(the_module "${m}") + ocv_cmake_hook(PRE_MODULES_CREATE_${the_module}) if(BUILD_opencv_world AND m STREQUAL "opencv_world" OR NOT BUILD_opencv_world OR NOT OPENCV_MODULE_${m}_IS_PART_OF_WORLD) @@ -323,6 +331,7 @@ function(_add_modules_2) #message(STATUS "Second pass: ${name} => ${OPENCV_MODULE_${m}_LOCATION}") add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${name}") endif() + ocv_cmake_hook(POST_MODULES_CREATE_${the_module}) endforeach() endfunction() @@ -348,6 +357,7 @@ endfunction() # NB: must be called only once! # Usage: ocv_glob_modules(
[ ...]) macro(ocv_glob_modules main_root) + ocv_cmake_hook(INIT_MODULES_GLOB) if(DEFINED OPENCV_INITIAL_PASS) message(FATAL_ERROR "OpenCV has already loaded its modules. Calling ocv_glob_modules second time is not allowed.") endif() @@ -359,10 +369,13 @@ macro(ocv_glob_modules main_root) _assert_uniqueness("Duplicated modules LOCATIONS has been found" ${__main_paths} ${__extra_paths}) _assert_uniqueness("Duplicated modules NAMES has been found" ${__main_names} ${__extra_names}) set(OPENCV_PROCESSING_EXTRA_MODULES 0) + ocv_cmake_hook(PRE_MODULES_SCAN) _add_modules_1(__main_paths __main_names) set(OPENCV_PROCESSING_EXTRA_MODULES 1) + ocv_cmake_hook(PRE_MODULES_SCAN_EXTRA) _add_modules_1(__extra_paths __extra_names) ocv_clear_vars(__main_names __extra_names __main_paths __extra_paths) + ocv_cmake_hook(POST_MODULES_SCAN) # resolve dependencies __ocv_resolve_dependencies() @@ -370,7 +383,9 @@ macro(ocv_glob_modules main_root) # create modules set(OPENCV_INITIAL_PASS OFF PARENT_SCOPE) set(OPENCV_INITIAL_PASS OFF) + ocv_cmake_hook(PRE_MODULES_CREATE) _add_modules_2(${OPENCV_MODULES_BUILD}) + ocv_cmake_hook(POST_MODULES_CREATE) endmacro() @@ -719,6 +734,10 @@ macro(ocv_set_module_sources) list(APPEND OPENCV_MODULE_${the_module}_SOURCES ${OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED}) endif() + # TODO Update hooks above + ocv_cmake_hook(INIT_MODULE_SOURCES) + ocv_cmake_hook(INIT_MODULE_SOURCES_${the_module}) + # use full paths for module to be independent from the module location ocv_convert_to_full_paths(OPENCV_MODULE_${the_module}_HEADERS) @@ -885,6 +904,8 @@ macro(_ocv_create_module) source_group("Include" FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp") source_group("Src" FILES "${${the_module}_pch}") + ocv_cmake_hook(PRE_CREATE_MODULE_LIBRARY) + ocv_cmake_hook(PRE_CREATE_MODULE_LIBRARY_${the_module}) 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} @@ -967,6 +988,8 @@ macro(_ocv_create_module) endif() # only "public" headers need to be installed + ocv_cmake_hook(PRE_INSTALL_MODULE_HEADERS) + ocv_cmake_hook(PRE_INSTALL_MODULE_HEADERS_${the_module}) 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}") @@ -977,6 +1000,9 @@ macro(_ocv_create_module) endif() _ocv_add_precompiled_headers(${the_module}) + + ocv_cmake_hook(POST_CREATE_MODULE_LIBRARY) + ocv_cmake_hook(POST_CREATE_MODULE_LIBRARY_${the_module}) endmacro() # opencv precompiled headers macro (can add pch to modules and tests) diff --git a/cmake/OpenCVPackaging.cmake b/cmake/OpenCVPackaging.cmake index 363e46b7ee..32537982f9 100644 --- a/cmake/OpenCVPackaging.cmake +++ b/cmake/OpenCVPackaging.cmake @@ -1,4 +1,9 @@ -if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") +ocv_cmake_hook(INIT_CPACK) +if(NOT EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") + message(STATUS "CPack is not found. SKIP") + return() +endif() + set(CPACK_set_DESTDIR "on") if(NOT OPENCV_CUSTOM_PACKAGE_INFO) @@ -165,6 +170,6 @@ if(NOT OPENCV_CUSTOM_PACKAGE_INFO) set(CPACK_DEBIAN_COMPONENT_TESTS_NAME "lib${CMAKE_PROJECT_NAME}-tests") endif(NOT OPENCV_CUSTOM_PACKAGE_INFO) +ocv_cmake_hook(PRE_CPACK) include(CPack) - -ENDif(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") +ocv_cmake_hook(POST_CPACK) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 712400c5b2..ae367d74a3 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -21,6 +21,52 @@ function(ocv_cmake_dump_vars) endif() endfunction() + +# +# CMake script hooks support +# +option(OPENCV_DUMP_HOOKS_FLOW "Dump called OpenCV hooks" OFF) +macro(ocv_cmake_hook_append hook_name) + set(__var_name "__OPENCV_CMAKE_HOOKS_${hook_name}") + set(__value "${${__var_name}}") + message(STATUS "Registering hook '${hook_name}': ${ARGN}") + list(APPEND __value ${ARGN}) + set(${__var_name} "${__value}" CACHE INTERNAL "") +endmacro() +macro(ocv_cmake_hook hook_name) + set(__var_name "__OPENCV_CMAKE_HOOKS_${hook_name}") + if(OPENCV_DUMP_HOOKS_FLOW) + message(STATUS "Hook ${hook_name} ...") + endif() + foreach(__hook ${${__var_name}}) + #message(STATUS "Hook ${hook_name}: calling '${__hook}' ...") + if(COMMAND "${__hook}") + message(FATAL_ERROR "Indirect calling of CMake commands is not supported yet") + else() + include("${__hook}") + endif() + endforeach() +endmacro() +macro(ocv_cmake_reset_hooks) + get_cmake_property(__variableNames VARIABLES) + foreach(__variableName ${__variableNames}) + if(__variableName MATCHES "^__OPENCV_CMAKE_HOOKS_") + unset(${__variableName}) + unset(${__variableName} CACHE) + endif() + endforeach() +endmacro() +macro(ocv_cmake_hook_register_dir dir) + file(GLOB hook_files RELATIVE "${dir}" "${dir}/*.cmake") + foreach(f ${hook_files}) + if(f MATCHES "^(.+)\\.cmake$") + set(hook_name "${CMAKE_MATCH_1}") + ocv_cmake_hook_append(${hook_name} "${dir}/${f}") + endif() + endforeach() +endmacro() + + function(ocv_cmake_eval var_name) if(DEFINED ${var_name}) file(WRITE "${CMAKE_BINARY_DIR}/CMakeCommand-${var_name}.cmake" ${${var_name}})