OpenCVModule.cmake 38.7 KB
Newer Older
1 2 3 4 5 6 7 8
# Local variables (set for each module):
#
# name       - short name in lower case i.e. core
# the_module - full name in lower case i.e. opencv_core

# Global variables:
#
# OPENCV_MODULE_${the_module}_LOCATION
Alexander Alekhin's avatar
Alexander Alekhin committed
9
# OPENCV_MODULE_${the_module}_BINARY_DIR
10
# OPENCV_MODULE_${the_module}_DESCRIPTION
11
# OPENCV_MODULE_${the_module}_CLASS - PUBLIC|INTERNAL|BINDINGS
12 13 14
# OPENCV_MODULE_${the_module}_HEADERS
# OPENCV_MODULE_${the_module}_SOURCES
# OPENCV_MODULE_${the_module}_DEPS - final flattened set of module dependencies
Alexander Alekhin's avatar
Alexander Alekhin committed
15
# OPENCV_MODULE_${the_module}_DEPS_TO_LINK - differs from above for world build only
16
# OPENCV_MODULE_${the_module}_DEPS_EXT - non-module dependencies
17 18
# OPENCV_MODULE_${the_module}_REQ_DEPS
# OPENCV_MODULE_${the_module}_OPT_DEPS
19 20
# OPENCV_MODULE_${the_module}_PRIVATE_REQ_DEPS
# OPENCV_MODULE_${the_module}_PRIVATE_OPT_DEPS
Alexander Alekhin's avatar
Alexander Alekhin committed
21
# OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD
22 23 24 25 26
# HAVE_${the_module} - for fast check of module availability

# To control the setup of the module you could also set:
# the_description - text to be used as current module description
# OPENCV_MODULE_TYPE - STATIC|SHARED - set to force override global settings for current module
27 28
# 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}
29 30 31 32

# The verbose template for OpenCV module:
#
#   ocv_add_module(modname <dependencies>)
33 34
#   ocv_glob_module_sources(([EXCLUDE_CUDA] <extra sources&headers>)
#                          or glob them manually and ocv_set_module_sources(...)
35 36 37 38 39 40 41
#   ocv_module_include_directories(<extra include directories>)
#   ocv_create_module()
#   <add extra link dependencies, compiler options, etc>
#   ocv_add_precompiled_headers(${the_module})
#   <add extra installation rules>
#   ocv_add_accuracy_tests(<extra dependencies>)
#   ocv_add_perf_tests(<extra dependencies>)
42
#   ocv_add_samples(<extra dependencies>)
43 44 45 46 47 48 49 50
#
#
# If module have no "extra" then you can define it in one line:
#
#   ocv_define_module(modname <dependencies>)

# clean flags for modules enabled on previous cmake run
# this is necessary to correctly handle modules removal
51
foreach(mod ${OPENCV_MODULES_BUILD} ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO} ${OPENCV_MODULES_DISABLED_FORCE})
52 53 54
  if(HAVE_${mod})
    unset(HAVE_${mod} CACHE)
  endif()
55 56
  unset(OPENCV_MODULE_${mod}_REQ_DEPS CACHE)
  unset(OPENCV_MODULE_${mod}_OPT_DEPS CACHE)
57 58
  unset(OPENCV_MODULE_${mod}_PRIVATE_REQ_DEPS CACHE)
  unset(OPENCV_MODULE_${mod}_PRIVATE_OPT_DEPS CACHE)
Alexander Alekhin's avatar
Alexander Alekhin committed
59
  unset(OPENCV_MODULE_${mod}_LINK_DEPS CACHE)
60 61 62 63 64 65 66 67
endforeach()

