OpenCVUtils.cmake 39.4 KB
Newer Older
1 2
include(CMakeParseArguments)

3 4
# Debugging function
function(ocv_cmake_dump_vars)
5
  get_cmake_property(__variableNames VARIABLES)
6 7
  cmake_parse_arguments(DUMP "" "TOFILE" "" ${ARGN})
  set(regex "${DUMP_UNPARSED_ARGUMENTS}")
8
  string(TOLOWER "${regex}" regex_lower)
9 10 11 12 13 14
  set(__VARS "")
  foreach(__variableName ${__variableNames})
    string(TOLOWER "${__variableName}" __variableName_lower)
    if((__variableName MATCHES "${regex}" OR __variableName_lower MATCHES "${regex_lower}")
        AND NOT __variableName_lower MATCHES "^__")
      set(__VARS "${__VARS}${__variableName}=${${__variableName}}\n")
15 16 17
    endif()
  endforeach()
  if(DUMP_TOFILE)
18
    file(WRITE ${CMAKE_BINARY_DIR}/${DUMP_TOFILE} "${__VARS}")
19
  else()
20
    message(AUTHOR_WARNING "${__VARS}")
21 22 23
  endif()
endfunction()

24 25 26 27 28 29 30 31 32
function(ocv_cmake_eval var_name)
  if(DEFINED ${var_name})
    file(WRITE "${CMAKE_BINARY_DIR}/CMakeCommand-${var_name}.cmake" ${${var_name}})
    include("${CMAKE_BINARY_DIR}/CMakeCommand-${var_name}.cmake")
  endif()
  if(";${ARGN};" MATCHES ";ONCE;")
    unset(${var_name} CACHE)
  endif()
endfunction()
33

34 35 36 37 38 39 40
macro(ocv_cmake_configure file_name var_name)
  configure_file(${file_name} "${CMAKE_BINARY_DIR}/CMakeConfig-${var_name}.cmake" ${ARGN})
  file(READ "${CMAKE_BINARY_DIR}/CMakeConfig-${var_name}.cmake" ${var_name})
endmacro()

macro(ocv_update VAR)
  if(NOT DEFINED ${VAR})
41 42 43 44 45
    if("x${ARGN}" STREQUAL "x")
      set(${VAR} "")
    else()
      set(${VAR} ${ARGN})
    endif()
46 47 48 49 50
  else()
    #ocv_debug_message("Preserve old value for ${VAR}: ${${VAR}}")
  endif()
endmacro()

51 52
# Search packages for the host system instead of packages for the target system
# in case of cross compilation these macros should be defined by the toolchain file
53
if(NOT COMMAND find_host_package)
54 55 56
  macro(find_host_package)
    find_package(${ARGN})
  endmacro()
57 58
endif()
if(NOT COMMAND find_host_program)
59 60 61
  macro(find_host_program)
    find_program(${ARGN})
  endmacro()
62
endif()
63 64 65 66 67 68 69 70 71 72 73 74

# assert macro
# Note: it doesn't support lists in arguments
# Usage samples:
#   ocv_assert(MyLib_FOUND)
#   ocv_assert(DEFINED MyLib_INCLUDE_DIRS)
macro(ocv_assert)
  if(NOT (${ARGN}))
    string(REPLACE ";" " " __assert_msg "${ARGN}")
    message(AUTHOR_WARNING "Assertion failed: ${__assert_msg}")
  endif()
endmacro()
75

Alexander Alekhin's avatar
Alexander Alekhin committed
76 77 78 79 80
macro(ocv_debug_message)
#  string(REPLACE ";" " " __msg "${ARGN}")
#  message(STATUS "${__msg}")
endmacro()

81 82
macro(ocv_check_environment_variables)
  foreach(_var ${ARGN})
83
    if(" ${${_var}}" STREQUAL " " AND DEFINED ENV{${_var}})
84 85 86 87 88 89 90 91
      set(__value "$ENV{${_var}}")
      file(TO_CMAKE_PATH "${__value}" __value) # Assume that we receive paths
      set(${_var} "${__value}")
      message(STATUS "Update variable ${_var} from environment: ${${_var}}")
    endif()
  endforeach()
endmacro()

92 93 94 95
macro(ocv_path_join result_var P1 P2_)
  string(REGEX REPLACE "^[/]+" "" P2 "${P2_}")
  if("${P1}" STREQUAL "" OR "${P1}" STREQUAL ".")
    set(${result_var} "${P2}")
96 97 98 99 100 101 102
  elseif("${P1}" STREQUAL "/")
    set(${result_var} "/${P2}")
  elseif("${P2}" STREQUAL "")
    set(${result_var} "${P1}")
  else()
    set(${result_var} "${P1}/${P2}")
  endif()
103 104 105 106 107
  string(REGEX REPLACE "([/\\]?)[\\.][/\\]" "\\1" ${result_var} "${${result_var}}")
  if("${${result_var}}" STREQUAL "")
    set(${result_var} ".")
  endif()
  #message(STATUS "'${P1}' '${P2_}' => '${${result_var}}'")
108 109
endmacro()

Alexander Alekhin's avatar
Alexander Alekhin committed
110 111 112 113 114 115 116 117 118
# rename modules target to world if needed
macro(_ocv_fix_target target_var)
  if(BUILD_opencv_world)
    if(OPENCV_MODULE_${${target_var}}_IS_PART_OF_WORLD)
      set(${target_var} opencv_world)
    endif()
  endif()
endmacro()

Alexander Alekhin's avatar
Alexander Alekhin committed
119 120 121 122 123 124 125 126 127 128 129 130
function(ocv_is_opencv_directory result_var dir)
  get_filename_component(__abs_dir "${dir}" ABSOLUTE)
  if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}"
      OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}"
      OR (OPENCV_EXTRA_MODULES_PATH AND "${__abs_dir}" MATCHES "^${OPENCV_EXTRA_MODULES_PATH}"))
    set(${result_var} 1 PARENT_SCOPE)
  else()
    set(${result_var} 0 PARENT_SCOPE)
  endif()
endfunction()


131
# adds include directories in such a way that directories from the OpenCV source tree go first
Vadim Pisarevsky's avatar
Vadim Pisarevsky committed
132
function(ocv_include_directories)
Alexander Alekhin's avatar
Alexander Alekhin committed
133
  ocv_debug_message("ocv_include_directories( ${ARGN} )")
134 135
  set(__add_before "")
  foreach(dir ${ARGN})
Alexander Alekhin's avatar
Alexander Alekhin committed
136 137
    ocv_is_opencv_directory(__is_opencv_dir "${dir}")
    if(__is_opencv_dir)
