Skip to content

Commit

Permalink
cmake: customize OpenCV build via CMake script hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
alalek committed Feb 15, 2018
1 parent cff7960 commit 36f11a5
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 6 deletions.
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -336,6 +347,7 @@ endif()
# ----------------------------------------------------------------------------
include(cmake/OpenCVVersion.cmake)

ocv_cmake_hook(POST_OPTIONS)

# ----------------------------------------------------------------------------
# Build & install layouts
Expand Down Expand Up @@ -531,13 +543,17 @@ 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)
endif()

include(cmake/OpenCVCompilerOptions.cmake)

ocv_cmake_hook(POST_COMPILER_OPTIONS)

# ----------------------------------------------------------------------------
# CHECK FOR SYSTEM LIBRARIES, OPTIONS, ETC..
# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -767,6 +783,7 @@ if(CV_TRACE)
include(cmake/OpenCVDetectTrace.cmake)
endif()

ocv_cmake_hook(POST_DETECT_DEPENDECIES)

# ----------------------------------------------------------------------------
# Solution folders:
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -1459,6 +1478,8 @@ status("")

ocv_finalize_status()

ocv_cmake_hook(POST_FINALIZE)

# ----------------------------------------------------------------------------
# CPack stuff
# ----------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions cmake/OpenCVGenConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
32 changes: 29 additions & 3 deletions cmake/OpenCVModule.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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 "")
Expand Down Expand Up @@ -256,7 +262,8 @@ endmacro()
# otherwise all first-level subfolders containing CMakeLists.txt are accepted.
# Usage: _glob_locations(<output paths list> <output names list> <folder> [<folder> ...])
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)
Expand Down Expand Up @@ -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)
Expand All @@ -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()

Expand All @@ -348,6 +357,7 @@ endfunction()
# NB: must be called only once!
# Usage: ocv_glob_modules(<main location> [<extra location> ...])
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()
Expand All @@ -359,18 +369,23 @@ 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()

# 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()


Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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}")
Expand All @@ -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)
Expand Down
11 changes: 8 additions & 3 deletions cmake/OpenCVPackaging.cmake
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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)
46 changes: 46 additions & 0 deletions cmake/OpenCVUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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}})
Expand Down

0 comments on commit 36f11a5

Please sign in to comment.