# clean modules info which needs to be recalculated
set(OPENCV_MODULES_PUBLIC         "" CACHE INTERNAL "List of OpenCV modules marked for export")
set(OPENCV_MODULES_BUILD          "" CACHE INTERNAL "List of OpenCV modules included into the build")
set(OPENCV_MODULES_DISABLED_USER  "" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user")
set(OPENCV_MODULES_DISABLED_AUTO  "" CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies")
set(OPENCV_MODULES_DISABLED_FORCE "" CACHE INTERNAL "List of OpenCV modules which can not be build in current configuration")
Alexander Alekhin's avatar
Alexander Alekhin committed
68
unset(OPENCV_WORLD_MODULES CACHE)
69 70 71 72 73 74 75

# adds dependencies to OpenCV module
# Usage:
#   add_dependencies(opencv_<name> [REQUIRED] [<list of dependencies>] [OPTIONAL <list of modules>])
# Notes:
# * <list of dependencies> - can include full names of modules or full pathes to shared/static libraries or cmake targets
macro(ocv_add_dependencies full_modname)
Alexander Alekhin's avatar
Alexander Alekhin committed
76
  ocv_debug_message("ocv_add_dependencies(" ${full_modname} ${ARGN} ")")
77
  #we don't clean the dependencies here to allow this macro several times for every module
78 79
  foreach(d "REQUIRED" ${ARGN})
    if(d STREQUAL "REQUIRED")
80 81 82
      set(__depsvar OPENCV_MODULE_${full_modname}_REQ_DEPS)
    elseif(d STREQUAL "OPTIONAL")
      set(__depsvar OPENCV_MODULE_${full_modname}_OPT_DEPS)
83 84 85 86
    elseif(d STREQUAL "PRIVATE_REQUIRED")
      set(__depsvar OPENCV_MODULE_${full_modname}_PRIVATE_REQ_DEPS)
    elseif(d STREQUAL "PRIVATE_OPTIONAL")
      set(__depsvar OPENCV_MODULE_${full_modname}_PRIVATE_OPT_DEPS)
87 88 89 90
    else()
      list(APPEND ${__depsvar} "${d}")
    endif()
  endforeach()
91 92 93 94
  unset(__depsvar)

  ocv_list_unique(OPENCV_MODULE_${full_modname}_REQ_DEPS)
  ocv_list_unique(OPENCV_MODULE_${full_modname}_OPT_DEPS)
95 96 97 98 99 100 101 102 103 104 105
  ocv_list_unique(OPENCV_MODULE_${full_modname}_PRIVATE_REQ_DEPS)
  ocv_list_unique(OPENCV_MODULE_${full_modname}_PRIVATE_OPT_DEPS)

  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")
  set(OPENCV_MODULE_${full_modname}_PRIVATE_REQ_DEPS ${OPENCV_MODULE_${full_modname}_PRIVATE_REQ_DEPS}
    CACHE INTERNAL "Required private dependencies of ${full_modname} module")
  set(OPENCV_MODULE_${full_modname}_PRIVATE_OPT_DEPS ${OPENCV_MODULE_${full_modname}_PRIVATE_OPT_DEPS}
    CACHE INTERNAL "Optional private dependencies of ${full_modname} module")
106 107
endmacro()

108 109
# declare new OpenCV module in current folder
# Usage:
110
#   ocv_add_module(<name> [INTERNAL|BINDINGS] [REQUIRED] [<list of dependencies>] [OPTIONAL <list of optional dependencies>])
111
# Example:
112
#   ocv_add_module(yaom INTERNAL opencv_core opencv_highgui opencv_flann OPTIONAL opencv_cuda)
113
macro(ocv_add_module _name)
Alexander Alekhin's avatar
Alexander Alekhin committed
114
  ocv_debug_message("ocv_add_module(" ${_name} ${ARGN} ")")
115 116 117
  string(TOLOWER "${_name}" name)
  string(REGEX REPLACE "^opencv_" "" ${name} "${name}")
  set(the_module opencv_${name})
118

119 120
  # the first pass - collect modules info, the second pass - create targets
  if(OPENCV_INITIAL_PASS)
121 122 123 124 125 126 127 128
    #guard agains redefinition
    if(";${OPENCV_MODULES_BUILD};${OPENCV_MODULES_DISABLED_USER};" MATCHES ";${the_module};")
      message(FATAL_ERROR "Redefinition of the ${the_module} module.
  at:                    ${CMAKE_CURRENT_SOURCE_DIR}
  previously defined at: ${OPENCV_MODULE_${the_module}_LOCATION}
")
    endif()

129 130 131
    if(NOT DEFINED the_description)
      set(the_description "The ${name} OpenCV module")
    endif()
132

133 134
    if(NOT DEFINED BUILD_${the_module}_INIT)
      set(BUILD_${the_module}_INIT ON)
135
    endif()
136 137

    # create option to enable/disable this module
138
    option(BUILD_${the_module} "Include ${the_module} module into the OpenCV build" ${BUILD_${the_module}_INIT})
139

140 141 142 143
    # remember the module details
    set(OPENCV_MODULE_${the_module}_DESCRIPTION "${the_description}" CACHE INTERNAL "Brief description of ${the_module} module")
    set(OPENCV_MODULE_${the_module}_LOCATION    "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${the_module} module sources")

Alexander Alekhin's avatar
Alexander Alekhin committed
144 145
    set(OPENCV_MODULE_${the_module}_LINK_DEPS "" CACHE INTERNAL "")

146
    # parse list of dependencies
147
    if("${ARGV1}" STREQUAL "INTERNAL" OR "${ARGV1}" STREQUAL "BINDINGS")
Ilya Lavrenov's avatar
Ilya Lavrenov committed
148
      set(OPENCV_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The category of the module")
149 150 151 152
      set(__ocv_argn__ ${ARGN})
      list(REMOVE_AT __ocv_argn__ 0)
      ocv_add_dependencies(${the_module} ${__ocv_argn__})
      unset(__ocv_argn__)
153
    else()
Ilya Lavrenov's avatar
Ilya Lavrenov committed
154
      set(OPENCV_MODULE_${the_module}_CLASS "PUBLIC" CACHE INTERNAL "The category of the module")
155 156
      ocv_add_dependencies(${the_module} ${ARGN})
      if(BUILD_${the_module})
157 158
        set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of OpenCV modules marked for export")
      endif()
159
    endif()
160

161
    # add self to the world dependencies
162 163 164 165 166
    # 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()
Alexander Alekhin's avatar
Alexander Alekhin committed
167
    if((NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS"
168
        AND __expected_extra EQUAL OPENCV_PROCESSING_EXTRA_MODULES)
Alexander Alekhin's avatar
Alexander Alekhin committed
169 170 171
        OR OPENCV_MODULE_IS_PART_OF_WORLD
        )
      set(OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD ON CACHE INTERNAL "")
172
      ocv_add_dependencies(opencv_world OPTIONAL ${the_module})
Alexander Alekhin's avatar
Alexander Alekhin committed
173 174
    else()
      set(OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD OFF CACHE INTERNAL "")
175
    endif()
176 177

    if(BUILD_${the_module})
178
      set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD} "${the_module}" CACHE INTERNAL "List of OpenCV modules included into the build")
179 180
    else()
      set(OPENCV_MODULES_DISABLED_USER ${OPENCV_MODULES_DISABLED_USER} "${the_module}" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user")
181
    endif()
182

183
    # TODO: add submodules if any
184

185
    # stop processing of current file
186
    return()
Alexander Alekhin's avatar
Alexander Alekhin committed
187 188
  else()
    set(OPENCV_MODULE_${the_module}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
189
    if(NOT BUILD_${the_module})
190
      return() # extra protection from redefinition
191
    endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
192 193 194 195
    if((NOT OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD AND NOT ${the_module} STREQUAL opencv_world) OR NOT ${BUILD_opencv_world})
      project(${the_module})
    endif()
  endif()
196 197
endmacro()

198
# excludes module from current configuration
199 200 201 202 203 204 205
macro(ocv_module_disable module)
  set(__modname ${module})
  if(NOT __modname MATCHES "^opencv_")
    set(__modname opencv_${module})
  endif()
  list(APPEND OPENCV_MODULES_DISABLED_FORCE "${__modname}")
  set(HAVE_${__modname} OFF CACHE INTERNAL "Module ${__modname} can not be built in current configuration")
206
  set(OPENCV_MODULE_${__modname}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${__modname} module sources")
207
  set(OPENCV_MODULES_DISABLED_FORCE "${OPENCV_MODULES_DISABLED_FORCE}" CACHE INTERNAL "List of OpenCV modules which can not be build in current configuration")
208 209 210
  if(BUILD_${__modname})
    # touch variable controlling build of the module to suppress "unused variable" CMake warning
  endif()
211
  unset(__modname)
212
  return() # leave the current folder
213
endmacro()
214 215


216 217 218
# collect modules from specified directories
# NB: must be called only once!
macro(ocv_glob_modules)
219 220 221 222 223
  if(DEFINED OPENCV_INITIAL_PASS)
    message(FATAL_ERROR "OpenCV has already loaded its modules. Calling ocv_glob_modules second time is not allowed.")
  endif()
  set(__directories_observed "")

224
  # collect modules
225
  set(OPENCV_INITIAL_PASS ON)
Alexander Alekhin's avatar
Alexander Alekhin committed
226
  set(OPENCV_PROCESSING_EXTRA_MODULES 0)
227
  foreach(__path ${ARGN})
Alexander Alekhin's avatar
Alexander Alekhin committed
228 229 230
    if("${__path}" STREQUAL "EXTRA")
      set(OPENCV_PROCESSING_EXTRA_MODULES 1)
    endif()
231
    get_filename_component(__path "${__path}" ABSOLUTE)
232

233 234 235 236 237 238
    list(FIND __directories_observed "${__path}" __pathIdx)
    if(__pathIdx GREATER -1)
      message(FATAL_ERROR "The directory ${__path} is observed for OpenCV modules second time.")
    endif()
    list(APPEND __directories_observed "${__path}")

239 240 241 242
    file(GLOB __ocvmodules RELATIVE "${__path}" "${__path}/*")
    if(__ocvmodules)
      list(SORT __ocvmodules)
      foreach(mod ${__ocvmodules})
243
        get_filename_component(__modpath "${__path}/${mod}" ABSOLUTE)
244
        if(EXISTS "${__modpath}/CMakeLists.txt")
245

246 247 248 249 250 251
          list(FIND __directories_observed "${__modpath}" __pathIdx)
          if(__pathIdx GREATER -1)
            message(FATAL_ERROR "The module from ${__modpath} is already loaded.")
          endif()
          list(APPEND __directories_observed "${__modpath}")

Alexander Alekhin's avatar
Alexander Alekhin committed
252
          add_subdirectory("${__modpath}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
253
        endif()
254
      endforeach()
255
    endif()
256
  endforeach()
257
  ocv_clear_vars(__ocvmodules __directories_observed __path __modpath __pathIdx)
258

259
  # resolve dependencies
260
  __ocv_resolve_dependencies()
261

262
  # create modules
263
  set(OPENCV_INITIAL_PASS OFF PARENT_SCOPE)
264
  set(OPENCV_INITIAL_PASS OFF)
Alexander Alekhin's avatar
Alexander Alekhin committed
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
  if(${BUILD_opencv_world})
    add_subdirectory("${OPENCV_MODULE_opencv_world_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/world")
    foreach(m ${OPENCV_MODULES_BUILD})
      if(NOT OPENCV_MODULE_${m}_IS_PART_OF_WORLD AND NOT ${m} STREQUAL opencv_world)
        message(STATUS "Processing module ${m}...")
        if(m MATCHES "^opencv_")
          string(REGEX REPLACE "^opencv_" "" __shortname "${m}")
          add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}")
        else()
          message(WARNING "Check module name: ${m}")
          add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${m}")
        endif()
      endif()
    endforeach()
  else()
    foreach(m ${OPENCV_MODULES_BUILD})
      if(m MATCHES "^opencv_")
        string(REGEX REPLACE "^opencv_" "" __shortname "${m}")
        add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}")
      else()
        message(WARNING "Check module name: ${m}")
        add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${m}")
      endif()
    endforeach()
  endif()
290
  unset(__shortname)
291 292
endmacro()

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349

# disables OpenCV module with missing dependencies
function(__ocv_module_turn_off the_module)
  list(REMOVE_ITEM OPENCV_MODULES_DISABLED_AUTO "${the_module}")
  list(APPEND OPENCV_MODULES_DISABLED_AUTO "${the_module}")
  list(REMOVE_ITEM OPENCV_MODULES_BUILD "${the_module}")
  list(REMOVE_ITEM OPENCV_MODULES_PUBLIC "${the_module}")
  set(HAVE_${the_module} OFF CACHE INTERNAL "Module ${the_module} can not be built in current configuration")

  set(OPENCV_MODULES_DISABLED_AUTO "${OPENCV_MODULES_DISABLED_AUTO}" CACHE INTERNAL "")
  set(OPENCV_MODULES_BUILD "${OPENCV_MODULES_BUILD}" CACHE INTERNAL "")
  set(OPENCV_MODULES_PUBLIC "${OPENCV_MODULES_PUBLIC}" CACHE INTERNAL "")
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}")
        endif()
      endif()
    endforeach()
    if(__index STREQUAL __lastindex)
      list(APPEND __result "${m}")
    else()
      list(INSERT __result ${__index} "${m}")
    endif()
  endforeach()
  set(${__lst} "${__result}" PARENT_SCOPE)
endfunction()

# resolve dependensies
function(__ocv_resolve_dependencies)
  foreach(m ${OPENCV_MODULES_DISABLED_USER})
    set(HAVE_${m} OFF CACHE INTERNAL "Module ${m} will not be built in current configuration")
  endforeach()
  foreach(m ${OPENCV_MODULES_BUILD})
    set(HAVE_${m} ON CACHE INTERNAL "Module ${m} will be built in current configuration")
  endforeach()

  # disable MODULES with unresolved dependencies
  set(has_changes ON)
  while(has_changes)
    set(has_changes OFF)
    foreach(m ${OPENCV_MODULES_BUILD})
      set(__deps ${OPENCV_MODULE_${m}_REQ_DEPS} ${OPENCV_MODULE_${m}_PRIVATE_REQ_DEPS})
      while(__deps)
        ocv_list_pop_front(__deps d)
350 351 352 353 354 355 356 357 358 359
        string(TOLOWER "${d}" upper_d)
        if(NOT (HAVE_${d} OR HAVE_${upper_d} OR TARGET ${d} OR EXISTS ${d}))
          if(d MATCHES "^opencv_") # TODO Remove this condition in the future and use HAVE_ variables only
            message(STATUS "Module ${m} disabled because ${d} dependency can't be resolved!")
            __ocv_module_turn_off(${m})
            set(has_changes ON)
            break()
          else()
            message(STATUS "Assume that non-module dependency is available: ${d} (for module ${m})")
          endif()
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
        endif()
      endwhile()
    endforeach()
  endwhile()

#  message(STATUS "List of active modules: ${OPENCV_MODULES_BUILD}")

  foreach(m ${OPENCV_MODULES_BUILD})
    set(deps_${m} ${OPENCV_MODULE_${m}_REQ_DEPS})
    foreach(d ${OPENCV_MODULE_${m}_OPT_DEPS})
      if(NOT (";${deps_${m}};" MATCHES ";${d};"))
        if(HAVE_${d} OR TARGET ${d})
          list(APPEND deps_${m} ${d})
        endif()
      endif()
    endforeach()
#    message(STATUS "Initial deps of ${m} (w/o private deps): ${deps_${m}}")
  endforeach()

  # propagate dependencies
  set(has_changes ON)
  while(has_changes)
    set(has_changes OFF)
    foreach(m2 ${OPENCV_MODULES_BUILD}) # transfer deps of m2 to m
      foreach(m ${OPENCV_MODULES_BUILD})
        if((NOT m STREQUAL m2) AND ";${deps_${m}};" MATCHES ";${m2};")
          foreach(d ${deps_${m2}})
            if(NOT (";${deps_${m}};" MATCHES ";${d};"))
#              message(STATUS "  Transfer dependency ${d} from ${m2} to ${m}")
              list(APPEND deps_${m} ${d})
              set(has_changes ON)
            endif()
          endforeach()
        endif()
      endforeach()
    endforeach()
  endwhile()

  # process private deps
  foreach(m ${OPENCV_MODULES_BUILD})
    foreach(d ${OPENCV_MODULE_${m}_PRIVATE_REQ_DEPS})
      if(NOT (";${deps_${m}};" MATCHES ";${d};"))
        list(APPEND deps_${m} ${d})
      endif()
    endforeach()
    foreach(d ${OPENCV_MODULE_${m}_PRIVATE_OPT_DEPS})
      if(NOT (";${deps_${m}};" MATCHES ";${d};"))
        if(HAVE_${d} OR TARGET ${d})
          list(APPEND deps_${m} ${d})
        endif()
      endif()
    endforeach()
  endforeach()

  ocv_list_sort(OPENCV_MODULES_BUILD)

  foreach(m ${OPENCV_MODULES_BUILD})
#    message(STATUS "FULL deps of ${m}: ${deps_${m}}")
    set(OPENCV_MODULE_${m}_DEPS ${deps_${m}})
    set(OPENCV_MODULE_${m}_DEPS_EXT ${deps_${m}})
    ocv_list_filterout(OPENCV_MODULE_${m}_DEPS_EXT "^opencv_[^ ]+$")
    if(OPENCV_MODULE_${m}_DEPS_EXT AND OPENCV_MODULE_${m}_DEPS)
      list(REMOVE_ITEM OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS_EXT})
    endif()
  endforeach()

  # reorder dependencies
  foreach(m ${OPENCV_MODULES_BUILD})
    __ocv_sort_modules_by_deps(OPENCV_MODULE_${m}_DEPS)
    ocv_list_sort(OPENCV_MODULE_${m}_DEPS_EXT)

Alexander Alekhin's avatar
Alexander Alekhin committed
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
    set(LINK_DEPS ${OPENCV_MODULE_${m}_DEPS})

    # process world
    if(BUILD_opencv_world)
      if(OPENCV_MODULE_${m}_IS_PART_OF_WORLD)
        list(APPEND OPENCV_WORLD_MODULES ${m})
      endif()
      foreach(m2 ${OPENCV_MODULES_BUILD})
        if(OPENCV_MODULE_${m2}_IS_PART_OF_WORLD)
          if(";${LINK_DEPS};" MATCHES ";${m2};")
            list(REMOVE_ITEM LINK_DEPS ${m2})
            if(NOT (";${LINK_DEPS};" MATCHES ";opencv_world;") AND NOT (${m} STREQUAL opencv_world))
              list(APPEND LINK_DEPS opencv_world)
            endif()
          endif()
          if(${m} STREQUAL opencv_world)
            list(APPEND OPENCV_MODULE_opencv_world_DEPS_EXT ${OPENCV_MODULE_${m2}_DEPS_EXT})
          endif()
        endif()
      endforeach()
    endif()

453 454
    set(OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module")
    set(OPENCV_MODULE_${m}_DEPS_EXT ${OPENCV_MODULE_${m}_DEPS_EXT} CACHE INTERNAL "Extra dependencies of ${m} module")
Alexander Alekhin's avatar
Alexander Alekhin committed
455
    set(OPENCV_MODULE_${m}_DEPS_TO_LINK ${LINK_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module (for linker)")
456

Alexander Alekhin's avatar
Alexander Alekhin committed
457 458 459 460
#    message(STATUS "  module deps of ${m}: ${OPENCV_MODULE_${m}_DEPS}")
#    message(STATUS "  module link deps of ${m}: ${OPENCV_MODULE_${m}_DEPS_TO_LINK}")
#    message(STATUS "  extra deps of ${m}: ${OPENCV_MODULE_${m}_DEPS_EXT}")
#    message(STATUS "")
461 462 463 464 465 466 467
  endforeach()

  __ocv_sort_modules_by_deps(OPENCV_MODULES_BUILD)

  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")
Alexander Alekhin's avatar
Alexander Alekhin committed
468
  set(OPENCV_WORLD_MODULES         ${OPENCV_WORLD_MODULES}         CACHE INTERNAL "List of OpenCV modules included into the world")
469 470 471
endfunction()


472 473 474 475 476
# setup include paths for the list of passed modules
macro(ocv_include_modules)
  foreach(d ${ARGN})
    if(d MATCHES "^opencv_" AND HAVE_${d})
      if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include")
477
        ocv_include_directories("${OPENCV_MODULE_${d}_LOCATION}/include")
478 479
      endif()
    elseif(EXISTS "${d}")
480
      ocv_include_directories("${d}")
481 482 483
    endif()
  endforeach()
endmacro()
484

Alexander Alekhin's avatar
Alexander Alekhin committed
485 486 487 488 489 490 491 492 493 494 495 496 497
# setup include paths for the list of passed modules
macro(ocv_target_include_modules target)
  foreach(d ${ARGN})
    if(d MATCHES "^opencv_" AND HAVE_${d})
      if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include")
        ocv_target_include_directories(${target} "${OPENCV_MODULE_${d}_LOCATION}/include")
      endif()
    elseif(EXISTS "${d}")
      ocv_target_include_directories(${target} "${d}")
    endif()
  endforeach()
endmacro()

498
# setup include paths for the list of passed modules and recursively add dependent modules
Alexander Alekhin's avatar
Alexander Alekhin committed
499
macro(ocv_target_include_modules_recurse target)
500 501 502
  foreach(d ${ARGN})
    if(d MATCHES "^opencv_" AND HAVE_${d})
      if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include")
Alexander Alekhin's avatar
Alexander Alekhin committed
503
        ocv_target_include_directories(${target} "${OPENCV_MODULE_${d}_LOCATION}/include")
504 505
      endif()
      if(OPENCV_MODULE_${d}_DEPS)
Alexander Alekhin's avatar
Alexander Alekhin committed
506
        ocv_target_include_modules(${target} ${OPENCV_MODULE_${d}_DEPS})
507 508
      endif()
    elseif(EXISTS "${d}")
Alexander Alekhin's avatar
Alexander Alekhin committed
509
      ocv_target_include_directories(${target} "${d}")
510 511 512 513
    endif()
  endforeach()
endmacro()

514 515 516
# setup include path for OpenCV headers for specified module
# ocv_module_include_directories(<extra include directories/extra include modules>)
macro(ocv_module_include_directories)
Alexander Alekhin's avatar
Alexander Alekhin committed
517 518 519 520 521 522
  ocv_target_include_directories(${the_module}
      "${OPENCV_MODULE_${the_module}_LOCATION}/include"
      "${OPENCV_MODULE_${the_module}_LOCATION}/src"
      "${CMAKE_CURRENT_BINARY_DIR}" # for precompiled headers
      )
  ocv_target_include_modules(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${ARGN})
523
endmacro()
524 525


526 527 528 529 530
# sets header and source files for the current module
# NB: all files specified as headers will be installed
# Usage:
# ocv_set_module_sources([HEADERS] <list of files> [SOURCES] <list of files>)
macro(ocv_set_module_sources)
Alexander Alekhin's avatar
Alexander Alekhin committed
531 532
  ocv_debug_message("ocv_set_module_sources(" ${ARGN} ")")

533 534
  set(OPENCV_MODULE_${the_module}_HEADERS "")
  set(OPENCV_MODULE_${the_module}_SOURCES "")
535

536 537 538 539 540 541 542
  foreach(f "HEADERS" ${ARGN})
    if(f STREQUAL "HEADERS" OR f STREQUAL "SOURCES")
      set(__filesvar "OPENCV_MODULE_${the_module}_${f}")
    else()
      list(APPEND ${__filesvar} "${f}")
    endif()
  endforeach()
543

544 545 546 547
  # 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()
548

549
  # use full paths for module to be independent from the module location
550
  ocv_convert_to_full_paths(OPENCV_MODULE_${the_module}_HEADERS)
551

552 553 554
  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()
555

556 557
# finds and sets headers and sources for the standard OpenCV module
# Usage:
558
# ocv_glob_module_sources([EXCLUDE_CUDA] <extra sources&headers in the same format as used in ocv_set_module_sources>)
559
macro(ocv_glob_module_sources)
Alexander Alekhin's avatar
Alexander Alekhin committed
560
  ocv_debug_message("ocv_glob_module_sources(" ${ARGN} ")")
561 562 563 564 565 566
  set(_argn ${ARGN})
  list(FIND _argn "EXCLUDE_CUDA" exclude_cuda)
  if(NOT exclude_cuda EQUAL -1)
    list(REMOVE_AT _argn ${exclude_cuda})
  endif()

Alexander Alekhin's avatar
Alexander Alekhin committed
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
  file(GLOB_RECURSE lib_srcs
       "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp"
  )
  file(GLOB_RECURSE lib_int_hdrs
       "${CMAKE_CURRENT_LIST_DIR}/src/*.hpp"
       "${CMAKE_CURRENT_LIST_DIR}/src/*.h"
  )
  file(GLOB lib_hdrs
       "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/*.hpp"
       "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp"
       "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h"
  )
  file(GLOB lib_hdrs_detail
       "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/detail/*.hpp"
       "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/detail/*.h"
  )
583
  if (APPLE)
Alexander Alekhin's avatar
Alexander Alekhin committed
584 585 586
    file(GLOB_RECURSE lib_srcs_apple
         "${CMAKE_CURRENT_LIST_DIR}/src/*.mm"
    )
587 588
    list(APPEND lib_srcs ${lib_srcs_apple})
  endif()
589

Alexander Alekhin's avatar
Alexander Alekhin committed
590 591
  ocv_source_group("Src" DIRBASE "${CMAKE_CURRENT_LIST_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs})
  ocv_source_group("Include" DIRBASE "${CMAKE_CURRENT_LIST_DIR}/include" FILES ${lib_hdrs} ${lib_hdrs_detail})
592

593 594 595
  set(lib_cuda_srcs "")
  set(lib_cuda_hdrs "")
  if(HAVE_CUDA AND exclude_cuda EQUAL -1)
Alexander Alekhin's avatar
Alexander Alekhin committed
596 597 598
    file(GLOB lib_cuda_srcs
         "${CMAKE_CURRENT_LIST_DIR}/src/cuda/*.cu"
    )
599 600 601 602
    file(GLOB lib_cuda_hdrs
         "${CMAKE_CURRENT_LIST_DIR}/src/cuda/*.hpp"
    )
    source_group("Src\\Cuda"      FILES ${lib_cuda_srcs} ${lib_cuda_hdrs})
603 604
  endif()

Alexander Alekhin's avatar
Alexander Alekhin committed
605 606 607
  file(GLOB cl_kernels
       "${CMAKE_CURRENT_LIST_DIR}/src/opencl/*.cl"
  )
608
  if(cl_kernels)
Alexander Alekhin's avatar
Alexander Alekhin committed
609
    set(OCL_NAME opencl_kernels_${name})
610 611
    ocv_include_directories(${OPENCL_INCLUDE_DIRS})
    add_custom_command(
Alexander Alekhin's avatar
Alexander Alekhin committed
612 613
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.hpp"
      COMMAND ${CMAKE_COMMAND} -DMODULE_NAME="${name}" -DCL_DIR="${CMAKE_CURRENT_LIST_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
614
      DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake")
615
    ocv_source_group("Src\\opencl\\kernels" FILES ${cl_kernels})
Alexander Alekhin's avatar
Alexander Alekhin committed
616 617
    ocv_source_group("Src\\opencl\\kernels\\autogenerated" FILES "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.hpp")
    list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.hpp")
618 619
  endif()

620
  ocv_set_module_sources(${_argn} HEADERS ${lib_hdrs} ${lib_hdrs_detail}
621
                         SOURCES ${lib_srcs} ${lib_int_hdrs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
622 623
endmacro()

624 625 626
# creates OpenCV module in current folder
# creates new target, configures standard dependencies, compilers flags, install rules
# Usage:
627
#   ocv_create_module(<extra link dependencies>)
Alexander Alekhin's avatar
Alexander Alekhin committed
628
#   ocv_create_module()
629
macro(ocv_create_module)
Alexander Alekhin's avatar
Alexander Alekhin committed
630 631 632 633 634 635 636 637 638 639 640 641
  ocv_debug_message("ocv_create_module(" ${ARGN} ")")
  set(OPENCV_MODULE_${the_module}_LINK_DEPS "${OPENCV_MODULE_${the_module}_LINK_DEPS};${ARGN}" CACHE INTERNAL "")
  if(${BUILD_opencv_world} AND OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD)
    # nothing
    set(the_module_target opencv_world)
  else()
    _ocv_create_module(${ARGN})
    set(the_module_target ${the_module})
  endif()
endmacro()

macro(_ocv_create_module)
642 643 644
  # The condition we ought to be testing here is whether ocv_add_precompiled_headers will
  # be called at some point in the future. We can't look into the future, though,
  # so this will have to do.
Alexander Alekhin's avatar
Alexander Alekhin committed
645
  if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/precomp.hpp" AND NOT ${the_module} STREQUAL opencv_world)
646 647 648
    get_native_precompiled_header(${the_module} precomp.hpp)
  endif()

Alexander Alekhin's avatar
Alexander Alekhin committed
649
  ocv_add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}
650 651
    "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp"
    ${${the_module}_pch})
652 653 654
  if(NOT the_module STREQUAL opencv_ts)
    set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS OPENCV_NOSTL)
  endif()
655

Alexander Alekhin's avatar
Alexander Alekhin committed
656 657 658 659 660
  ocv_target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK})
  ocv_target_link_libraries(${the_module} LINK_INTERFACE_LIBRARIES ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK})
  ocv_target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN})
  if (HAVE_CUDA)
    ocv_target_link_libraries(${the_module} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
661
  endif()
662

663
  add_dependencies(opencv_modules ${the_module})
664

665 666 667
  if(ENABLE_SOLUTION_FOLDERS)
    set_target_properties(${the_module} PROPERTIES FOLDER "modules")
  endif()
668

669 670 671 672
  set_target_properties(${the_module} PROPERTIES
    OUTPUT_NAME "${the_module}${OPENCV_DLLVERSION}"
    DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
    ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
673
    LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
674 675 676
    RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
    INSTALL_NAME_DIR lib
  )
677

678 679 680 681 682
  # For dynamic link numbering convenions
  if(NOT ANDROID)
    # Android SDK build scripts can include only .so files into final .apk
    # As result we should not set version properties for Android
    set_target_properties(${the_module} PROPERTIES
683
      VERSION ${OPENCV_LIBVERSION}
684 685 686 687
      SOVERSION ${OPENCV_SOVERSION}
    )
  endif()

688 689
  if((NOT DEFINED OPENCV_MODULE_TYPE AND BUILD_SHARED_LIBS)
      OR (DEFINED OPENCV_MODULE_TYPE AND OPENCV_MODULE_TYPE STREQUAL SHARED))
690
    set_target_properties(${the_module} PROPERTIES DEFINE_SYMBOL CVAPI_EXPORTS)
691
  endif()
Andrey Kamaev's avatar
Andrey Kamaev committed
692

693 694 695
  if(MSVC)
    if(CMAKE_CROSSCOMPILING)
      set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:secchk")
696
    endif()
697
    set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libc /DEBUG")
698
  endif()
699

700
  ocv_install_target(${the_module} EXPORT OpenCVModules
701
    RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs
702 703
    LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs
    ARCHIVE DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT dev
704
    )
705

706
  # only "public" headers need to be installed
707
  if(OPENCV_MODULE_${the_module}_HEADERS AND ";${OPENCV_MODULES_PUBLIC};" MATCHES ";${the_module};")
708
    foreach(hdr ${OPENCV_MODULE_${the_module}_HEADERS})
709
      string(REGEX REPLACE "^.*opencv2/" "opencv2/" hdr2 "${hdr}")
710
      if(NOT hdr2 MATCHES "opencv2/${the_module}/private.*" AND hdr2 MATCHES "^(opencv2/?.*)/[^/]+.h(..)?$" )
711
        install(FILES ${hdr} DESTINATION "${OPENCV_INCLUDE_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT dev)
712 713
      endif()
    endforeach()
714
  endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
715
  _ocv_add_precompiled_headers(${the_module})
716 717 718 719 720 721
endmacro()

# opencv precompiled headers macro (can add pch to modules and tests)
# this macro must be called after any "add_definitions" commands, otherwise precompiled headers will not work
# Usage:
# ocv_add_precompiled_headers(${the_module})
Alexander Alekhin's avatar
Alexander Alekhin committed
722 723 724
macro(_ocv_add_precompiled_headers the_target)
  ocv_debug_message("ocv_add_precompiled_headers(" ${the_target} ${ARGN} ")")

725 726 727 728 729 730 731 732 733
  if("${the_target}" MATCHES "^opencv_test_.*$")
    SET(pch_path "test/test_")
  elseif("${the_target}" MATCHES "^opencv_perf_.*$")
    SET(pch_path "perf/perf_")
  else()
    SET(pch_path "src/")
  endif()
  ocv_add_precompiled_header_to_target(${the_target} "${CMAKE_CURRENT_SOURCE_DIR}/${pch_path}precomp.hpp")
  unset(pch_path)
734
endmacro()
735

736 737 738
# short command for adding simple OpenCV module
# see ocv_add_module for argument details
# Usage:
739
# ocv_define_module(module_name  [INTERNAL] [EXCLUDE_CUDA] [REQUIRED] [<list of dependencies>] [OPTIONAL <list of optional dependencies>])
740
macro(ocv_define_module module_name)
Alexander Alekhin's avatar
Alexander Alekhin committed
741
  ocv_debug_message("ocv_define_module(" ${module_name} ${ARGN} ")")
742 743 744 745 746 747
  set(_argn ${ARGN})
  set(exclude_cuda "")
  foreach(arg ${_argn})
    if("${arg}" STREQUAL "EXCLUDE_CUDA")
      set(exclude_cuda "${arg}")
      list(REMOVE_ITEM _argn ${arg})
748 749 750
    endif()
  endforeach()

751 752
  ocv_add_module(${module_name} ${_argn})
  ocv_glob_module_sources(${exclude_cuda})
Alexander Alekhin's avatar
Alexander Alekhin committed
753
  ocv_module_include_directories()
754 755 756 757
  ocv_create_module()

  ocv_add_accuracy_tests()
  ocv_add_perf_tests()
758
  ocv_add_samples()
759
endmacro()
760

761 762 763 764 765 766 767 768
# ensures that all passed modules are available
# sets OCV_DEPENDENCIES_FOUND variable to TRUE/FALSE
macro(ocv_check_dependencies)
  set(OCV_DEPENDENCIES_FOUND TRUE)
  foreach(d ${ARGN})
    if(d MATCHES "^opencv_[^ ]+$" AND NOT HAVE_${d})
      set(OCV_DEPENDENCIES_FOUND FALSE)
      break()
769
    endif()
770
  endforeach()
771 772
endmacro()

773
# auxiliary macro to parse arguments of ocv_add_accuracy_tests and ocv_add_perf_tests commands
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
macro(__ocv_parse_test_sources tests_type)
  set(OPENCV_${tests_type}_${the_module}_SOURCES "")
  set(OPENCV_${tests_type}_${the_module}_DEPS "")
  set(__file_group_name "")
  set(__file_group_sources "")
  foreach(arg "DEPENDS_ON" ${ARGN} "FILES")
    if(arg STREQUAL "FILES")
      set(__currentvar "__file_group_sources")
      if(__file_group_name AND __file_group_sources)
        source_group("${__file_group_name}" FILES ${__file_group_sources})
        list(APPEND OPENCV_${tests_type}_${the_module}_SOURCES ${__file_group_sources})
      endif()
      set(__file_group_name "")
      set(__file_group_sources "")
    elseif(arg STREQUAL "DEPENDS_ON")
Alexander Alekhin's avatar
Alexander Alekhin committed
789
      set(__currentvar "OPENCV_${tests_type}_${the_module}_DEPS")
790 791 792 793 794 795 796 797 798 799
    elseif("${__currentvar}" STREQUAL "__file_group_sources" AND NOT __file_group_name)
      set(__file_group_name "${arg}")
    else()
      list(APPEND ${__currentvar} "${arg}")
    endif()
  endforeach()
  unset(__file_group_name)
  unset(__file_group_sources)
  unset(__currentvar)
endmacro()
800

801 802
# this is a command for adding OpenCV performance tests to the module
# ocv_add_perf_tests(<extra_dependencies>)
803
function(ocv_add_perf_tests)
Alexander Alekhin's avatar
Alexander Alekhin committed
804 805 806
  ocv_debug_message("ocv_add_perf_tests(" ${ARGN} ")")

  set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf")
807 808
  if(BUILD_PERF_TESTS AND EXISTS "${perf_path}")
    __ocv_parse_test_sources(PERF ${ARGN})
809

810
    # opencv_imgcodecs is required for imread/imwrite
Alexander Alekhin's avatar
Alexander Alekhin committed
811
    set(perf_deps ${the_module} opencv_ts opencv_imgcodecs ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS})
812
    ocv_check_dependencies(${perf_deps})
813

814 815
    if(OCV_DEPENDENCIES_FOUND)
      set(the_target "opencv_perf_${name}")
816
      # project(${the_target})
817

818
      if(NOT OPENCV_PERF_${the_module}_SOURCES)
819 820
        file(GLOB_RECURSE perf_srcs "${perf_path}/*.cpp")
        file(GLOB_RECURSE perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h")
821 822
        ocv_source_group("Src" DIRBASE "${perf_path}" FILES ${perf_srcs})
        ocv_source_group("Include" DIRBASE "${perf_path}" FILES ${perf_hdrs})
823 824
        set(OPENCV_PERF_${the_module}_SOURCES ${perf_srcs} ${perf_hdrs})
      endif()
825

Alexander Alekhin's avatar
Alexander Alekhin committed
826 827 828
      if(NOT BUILD_opencv_world)
        get_native_precompiled_header(${the_target} perf_precomp.hpp)
      endif()
829

Alexander Alekhin's avatar
Alexander Alekhin committed
830 831 832
      ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
      ocv_target_include_modules(${the_target} ${perf_deps} "${perf_path}")
      ocv_target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${perf_deps} ${OPENCV_LINKER_LIBS})
833
      add_dependencies(opencv_perf_tests ${the_target})
834

835 836 837 838 839 840 841 842 843 844
      # Additional target properties
      set_target_properties(${the_target} PROPERTIES
        DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
        RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}"
      )

      if(ENABLE_SOLUTION_FOLDERS)
        set_target_properties(${the_target} PROPERTIES FOLDER "tests performance")
      endif()

Alexander Alekhin's avatar
Alexander Alekhin committed
845 846 847
      if(NOT BUILD_opencv_world)
        _ocv_add_precompiled_headers(${the_target})
      endif()
848
    else(OCV_DEPENDENCIES_FOUND)
849
      # TODO: warn about unsatisfied dependencies
850
    endif(OCV_DEPENDENCIES_FOUND)
851
    if(INSTALL_TESTS)
852
      install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests)