138
      list(APPEND __add_before "${dir}")
139 140 141
    elseif(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND
           dir MATCHES "/usr/include$")
      # workaround for GCC 6.x bug
142
    else()
Andrey Kamaev's avatar
Andrey Kamaev committed
143
      include_directories(AFTER SYSTEM "${dir}")
144 145 146
    endif()
  endforeach()
  include_directories(BEFORE ${__add_before})
Vadim Pisarevsky's avatar
Vadim Pisarevsky committed
147
endfunction()
148

149 150 151 152 153 154 155 156 157 158
function(ocv_append_target_property target prop)
  get_target_property(val ${target} ${prop})
  if(val)
    set(val "${val} ${ARGN}")
    set_target_properties(${target} PROPERTIES ${prop} "${val}")
  else()
    set_target_properties(${target} PROPERTIES ${prop} "${ARGN}")
  endif()
endfunction()

159 160 161 162 163 164
function(ocv_append_dependant_targets target)
  #ocv_debug_message("ocv_append_dependant_targets(${target} ${ARGN})")
  _ocv_fix_target(target)
  set(OPENCV_DEPENDANT_TARGETS_${target} "${OPENCV_DEPENDANT_TARGETS_${target}};${ARGN}" CACHE INTERNAL "" FORCE)
endfunction()

165
# adds include directories in such a way that directories from the OpenCV source tree go first
Alexander Alekhin's avatar
Alexander Alekhin committed
166
function(ocv_target_include_directories target)
167
  #ocv_debug_message("ocv_target_include_directories(${target} ${ARGN})")
Alexander Alekhin's avatar
Alexander Alekhin committed
168 169
  _ocv_fix_target(target)
  set(__params "")
170 171 172 173
  if(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND
      ";${ARGN};" MATCHES "/usr/include;")
    return() # workaround for GCC 6.x bug
  endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
174 175
  foreach(dir ${ARGN})
    get_filename_component(__abs_dir "${dir}" ABSOLUTE)
Alexander Alekhin's avatar
Alexander Alekhin committed
176 177
    ocv_is_opencv_directory(__is_opencv_dir "${dir}")
    if(__is_opencv_dir)
Alexander Alekhin's avatar
Alexander Alekhin committed
178 179 180 181 182
      list(APPEND __params "${__abs_dir}")
    else()
      list(APPEND __params "${dir}")
    endif()
  endforeach()
183
  if(HAVE_CUDA OR CMAKE_VERSION VERSION_LESS 2.8.11)
Alexander Alekhin's avatar
Alexander Alekhin committed
184 185 186 187
    include_directories(${__params})
  else()
    if(TARGET ${target})
      target_include_directories(${target} PRIVATE ${__params})
188 189 190 191 192
      if(OPENCV_DEPENDANT_TARGETS_${target})
        foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
          target_include_directories(${t} PRIVATE ${__params})
        endforeach()
      endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
193 194 195 196 197 198 199
    else()
      set(__new_inc "${OCV_TARGET_INCLUDE_DIRS_${target}};${__params}")
      set(OCV_TARGET_INCLUDE_DIRS_${target} "${__new_inc}" CACHE INTERNAL "")
    endif()
  endif()
endfunction()

200 201 202
# clears all passed variables
macro(ocv_clear_vars)
  foreach(_var ${ARGN})
203
    unset(${_var})
204 205 206
    unset(${_var} CACHE)
  endforeach()
endmacro()
207

208 209
set(OCV_COMPILER_FAIL_REGEX
    "command line option .* is valid for .* but not for C\\+\\+" # GNU
210
    "command line option .* is valid for .* but not for C" # GNU
211 212 213 214 215 216 217 218
    "unrecognized .*option"                     # GNU
    "unknown .*option"                          # Clang
    "ignoring unknown option"                   # MSVC
    "warning D9002"                             # MSVC, any lang
    "option .*not supported"                    # Intel
    "[Uu]nknown option"                         # HP
    "[Ww]arning: [Oo]ption"                     # SunPro
    "command option .* is not recognized"       # XL
219
    "not supported in this configuration, ignored"       # AIX (';' is replaced with ',')
220 221 222
    "File with unknown suffix passed to linker" # PGI
    "WARNING: unknown flag:"                    # Open64
  )
223

224
MACRO(ocv_check_compiler_flag LANG FLAG RESULT)
225
  set(_fname "${ARGN}")
226
  if(NOT DEFINED ${RESULT})
227 228 229
    if(_fname)
      # nothing
    elseif("_${LANG}_" MATCHES "_CXX_")
230 231 232 233 234 235 236 237 238 239 240 241 242
      set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx")
      if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
        FILE(WRITE "${_fname}" "int main() { return 0; }\n")
      else()
        FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
      endif()
    elseif("_${LANG}_" MATCHES "_C_")
      set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
      if("${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
        FILE(WRITE "${_fname}" "int main(void) { return 0; }\n")
      else()
        FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n")
      endif()
243 244 245 246 247 248 249
    elseif("_${LANG}_" MATCHES "_OBJCXX_")
      set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm")
      if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
        FILE(WRITE "${_fname}" "int main() { return 0; }\n")
      else()
        FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
      endif()
250 251 252 253
    else()
      unset(_fname)
    endif()
    if(_fname)
254 255 256 257 258 259 260
      if(NOT "x${ARGN}" STREQUAL "x")
        file(RELATIVE_PATH __msg "${CMAKE_SOURCE_DIR}" "${ARGN}")
        set(__msg " (check file: ${__msg})")
      else()
        set(__msg "")
      endif()
      MESSAGE(STATUS "Performing Test ${RESULT}${__msg}")
261
      TRY_COMPILE(${RESULT}
262
        "${CMAKE_BINARY_DIR}"
263
        "${_fname}"
264
        CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}"   # CMP0056 do this on new CMake
265 266
        COMPILE_DEFINITIONS "${FLAG}"
        OUTPUT_VARIABLE OUTPUT)
267

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
      if(${RESULT})
        string(REPLACE ";" "," OUTPUT_LINES "${OUTPUT}")
        string(REPLACE "\n" ";" OUTPUT_LINES "${OUTPUT_LINES}")
        foreach(_regex ${OCV_COMPILER_FAIL_REGEX})
          if(NOT ${RESULT})
            break()
          endif()
          foreach(_line ${OUTPUT_LINES})
            if("${_line}" MATCHES "${_regex}")
              file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
                  "Build output check failed:\n"
                  "    Regex: '${_regex}'\n"
                  "    Output line: '${_line}'\n")
              set(${RESULT} 0)
              break()
            endif()
          endforeach()
        endforeach()
      endif()
287

288 289 290 291 292 293
      IF(${RESULT})
        SET(${RESULT} 1 CACHE INTERNAL "Test ${RESULT}")
        MESSAGE(STATUS "Performing Test ${RESULT} - Success")
      ELSE(${RESULT})
        MESSAGE(STATUS "Performing Test ${RESULT} - Failed")
        SET(${RESULT} "" CACHE INTERNAL "Test ${RESULT}")
294 295 296 297 298 299 300
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
            "Compilation failed:\n"
            "    source file: '${_fname}'\n"
            "    check option: '${FLAG}'\n"
            "===== BUILD LOG =====\n"
            "${OUTPUT}\n"
            "===== END =====\n\n")
301 302 303 304
      ENDIF(${RESULT})
    else()
      SET(${RESULT} 0)
    endif()
305 306
  endif()
ENDMACRO()
307

308 309 310 311 312
macro(ocv_check_flag_support lang flag varname base_options)
  if(CMAKE_BUILD_TYPE)
    set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
  endif()

313 314
  if("_${lang}_" MATCHES "_CXX_")
    set(_lang CXX)
315
  elseif("_${lang}_" MATCHES "_C_")
316
    set(_lang C)
317 318
  elseif("_${lang}_" MATCHES "_OBJCXX_")
    set(_lang OBJCXX)
319 320 321 322 323 324
  else()
    set(_lang ${lang})
  endif()

  string(TOUPPER "${flag}" ${varname})
  string(REGEX REPLACE "^(/|-)" "HAVE_${_lang}_" ${varname} "${${varname}}")
Andrey Kamaev's avatar
Andrey Kamaev committed
325
  string(REGEX REPLACE " -|-|=| |\\." "_" ${varname} "${${varname}}")
326

327
  ocv_check_compiler_flag("${_lang}" "${base_options} ${flag}" ${${varname}} ${ARGN})
328 329
endmacro()

Andrey Kamaev's avatar
Andrey Kamaev committed
330 331 332 333 334 335
# turns off warnings
macro(ocv_warnings_disable)
  if(NOT ENABLE_NOISY_WARNINGS)
    set(_flag_vars "")
    set(_msvc_warnings "")
    set(_gxx_warnings "")
336
    set(_icc_warnings "")
Andrey Kamaev's avatar
Andrey Kamaev committed
337 338 339 340 341 342 343
    foreach(arg ${ARGN})
      if(arg MATCHES "^CMAKE_")
        list(APPEND _flag_vars ${arg})
      elseif(arg MATCHES "^/wd")
        list(APPEND _msvc_warnings ${arg})
      elseif(arg MATCHES "^-W")
        list(APPEND _gxx_warnings ${arg})
344 345
      elseif(arg MATCHES "^-wd" OR arg MATCHES "^-Qwd" OR arg MATCHES "^/Qwd")
        list(APPEND _icc_warnings ${arg})
Andrey Kamaev's avatar
Andrey Kamaev committed
346 347 348 349 350 351 352 353
      endif()
    endforeach()
    if(MSVC AND _msvc_warnings AND _flag_vars)
      foreach(var ${_flag_vars})
        foreach(warning ${_msvc_warnings})
          set(${var} "${${var}} ${warning}")
        endforeach()
      endforeach()
354
    elseif((CMAKE_COMPILER_IS_GNUCXX OR (UNIX AND CV_ICC)) AND _gxx_warnings AND _flag_vars)
Andrey Kamaev's avatar
Andrey Kamaev committed
355 356
      foreach(var ${_flag_vars})
        foreach(warning ${_gxx_warnings})
357
          if(NOT warning MATCHES "^-Wno-")
Andrey Kamaev's avatar
Andrey Kamaev committed
358 359
            string(REPLACE "${warning}" "" ${var} "${${var}}")
            string(REPLACE "-W" "-Wno-" warning "${warning}")
360
          endif()
361
          ocv_check_flag_support(${var} "${warning}" _varname "")
362
          if(${_varname})
Andrey Kamaev's avatar
Andrey Kamaev committed
363 364 365 366 367
            set(${var} "${${var}} ${warning}")
          endif()
        endforeach()
      endforeach()
    endif()
368 369 370 371 372 373 374 375
    if(CV_ICC AND _icc_warnings AND _flag_vars)
      foreach(var ${_flag_vars})
        foreach(warning ${_icc_warnings})
          if(UNIX)
            string(REPLACE "-Qwd" "-wd" warning "${warning}")
          else()
            string(REPLACE "-wd" "-Qwd" warning "${warning}")
          endif()
376
          ocv_check_flag_support(${var} "${warning}" _varname "")
377 378 379 380 381 382
          if(${_varname})
            set(${var} "${${var}} ${warning}")
          endif()
        endforeach()
      endforeach()
    endif()
Andrey Kamaev's avatar
Andrey Kamaev committed
383 384 385
    unset(_flag_vars)
    unset(_msvc_warnings)
    unset(_gxx_warnings)
386
    unset(_icc_warnings)
Andrey Kamaev's avatar
Andrey Kamaev committed
387 388 389
  endif(NOT ENABLE_NOISY_WARNINGS)
endmacro()

390
macro(ocv_append_source_file_compile_definitions source)
391 392 393 394 395 396 397 398 399
  get_source_file_property(_value "${source}" COMPILE_DEFINITIONS)
  if(_value)
    set(_value ${_value} ${ARGN})
  else()
    set(_value ${ARGN})
  endif()
  set_source_files_properties("${source}" PROPERTIES COMPILE_DEFINITIONS "${_value}")
endmacro()

400
macro(add_apple_compiler_options the_module)
401
  ocv_check_flag_support(OBJCXX "-fobjc-exceptions" HAVE_OBJC_EXCEPTIONS "")
402 403 404 405 406
  if(HAVE_OBJC_EXCEPTIONS)
    foreach(source ${OPENCV_MODULE_${the_module}_SOURCES})
      if("${source}" MATCHES "\\.mm$")
        get_source_file_property(flags "${source}" COMPILE_FLAGS)
        if(flags)
407
          set(flags "${_flags} -fobjc-exceptions")
408
        else()
409
          set(flags "-fobjc-exceptions")
410 411 412 413 414 415 416 417
        endif()

        set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
      endif()
    endforeach()
  endif()
endmacro()