853
    endif()
854
  endif()
855
endfunction()
856

857 858
# this is a command for adding OpenCV accuracy/regression tests to the module
# ocv_add_accuracy_tests([FILES <source group name> <list of sources>] [DEPENDS_ON] <list of extra dependencies>)
859
function(ocv_add_accuracy_tests)
Alexander Alekhin's avatar
Alexander Alekhin committed
860 861 862
  ocv_debug_message("ocv_add_accuracy_tests(" ${ARGN} ")")

  set(test_path "${CMAKE_CURRENT_LIST_DIR}/test")
863 864 865
  if(BUILD_TESTS AND EXISTS "${test_path}")
    __ocv_parse_test_sources(TEST ${ARGN})

866
    # opencv_imgcodecs is required for imread/imwrite
Alexander Alekhin's avatar
Alexander Alekhin committed
867
    set(test_deps ${the_module} opencv_ts opencv_imgcodecs opencv_videoio ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS})
868 869 870
    ocv_check_dependencies(${test_deps})
    if(OCV_DEPENDENCIES_FOUND)
      set(the_target "opencv_test_${name}")
871
      # project(${the_target})
872

873
      if(NOT OPENCV_TEST_${the_module}_SOURCES)
874 875
        file(GLOB_RECURSE test_srcs "${test_path}/*.cpp")
        file(GLOB_RECURSE test_hdrs "${test_path}/*.hpp" "${test_path}/*.h")