418 419 420
# Provides an option that the user can optionally select.
# Can accept condition to control when option is available for user.
# Usage:
421
#   option(<option_variable> "help string describing the option" <initial value or boolean expression> [IF <condition>])
422
macro(OCV_OPTION variable description value)
423 424 425 426 427 428 429 430 431 432 433
  set(__value ${value})
  set(__condition "")
  set(__varname "__value")
  foreach(arg ${ARGN})
    if(arg STREQUAL "IF" OR arg STREQUAL "if")
      set(__varname "__condition")
    else()
      list(APPEND ${__varname} ${arg})
    endif()
  endforeach()
  unset(__varname)
434
  if(__condition STREQUAL "")
435
    set(__condition 2 GREATER 1)
436
  endif()
437

438
  if(${__condition})
439
    if(__value MATCHES ";")
440 441 442 443 444 445 446 447 448 449 450 451 452 453
      if(${__value})
        option(${variable} "${description}" ON)
      else()
        option(${variable} "${description}" OFF)
      endif()
    elseif(DEFINED ${__value})
      if(${__value})
        option(${variable} "${description}" ON)
      else()
        option(${variable} "${description}" OFF)
      endif()
    else()
      option(${variable} "${description}" ${__value})
    endif()
454
  else()
455
    unset(${variable} CACHE)
456
  endif()
457 458
  unset(__condition)
  unset(__value)
459 460
endmacro()

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
# Usage: ocv_append_build_options(HIGHGUI FFMPEG)
macro(ocv_append_build_options var_prefix pkg_prefix)
  foreach(suffix INCLUDE_DIRS LIBRARIES LIBRARY_DIRS)
    if(${pkg_prefix}_${suffix})
      list(APPEND ${var_prefix}_${suffix} ${${pkg_prefix}_${suffix}})
      list(REMOVE_DUPLICATES ${var_prefix}_${suffix})
    endif()
  endforeach()
endmacro()

# Usage is similar to CMake 'pkg_check_modules' command
# It additionally controls HAVE_${define} and ${define}_${modname}_FOUND variables
macro(ocv_check_modules define)
  unset(HAVE_${define})
  foreach(m ${ARGN})
    if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
      set(__modname "${CMAKE_MATCH_1}")
    else()
      set(__modname "${m}")
    endif()
    unset(${define}_${__modname}_FOUND)
  endforeach()
  pkg_check_modules(${define} ${ARGN})
  if(${define}_FOUND)
    set(HAVE_${define} 1)
  endif()
  foreach(m ${ARGN})
    if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
      set(__modname "${CMAKE_MATCH_1}")
    else()
      set(__modname "${m}")
    endif()
    if(NOT DEFINED ${define}_${__modname}_FOUND AND ${define}_FOUND)
      set(${define}_${__modname}_FOUND 1)
    endif()
  endforeach()
endmacro()

499

500
# Macro that checks if module has been installed.
501 502
# After it adds module to build and define
# constants passed as second arg
503
macro(CHECK_MODULE module_name define cv_module)
504 505 506 507 508 509 510 511 512 513 514
  set(${define} 0)
  if(PKG_CONFIG_FOUND)
    set(ALIAS               ALIASOF_${module_name})
    set(ALIAS_FOUND                 ${ALIAS}_FOUND)
    set(ALIAS_INCLUDE_DIRS   ${ALIAS}_INCLUDE_DIRS)
    set(ALIAS_LIBRARY_DIRS   ${ALIAS}_LIBRARY_DIRS)
    set(ALIAS_LIBRARIES         ${ALIAS}_LIBRARIES)

    PKG_CHECK_MODULES(${ALIAS} ${module_name})
    if(${ALIAS_FOUND})
      set(${define} 1)
515
      ocv_append_build_options(${cv_module} ${ALIAS})
516
    endif()
517
  endif()
518 519
endmacro()

Alexander Alekhin's avatar
Alexander Alekhin committed
520
if(NOT DEFINED CMAKE_ARGC) # Guard CMake standalone invocations
521

522
set(OPENCV_BUILD_INFO_FILE "${CMAKE_BINARY_DIR}/version_string.tmp")
523 524 525 526 527 528 529 530
file(REMOVE "${OPENCV_BUILD_INFO_FILE}")
function(ocv_output_status msg)
  message(STATUS "${msg}")
  string(REPLACE "\\" "\\\\" msg "${msg}")
  string(REPLACE "\"" "\\\"" msg "${msg}")
  file(APPEND "${OPENCV_BUILD_INFO_FILE}" "\"${msg}\\n\"\n")
endfunction()

Vadim Pisarevsky's avatar
Vadim Pisarevsky committed
531 532
macro(ocv_finalize_status)
  if(NOT OPENCV_SKIP_STATUS_FINALIZATION)
Alexander Alekhin's avatar
Alexander Alekhin committed
533 534
    if(DEFINED OPENCV_MODULE_opencv_core_BINARY_DIR)
      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
Vadim Pisarevsky's avatar
Vadim Pisarevsky committed
535 536
    endif()
  endif()
537 538 539 540 541 542

  if(UNIX)
    install(FILES "${OpenCV_SOURCE_DIR}/platforms/scripts/valgrind.supp"
                  "${OpenCV_SOURCE_DIR}/platforms/scripts/valgrind_3rdparty.supp"
            DESTINATION "${OPENCV_OTHER_INSTALL_PATH}" COMPONENT "dev")
  endif()
Vadim Pisarevsky's avatar
Vadim Pisarevsky committed
543 544 545
endmacro()


546
# Status report function.
547 548 549 550 551
# Automatically align right column and selects text based on condition.
# Usage:
#   status(<text>)
#   status(<heading> <value1> [<value2> ...])
#   status(<heading> <condition> THEN <text for TRUE> ELSE <text for FALSE> )
552
function(status text)
553 554 555 556 557 558 559 560 561 562 563 564 565 566
  set(status_cond)
  set(status_then)
  set(status_else)

  set(status_current_name "cond")
  foreach(arg ${ARGN})
    if(arg STREQUAL "THEN")
      set(status_current_name "then")
    elseif(arg STREQUAL "ELSE")
      set(status_current_name "else")
    else()
      list(APPEND status_${status_current_name} ${arg})
    endif()
  endforeach()
567

568 569 570 571 572 573 574
  if(DEFINED status_cond)
    set(status_placeholder_length 32)
    string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder)
    string(LENGTH "${text}" status_text_length)
    if(status_text_length LESS status_placeholder_length)
      string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text)
    elseif(DEFINED status_then OR DEFINED status_else)
575
      ocv_output_status("${text}")