876 877
        ocv_source_group("Src" DIRBASE "${test_path}" FILES ${test_srcs})
        ocv_source_group("Include" DIRBASE "${test_path}" FILES ${test_hdrs})
878 879
        set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs})
      endif()
880

Alexander Alekhin's avatar
Alexander Alekhin committed
881 882 883
      if(NOT BUILD_opencv_world)
        get_native_precompiled_header(${the_target} test_precomp.hpp)
      endif()
884

Alexander Alekhin's avatar
Alexander Alekhin committed
885 886 887
      ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
      ocv_target_include_modules(${the_target} ${test_deps} "${test_path}")
      ocv_target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS})
888
      add_dependencies(opencv_tests ${the_target})
889

890 891 892 893 894 895 896 897 898
      # Additional target properties
      set_target_properties(${the_target} PROPERTIES
        DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
        RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}"
      )

      if(ENABLE_SOLUTION_FOLDERS)
        set_target_properties(${the_target} PROPERTIES FOLDER "tests accuracy")
      endif()
899

900 901 902 903
      enable_testing()
      get_target_property(LOC ${the_target} LOCATION)
      add_test(${the_target} "${LOC}")

Alexander Alekhin's avatar
Alexander Alekhin committed
904 905 906
      if(NOT BUILD_opencv_world)
        _ocv_add_precompiled_headers(${the_target})
      endif()