576 577 578 579 580 581 582 583
      set(status_text "${status_placeholder}")
    else()
      set(status_text "${text}")
    endif()

    if(DEFINED status_then OR DEFINED status_else)
      if(${status_cond})
        string(REPLACE ";" " " status_then "${status_then}")
584 585
        string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}")
        ocv_output_status("${status_text} ${status_then}")
586 587
      else()
        string(REPLACE ";" " " status_else "${status_else}")
588 589
        string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}")
        ocv_output_status("${status_text} ${status_else}")
590 591 592
      endif()
    else()
      string(REPLACE ";" " " status_cond "${status_cond}")
593 594
      string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}")
      ocv_output_status("${status_text} ${status_cond}")
595 596
    endif()
  else()
597
    ocv_output_status("${text}")
598
  endif()
599
endfunction()
600

Alexander Alekhin's avatar
Alexander Alekhin committed
601
endif() # NOT DEFINED CMAKE_ARGC
602

603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
#
# Generate a list of enabled features basing on conditions:
#   IF <cond> THEN <title>: check condition and append title to the result if it is true
#   ELSE <title>: return provided value instead of empty result
#   EXCLUSIVE: break after first successful condition
#
# Usage:
#   ocv_build_features_string(out [EXLUSIVE] [IF feature THEN title] ... [ELSE title])
#
function(ocv_build_features_string out)
  set(result)
  list(REMOVE_AT ARGV 0)
  foreach(arg ${ARGV})
    if(arg STREQUAL "EXCLUSIVE")
      set(exclusive TRUE)
    elseif(arg STREQUAL "IF")
      set(then FALSE)
      set(cond)
    elseif(arg STREQUAL "THEN")
      set(then TRUE)
      set(title)
    elseif(arg STREQUAL "ELSE")
      set(then FALSE)
      set(else TRUE)
    else()
      if(then)
        if(${cond})
          list(APPEND result "${arg}")
          if(exclusive)
            break()
          endif()
        endif()
      elseif(else)
        if(NOT result)
          set(result "${arg}")
        endif()
      else()
        list(APPEND cond ${arg})
      endif()
    endif()
  endforeach()
  set(${out} ${result} PARENT_SCOPE)
endfunction()


648 649 650 651 652 653 654 655 656
# remove all matching elements from the list
macro(ocv_list_filterout lst regex)
  foreach(item ${${lst}})
    if(item MATCHES "${regex}")
      list(REMOVE_ITEM ${lst} "${item}")
    endif()
  endforeach()
endmacro()

657

658 659 660 661 662 663 664
# stable & safe duplicates removal macro
macro(ocv_list_unique __lst)
  if(${__lst})
    list(REMOVE_DUPLICATES ${__lst})
  endif()
endmacro()

665

666 667 668 669 670 671 672
# safe list reversal macro
macro(ocv_list_reverse __lst)
  if(${__lst})
    list(REVERSE ${__lst})
  endif()
endmacro()

673

674 675 676 677 678 679 680
# safe list sorting macro
macro(ocv_list_sort __lst)
  if(${__lst})
    list(SORT ${__lst})
  endif()
endmacro()

681

682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
# 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()


704
# gets and removes the first element from the list
705 706 707 708 709 710 711 712 713 714
macro(ocv_list_pop_front LST VAR)
  if(${LST})
    list(GET ${LST} 0 ${VAR})
    list(REMOVE_AT ${LST} 0)
  else()
    set(${VAR} "")
  endif()
endmacro()


715 716 717 718
# simple regex escaping routine (does not cover all cases!!!)
macro(ocv_regex_escape var regex)
  string(REGEX REPLACE "([+.*^$])" "\\\\1" ${var} "${regex}")
endmacro()
719 720


721
# convert list of paths to full paths
722
macro(ocv_convert_to_full_paths VAR)
723 724 725 726 727 728 729 730 731
  if(${VAR})
    set(__tmp "")
    foreach(path ${${VAR}})
      get_filename_component(${VAR} "${path}" ABSOLUTE)
      list(APPEND __tmp "${${VAR}}")
    endforeach()
    set(${VAR} ${__tmp})
    unset(__tmp)
  endif()
732 733 734
endmacro()


735
# convert list of paths to libraries names without lib prefix
736 737
function(ocv_convert_to_lib_name var)
  set(tmp "")
738
  foreach(path ${ARGN})
Alexander Alekhin's avatar
Alexander Alekhin committed
739 740
    get_filename_component(tmp_name "${path}" NAME)
    ocv_get_libname(tmp_name "${tmp_name}")
741
    list(APPEND tmp "${tmp_name}")
742
  endforeach()
743 744
  set(${var} ${tmp} PARENT_SCOPE)
endfunction()
745 746


747 748
# add install command
function(ocv_install_target)
749 750 751 752 753
  if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
    install(TARGETS ${ARGN} FRAMEWORK DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH})
  else()
    install(TARGETS ${ARGN})
  endif()
754

755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
  set(isPackage 0)
  unset(__package)
  unset(__target)
  foreach(e ${ARGN})
    if(NOT DEFINED __target)
      set(__target "${e}")
    endif()
    if(isPackage EQUAL 1)
      set(__package "${e}")
      break()
    endif()
    if(e STREQUAL "EXPORT")
      set(isPackage 1)
    endif()
  endforeach()

  if(DEFINED __package)
    list(APPEND ${__package}_TARGETS ${__target})
    set(${__package}_TARGETS "${${__package}_TARGETS}" CACHE INTERNAL "List of ${__package} targets")
  endif()

776 777 778 779 780
  if(MSVS)
    if(NOT INSTALL_IGNORE_PDB AND
        (INSTALL_PDB OR
          (INSTALL_CREATE_DISTRIB AND NOT BUILD_SHARED_LIBS)
        ))
781 782 783 784
      set(__target "${ARGV0}")

      set(isArchive 0)
      set(isDst 0)
785
      unset(__dst)
786 787
      foreach(e ${ARGN})
        if(isDst EQUAL 1)
788
          set(__dst "${e}")
789 790 791 792 793 794 795 796 797 798 799 800
          break()
        endif()
        if(isArchive EQUAL 1 AND e STREQUAL "DESTINATION")
          set(isDst 1)
        endif()
        if(e STREQUAL "ARCHIVE")
          set(isArchive 1)
        else()
          set(isArchive 0)
        endif()
      endforeach()

801 802
#      message(STATUS "Process ${__target} dst=${__dst}...")
      if(DEFINED __dst)
803 804
        # If CMake version is >=3.1.0 or <2.8.12.
        if(NOT CMAKE_VERSION VERSION_LESS 3.1.0 OR CMAKE_VERSION VERSION_LESS 2.8.12)
Alexander Alekhin's avatar
Alexander Alekhin committed
805 806 807
          get_target_property(fname ${__target} LOCATION_DEBUG)
          if(fname MATCHES "\\.lib$")
            string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}")
808
            install(FILES "${fname}" DESTINATION "${__dst}" CONFIGURATIONS Debug OPTIONAL)
Alexander Alekhin's avatar
Alexander Alekhin committed
809
          endif()
810

Alexander Alekhin's avatar
Alexander Alekhin committed
811 812 813
          get_target_property(fname ${__target} LOCATION_RELEASE)
          if(fname MATCHES "\\.lib$")
            string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}")
814
            install(FILES "${fname}" DESTINATION "${__dst}" CONFIGURATIONS Release OPTIONAL)
Alexander Alekhin's avatar
Alexander Alekhin committed
815 816
          endif()
        else()
817 818
          # CMake 2.8.12 broke PDB support for STATIC libraries from MSVS, fix was introduced in CMake 3.1.0.
          message(WARNING "PDB's are not supported from this version of CMake, use CMake version later then 3.1.0 or before 2.8.12.")
819 820
        endif()
      endif()
821 822 823 824 825
    endif()
  endif()
endfunction()


826 827 828 829 830 831
# read set of version defines from the header file
macro(ocv_parse_header FILENAME FILE_VAR)
  set(vars_regex "")
  set(__parnet_scope OFF)
  set(__add_cache OFF)
  foreach(name ${ARGN})
832
    if(${name} STREQUAL "PARENT_SCOPE")
833
      set(__parnet_scope ON)
834
    elseif(${name} STREQUAL "CACHE")
835 836 837 838 839 840 841 842 843 844 845 846 847
      set(__add_cache ON)
    elseif(vars_regex)
      set(vars_regex "${vars_regex}|${name}")
    else()
      set(vars_regex "${name}")
    endif()
  endforeach()
  if(EXISTS "${FILENAME}")
    file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" )
  else()
    unset(${FILE_VAR})
  endif()
  foreach(name ${ARGN})
848
    if(NOT ${name} STREQUAL "PARENT_SCOPE" AND NOT ${name} STREQUAL "CACHE")
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
      if(${FILE_VAR})
        if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*")
          string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}")
        else()
          set(${name} "")
        endif()
        if(__add_cache)
          set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE)
        elseif(__parnet_scope)
          set(${name} "${${name}}" PARENT_SCOPE)
        endif()
      else()
        unset(${name} CACHE)
      endif()
    endif()
  endforeach()
endmacro()

# read single version define from the header file
868 869 870 871 872 873 874
macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME)
  ocv_clear_vars(${LIBNAME}_VERSION_MAJOR
                 ${LIBNAME}_VERSION_MAJOR
                 ${LIBNAME}_VERSION_MINOR
                 ${LIBNAME}_VERSION_PATCH
                 ${LIBNAME}_VERSION_TWEAK
                 ${LIBNAME}_VERSION_STRING)
875 876 877 878
  set(${LIBNAME}_H "")
  if(EXISTS "${HDR_PATH}")
    file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1)
  endif()
879

880 881 882 883
  if(${LIBNAME}_H)
    string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}")
    string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR  "${${LIBNAME}_H}")
    string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}")
884 885 886 887
    set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN})
    set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN})
    set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN})
    set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}")
888 889 890 891

    # append a TWEAK version if it exists:
    set(${LIBNAME}_VERSION_TWEAK "")
    if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
892 893 894 895 896 897
      set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN})
    endif()
    if(${LIBNAME}_VERSION_TWEAK)
      set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN})
    else()
      set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN})
898 899 900
    endif()
  endif()
endmacro()
Anatoly Baksheev's avatar
Anatoly Baksheev committed
901

902 903 904 905 906 907 908
# read single version info from the pkg file
macro(ocv_parse_pkg LIBNAME PKG_PATH SCOPE)
  if(EXISTS "${PKG_PATH}/${LIBNAME}.pc")
    file(STRINGS "${PKG_PATH}/${LIBNAME}.pc" line_to_parse REGEX "^Version:[ \t]+[0-9.]*.*$" LIMIT_COUNT 1)
    STRING(REGEX REPLACE ".*Version: ([^ ]+).*" "\\1" ALIASOF_${LIBNAME}_VERSION "${line_to_parse}" )
  endif()
endmacro()
Anatoly Baksheev's avatar
Anatoly Baksheev committed
909 910 911 912

################################################################################################
# short command to setup source group
function(ocv_source_group group)
Alexander Alekhin's avatar
Alexander Alekhin committed
913 914 915
  if(BUILD_opencv_world AND OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD)
    set(group "${the_module}\\${group}")
  endif()
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
  cmake_parse_arguments(SG "" "DIRBASE" "GLOB;GLOB_RECURSE;FILES" ${ARGN})
  set(files "")
  if(SG_FILES)
    list(APPEND files ${SG_FILES})
  endif()
  if(SG_GLOB)
    file(GLOB srcs ${SG_GLOB})
    list(APPEND files ${srcs})
  endif()
  if(SG_GLOB_RECURSE)
    file(GLOB_RECURSE srcs ${SG_GLOB_RECURSE})
    list(APPEND files ${srcs})
  endif()
  if(SG_DIRBASE)
    foreach(f ${files})
      file(RELATIVE_PATH fpart "${SG_DIRBASE}" "${f}")
      if(fpart MATCHES "^\\.\\.")
        message(AUTHOR_WARNING "Can't detect subpath for source_group command: Group=${group} FILE=${f} DIRBASE=${SG_DIRBASE}")
        set(fpart "")
      else()
        get_filename_component(fpart "${fpart}" PATH)
        if(fpart)
          set(fpart "/${fpart}") # add '/'
          string(REPLACE "/" "\\" fpart "${fpart}")
        endif()
      endif()
      source_group("${group}${fpart}" FILES ${f})
    endforeach()
  else()
    source_group(${group} FILES ${files})
  endif()
947
endfunction()
Alexander Alekhin's avatar
Alexander Alekhin committed
948

Alexander Alekhin's avatar
Alexander Alekhin committed
949
macro(__ocv_push_target_link_libraries)
950 951 952 953
  if(NOT TARGET ${target})
    if(NOT DEFINED OPENCV_MODULE_${target}_LOCATION)
      message(FATAL_ERROR "ocv_target_link_libraries: invalid target: '${target}'")
    endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