907
    else(OCV_DEPENDENCIES_FOUND)
908
      # TODO: warn about unsatisfied dependencies
909
    endif(OCV_DEPENDENCIES_FOUND)
910 911

    if(INSTALL_TESTS)
912
      install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests)
913
    endif()
914
  endif()
915
endfunction()
916

917
function(ocv_add_samples)
Alexander Alekhin's avatar
Alexander Alekhin committed
918 919
  ocv_debug_message("ocv_add_samples(" ${ARGN} ")")

920 921 922 923
  set(samples_path "${CMAKE_CURRENT_SOURCE_DIR}/samples")
  string(REGEX REPLACE "^opencv_" "" module_id ${the_module})

  if(BUILD_EXAMPLES AND EXISTS "${samples_path}")
924
    set(samples_deps ${the_module} ${OPENCV_MODULE_${the_module}_DEPS} opencv_imgcodecs opencv_videoio opencv_highgui ${ARGN})
925 926 927 928 929 930 931 932 933
    ocv_check_dependencies(${samples_deps})

    if(OCV_DEPENDENCIES_FOUND)
      file(GLOB sample_sources "${samples_path}/*.cpp")

      foreach(source ${sample_sources})
        get_filename_component(name "${source}" NAME_WE)
        set(the_target "example_${module_id}_${name}")

Alexander Alekhin's avatar
Alexander Alekhin committed
934 935 936
        ocv_add_executable(${the_target} "${source}")
        ocv_target_include_modules(${the_target} ${samples_deps})
        ocv_target_link_libraries(${the_target} ${samples_deps})
937 938 939 940 941 942 943 944 945
        set_target_properties(${the_target} PROPERTIES PROJECT_LABEL "(sample) ${name}")

        if(ENABLE_SOLUTION_FOLDERS)
          set_target_properties(${the_target} PROPERTIES
            OUTPUT_NAME "${module_id}-example-${name}"
            FOLDER "samples/${module_id}")
        endif()

        if(WIN32)
946
          install(TARGETS ${the_target} RUNTIME DESTINATION "samples/${module_id}" COMPONENT samples)
947 948 949 950 951 952
        endif()
      endforeach()
    endif()
  endif()

  if(INSTALL_C_EXAMPLES AND NOT WIN32 AND EXISTS "${samples_path}")
953 954 955 956 957 958 959 960
  file(GLOB DEPLOY_FILES_AND_DIRS "${samples_path}/*")
    foreach(ITEM ${DEPLOY_FILES_AND_DIRS})
        IF( IS_DIRECTORY "${ITEM}" )
            LIST( APPEND sample_dirs "${ITEM}" )
        ELSE()
            LIST( APPEND sample_files "${ITEM}" )
        ENDIF()
    endforeach()
961
    install(FILES ${sample_files}
962
            DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/${module_id}
963
            PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples)
964 965 966
    install(DIRECTORY ${sample_dirs}
            DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/${module_id}
            USE_SOURCE_PERMISSIONS COMPONENT samples)
967 968
  endif()
endfunction()