954
    set(OPENCV_MODULE_${target}_LINK_DEPS ${OPENCV_MODULE_${target}_LINK_DEPS} ${ARGN} CACHE INTERNAL "" FORCE)
955
  else()
Alexander Alekhin's avatar
Alexander Alekhin committed
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
    target_link_libraries(${target} ${ARGN})
  endif()
endmacro()

function(ocv_target_link_libraries target)
  set(LINK_DEPS ${ARGN})
  _ocv_fix_target(target)
  set(LINK_MODE "LINK_PRIVATE")
  set(LINK_PENDING "")
  foreach(dep ${LINK_DEPS})
    if(" ${dep}" STREQUAL " ${target}")
      # prevent "link to itself" warning (world problem)
    elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL "LINK_PUBLIC")
      if(NOT LINK_PENDING STREQUAL "")
        __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
        set(LINK_PENDING "")
        set(LINK_MODE "${dep}")
      endif()
    else()
      if(BUILD_opencv_world)
        if(OPENCV_MODULE_${dep}_IS_PART_OF_WORLD)
          set(dep opencv_world)
        endif()
      endif()
      list(APPEND LINK_PENDING "${dep}")
    endif()
  endforeach()
  if(NOT LINK_PENDING STREQUAL "")
    __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
985
  endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
986 987
endfunction()

Alexander Alekhin's avatar
Alexander Alekhin committed
988 989 990 991 992 993
function(ocv_target_compile_definitions target)
  _ocv_fix_target(target)
  target_compile_definitions(${target} ${ARGN})
endfunction()


Alexander Alekhin's avatar
Alexander Alekhin committed
994 995 996
function(_ocv_append_target_includes target)
  if(DEFINED OCV_TARGET_INCLUDE_DIRS_${target})
    target_include_directories(${target} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
997 998 999 1000 1001
    if(OPENCV_DEPENDANT_TARGETS_${target})
      foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
        target_include_directories(${t} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
      endforeach()
    endif()
Alexander Alekhin's avatar
Alexander Alekhin committed
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
    unset(OCV_TARGET_INCLUDE_DIRS_${target} CACHE)
  endif()
endfunction()

function(ocv_add_executable target)
  add_executable(${target} ${ARGN})
  _ocv_append_target_includes(${target})
endfunction()

function(ocv_add_library target)
1012 1013 1014
  if(HAVE_CUDA AND ARGN MATCHES "\\.cu")
    ocv_include_directories(${CUDA_INCLUDE_DIRS})
    ocv_cuda_compile(cuda_objs ${ARGN})
1015
    set(OPENCV_MODULE_${target}_CUDA_OBJECTS ${cuda_objs} CACHE INTERNAL "Compiled CUDA object files")
1016 1017 1018
  endif()

  add_library(${target} ${ARGN} ${cuda_objs})
1019

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
  if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
    message(STATUS "Setting Apple target properties for ${target}")

    set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1)

    set_target_properties(${target} PROPERTIES
      FRAMEWORK TRUE
      MACOSX_FRAMEWORK_IDENTIFIER org.opencv
      MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_BINARY_DIR}/ios/Info.plist
      # "current version" in semantic format in Mach-O binary file
      VERSION ${OPENCV_LIBVERSION}
      # "compatibility version" in semantic format in Mach-O binary file
      SOVERSION ${OPENCV_LIBVERSION}
      INSTALL_RPATH ""
      INSTALL_NAME_DIR "@rpath"
      BUILD_WITH_INSTALL_RPATH 1
      LIBRARY_OUTPUT_NAME "opencv2"
      XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
      #PUBLIC_HEADER "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h"
      #XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
    )
  endif()

Alexander Alekhin's avatar
Alexander Alekhin committed
1043
  _ocv_append_target_includes(${target})
1044
endfunction()
1045

1046 1047 1048

macro(ocv_get_libname var_name)
  get_filename_component(__libname "${ARGN}" NAME)
1049
  # libopencv_core.so.3.3 -> opencv_core
1050
  string(REGEX REPLACE "^lib(.+)\\.(a|so|dll)(\\.[.0-9]+)?$" "\\1" __libname "${__libname}")
1051 1052
  # MacOSX: libopencv_core.3.3.1.dylib -> opencv_core
  string(REGEX REPLACE "^lib(.+[^.0-9])\\.([.0-9]+\\.)?dylib$" "\\1" __libname "${__libname}")
1053 1054 1055
  set(${var_name} "${__libname}")
endmacro()

1056 1057 1058 1059 1060 1061 1062 1063 1064
# build the list of opencv libs and dependencies for all modules
#  _modules - variable to hold list of all modules
#  _extra - variable to hold list of extra dependencies
#  _3rdparty - variable to hold list of prebuilt 3rdparty libraries
macro(ocv_get_all_libs _modules _extra _3rdparty)
  set(${_modules} "")
  set(${_extra} "")
  set(${_3rdparty} "")
  foreach(m ${OPENCV_MODULES_PUBLIC})
1065 1066 1067 1068 1069 1070
    if(TARGET ${m})
      get_target_property(deps ${m} INTERFACE_LINK_LIBRARIES)
      if(NOT deps)
        set(deps "")
      endif()
    else()
1071 1072
      set(deps "")
    endif()
1073 1074 1075 1076 1077 1078 1079
    set(_rev_deps "${deps};${m}")
    ocv_list_reverse(_rev_deps)
    foreach (dep ${_rev_deps})
      if(DEFINED OPENCV_MODULE_${dep}_LOCATION)
        list(INSERT ${_modules} 0 ${dep})
      endif()
    endforeach()
1080
    foreach (dep ${deps} ${OPENCV_LINKER_LIBS})
1081
      if (NOT DEFINED OPENCV_MODULE_${dep}_LOCATION)
Alexander Alekhin's avatar
Alexander Alekhin committed
1082 1083 1084 1085 1086 1087
        if(dep MATCHES "^\\$<LINK_ONLY:([^>]+)>$")
          set(dep "${CMAKE_MATCH_1}")
        endif()
        if(dep MATCHES "^\\$<")
          message(WARNING "Unexpected CMake generator expression: ${dep}")
        endif()
1088
        if (TARGET ${dep})
1089 1090 1091
          get_target_property(_type ${dep} TYPE)
          if(_type STREQUAL "STATIC_LIBRARY" AND BUILD_SHARED_LIBS)
            # nothing
1092
          else()
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
            get_target_property(_output ${dep} IMPORTED_LOCATION)
            if(NOT _output)
              get_target_property(_output ${dep} ARCHIVE_OUTPUT_DIRECTORY)
              get_target_property(_output_name ${dep} OUTPUT_NAME)
              if(NOT _output_name)
                set(_output_name "${dep}")
              endif()
            else()
              get_filename_component(_output_name "${_output}" NAME)
            endif()
            string(FIND "${_output}" "${CMAKE_BINARY_DIR}" _POS)
            if (_POS EQUAL 0)
              ocv_get_libname(_libname "${_output_name}")
Alexander Alekhin's avatar
Alexander Alekhin committed
1106
              list(INSERT ${_3rdparty} 0 ${dep})
1107 1108 1109 1110 1111 1112 1113
            else()
              if(_output)
                list(INSERT ${_extra} 0 ${_output})
              else()
                list(INSERT ${_extra} 0 ${dep})
              endif()
            endif()
1114
          endif()
1115 1116 1117
        else()
          list(INSERT ${_extra} 0 ${dep})
        endif()
1118 1119 1120 1121
      endif()
    endforeach()
  endforeach()

1122 1123 1124 1125
  ocv_list_filterout(${_modules} "^[\$]<")
  ocv_list_filterout(${_3rdparty} "^[\$]<")
  ocv_list_filterout(${_extra} "^[\$]<")

1126 1127 1128 1129 1130 1131
  # convert CMake lists to makefile literals
  foreach(lst ${_modules} ${_3rdparty} ${_extra})
    ocv_list_unique(${lst})
    ocv_list_reverse(${lst})
  endforeach()
endmacro()
1132

1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161

function(ocv_add_test_from_target test_name test_kind the_target)
  if(CMAKE_VERSION VERSION_GREATER "2.8" AND NOT CMAKE_CROSSCOMPILING)
    if(NOT "${test_kind}" MATCHES "^(Accuracy|Performance|Sanity)$")
      message(FATAL_ERROR "Unknown test kind : ${test_kind}")
    endif()
    if(NOT TARGET "${the_target}")
      message(FATAL_ERROR "${the_target} is not a CMake target")
    endif()

    string(TOLOWER "${test_kind}" test_kind_lower)
    set(test_report_dir "${CMAKE_BINARY_DIR}/test-reports/${test_kind_lower}")
    file(MAKE_DIRECTORY "${test_report_dir}")

    add_test(NAME "${test_name}"
      COMMAND "${the_target}"
              "--gtest_output=xml:${the_target}.xml"
              ${ARGN})

    set_tests_properties("${test_name}" PROPERTIES
      LABELS "${OPENCV_MODULE_${the_module}_LABEL};${test_kind}"
      WORKING_DIRECTORY "${test_report_dir}")

    if(OPENCV_TEST_DATA_PATH)
      set_tests_properties("${test_name}" PROPERTIES
        ENVIRONMENT "OPENCV_TEST_DATA_PATH=${OPENCV_TEST_DATA_PATH}")
    endif()
  endif()
endfunction()
1162 1163 1164 1165 1166 1167

macro(ocv_add_testdata basedir dest_subdir)
  if(BUILD_TESTS)
    if(NOT CMAKE_CROSSCOMPILING AND NOT INSTALL_TESTS)
      file(COPY ${basedir}/
           DESTINATION ${CMAKE_BINARY_DIR}/${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir}
1168
           ${ARGN}
1169 1170 1171 1172
      )
    endif()
    if(INSTALL_TESTS)
      install(DIRECTORY ${basedir}/
1173
              DESTINATION ${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir}
1174
              COMPONENT "tests"
1175 1176 1177 1178 1179
              ${ARGN}
      )
    endif()
  endif()
endmacro()
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225

macro(ocv_generate_vs_version_file DESTINATION)
  cmake_parse_arguments(VS_VER "" "NAME;FILEDESCRIPTION;FILEVERSION;INTERNALNAME;COPYRIGHT;ORIGINALFILENAME;PRODUCTNAME;PRODUCTVERSION;COMMENTS;FILEVERSION_QUAD;PRODUCTVERSION_QUAD" "" ${ARGN})

  macro(__vs_ver_update_variable name)
    if(VS_VER_NAME AND DEFINED OPENCV_${VS_VER_NAME}_VS_VER_${name})
      set(OPENCV_VS_VER_${name} "${OPENCV_${VS_VER_NAME}_VS_VER_${name}}")
    elseif(VS_VER_${name})
      set(OPENCV_VS_VER_${name} "${VS_VER_${name}}")
    endif()
  endmacro()

  __vs_ver_update_variable(FILEVERSION_QUAD)
  __vs_ver_update_variable(PRODUCTVERSION_QUAD)

  macro(__vs_ver_update_str_variable name)
    if(VS_VER_NAME AND DEFINED OPENCV_${VS_VER_NAME}_VS_VER_${name})
      set(OPENCV_VS_VER_${name}_STR "${OPENCV_${VS_VER_NAME}_VS_VER_${name}}")
    elseif(VS_VER_${name})
      set(OPENCV_VS_VER_${name}_STR "${VS_VER_${name}}")
    endif()
  endmacro()

  __vs_ver_update_str_variable(FILEDESCRIPTION)
  __vs_ver_update_str_variable(FILEVERSION)
  __vs_ver_update_str_variable(INTERNALNAME)
  __vs_ver_update_str_variable(COPYRIGHT)
  __vs_ver_update_str_variable(ORIGINALFILENAME)
  __vs_ver_update_str_variable(PRODUCTNAME)
  __vs_ver_update_str_variable(PRODUCTVERSION)
  __vs_ver_update_str_variable(COMMENTS)

  if(OPENCV_VS_VER_COPYRIGHT_STR)
    set(OPENCV_VS_VER_HAVE_COPYRIGHT_STR 1)
  else()
    set(OPENCV_VS_VER_HAVE_COPYRIGHT_STR 0)
  endif()

  if(OPENCV_VS_VER_COMMENTS_STR)
    set(OPENCV_VS_VER_HAVE_COMMENTS_STR 1)
  else()
    set(OPENCV_VS_VER_HAVE_COMMENTS_STR 0)
  endif()

  configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/vs_version.rc.in" "${DESTINATION}" @ONLY)
endmacro()
Alexander Alekhin's avatar
Alexander Alekhin committed
1226 1227 1228 1229 1230 1231 1232 1233

macro(ocv_cmake_script_append_var content_var)
  foreach(var_name ${ARGN})
    set(${content_var} "${${content_var}}
set(${var_name} \"${${var_name}}\")
")
  endforeach()
endmacro()