Merge pull request #16122 from alalek:cmake_update_cpu_compiler_detection
[platform/upstream/opencv.git] / cmake / OpenCVUtils.cmake
1 if(COMMAND ocv_cmake_dump_vars)  # include guard
2   return()
3 endif()
4
5 include(CMakeParseArguments)
6
7 # Debugging function
8 function(ocv_cmake_dump_vars)
9   set(OPENCV_SUPPRESS_DEPRECATIONS 1)  # suppress deprecation warnings from variable_watch() guards
10   get_cmake_property(__variableNames VARIABLES)
11   cmake_parse_arguments(DUMP "" "TOFILE" "" ${ARGN})
12   set(regex "${DUMP_UNPARSED_ARGUMENTS}")
13   string(TOLOWER "${regex}" regex_lower)
14   set(__VARS "")
15   foreach(__variableName ${__variableNames})
16     string(TOLOWER "${__variableName}" __variableName_lower)
17     if((__variableName MATCHES "${regex}" OR __variableName_lower MATCHES "${regex_lower}")
18         AND NOT __variableName_lower MATCHES "^__")
19       get_property(__value VARIABLE PROPERTY "${__variableName}")
20       set(__VARS "${__VARS}${__variableName}=${__value}\n")
21     endif()
22   endforeach()
23   if(DUMP_TOFILE)
24     file(WRITE ${CMAKE_BINARY_DIR}/${DUMP_TOFILE} "${__VARS}")
25   else()
26     message(AUTHOR_WARNING "${__VARS}")
27   endif()
28 endfunction()
29
30
31 #
32 # CMake script hooks support
33 #
34 option(OPENCV_DUMP_HOOKS_FLOW "Dump called OpenCV hooks" OFF)
35 macro(ocv_cmake_hook_append hook_name)
36   set(__var_name "__OPENCV_CMAKE_HOOKS_${hook_name}")
37   set(__value "${${__var_name}}")
38   message(STATUS "Registering hook '${hook_name}': ${ARGN}")
39   list(APPEND __value ${ARGN})
40   set(${__var_name} "${__value}" CACHE INTERNAL "")
41 endmacro()
42 macro(ocv_cmake_hook hook_name)
43   set(__var_name "__OPENCV_CMAKE_HOOKS_${hook_name}")
44   if(OPENCV_DUMP_HOOKS_FLOW)
45     message(STATUS "Hook ${hook_name} ...")
46   endif()
47   foreach(__hook ${${__var_name}})
48     #message(STATUS "Hook ${hook_name}: calling '${__hook}' ...")
49     if(COMMAND "${__hook}")
50       message(FATAL_ERROR "Indirect calling of CMake commands is not supported yet")
51     else()
52       include("${__hook}")
53     endif()
54   endforeach()
55 endmacro()
56 macro(ocv_cmake_reset_hooks)
57   get_cmake_property(__variableNames VARIABLES)
58   foreach(__variableName ${__variableNames})
59     if(__variableName MATCHES "^__OPENCV_CMAKE_HOOKS_")
60       unset(${__variableName})
61       unset(${__variableName} CACHE)
62     endif()
63   endforeach()
64 endmacro()
65 macro(ocv_cmake_hook_register_dir dir)
66   file(GLOB hook_files RELATIVE "${dir}" "${dir}/*.cmake")
67   foreach(f ${hook_files})
68     if(f MATCHES "^(.+)\\.cmake$")
69       set(hook_name "${CMAKE_MATCH_1}")
70       ocv_cmake_hook_append(${hook_name} "${dir}/${f}")
71     endif()
72   endforeach()
73 endmacro()
74
75
76 function(ocv_cmake_eval var_name)
77   if(DEFINED ${var_name})
78     file(WRITE "${CMAKE_BINARY_DIR}/CMakeCommand-${var_name}.cmake" ${${var_name}})
79     include("${CMAKE_BINARY_DIR}/CMakeCommand-${var_name}.cmake")
80   endif()
81   if(";${ARGN};" MATCHES ";ONCE;")
82     unset(${var_name} CACHE)
83   endif()
84 endfunction()
85
86 macro(ocv_cmake_configure file_name var_name)
87   file(READ "${file_name}" __config)
88   string(CONFIGURE "${__config}" ${var_name} ${ARGN})
89 endmacro()
90
91 macro(ocv_update VAR)
92   if(NOT DEFINED ${VAR})
93     if("x${ARGN}" STREQUAL "x")
94       set(${VAR} "")
95     else()
96       set(${VAR} ${ARGN})
97     endif()
98   else()
99     #ocv_debug_message("Preserve old value for ${VAR}: ${${VAR}}")
100   endif()
101 endmacro()
102
103 function(_ocv_access_removed_variable VAR ACCESS)
104   if(ACCESS STREQUAL "MODIFIED_ACCESS")
105     set(OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE_${VAR} 1 PARENT_SCOPE)
106     return()
107   endif()
108   if(ACCESS MATCHES "UNKNOWN_.*"
109       AND NOT OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE
110       AND NOT OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE_${VAR}
111   )
112     message(WARNING "OpenCV: Variable has been removed from CMake scripts: ${VAR}")
113     set(OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE_${VAR} 1 PARENT_SCOPE)  # suppress similar messages
114   endif()
115 endfunction()
116 macro(ocv_declare_removed_variable VAR)
117   if(NOT DEFINED ${VAR})  # don't hit external variables
118     variable_watch(${VAR} _ocv_access_removed_variable)
119   endif()
120 endmacro()
121 macro(ocv_declare_removed_variables)
122   foreach(_var ${ARGN})
123     ocv_declare_removed_variable(${_var})
124   endforeach()
125 endmacro()
126
127 # Search packages for the host system instead of packages for the target system
128 # in case of cross compilation these macros should be defined by the toolchain file
129 if(NOT COMMAND find_host_package)
130   macro(find_host_package)
131     find_package(${ARGN})
132   endmacro()
133 endif()
134 if(NOT COMMAND find_host_program)
135   macro(find_host_program)
136     find_program(${ARGN})
137   endmacro()
138 endif()
139
140 # assert macro
141 # Note: it doesn't support lists in arguments
142 # Usage samples:
143 #   ocv_assert(MyLib_FOUND)
144 #   ocv_assert(DEFINED MyLib_INCLUDE_DIRS)
145 macro(ocv_assert)
146   if(NOT (${ARGN}))
147     string(REPLACE ";" " " __assert_msg "${ARGN}")
148     message(AUTHOR_WARNING "Assertion failed: ${__assert_msg}")
149   endif()
150 endmacro()
151
152 macro(ocv_debug_message)
153   if(OPENCV_CMAKE_DEBUG_MESSAGES)
154     string(REPLACE ";" " " __msg "${ARGN}")
155     message(STATUS "${__msg}")
156   endif()
157 endmacro()
158
159 macro(ocv_check_environment_variables)
160   foreach(_var ${ARGN})
161     if(" ${${_var}}" STREQUAL " " AND DEFINED ENV{${_var}})
162       set(__value "$ENV{${_var}}")
163       file(TO_CMAKE_PATH "${__value}" __value) # Assume that we receive paths
164       set(${_var} "${__value}")
165       message(STATUS "Update variable ${_var} from environment: ${${_var}}")
166     endif()
167   endforeach()
168 endmacro()
169
170 macro(ocv_path_join result_var P1 P2_)
171   string(REGEX REPLACE "^[/]+" "" P2 "${P2_}")
172   if("${P1}" STREQUAL "" OR "${P1}" STREQUAL ".")
173     set(${result_var} "${P2}")
174   elseif("${P1}" STREQUAL "/")
175     set(${result_var} "/${P2}")
176   elseif("${P2}" STREQUAL "")
177     set(${result_var} "${P1}")
178   else()
179     set(${result_var} "${P1}/${P2}")
180   endif()
181   string(REPLACE "\\\\" "\\" ${result_var} "${${result_var}}")
182   string(REPLACE "//" "/" ${result_var} "${${result_var}}")
183   string(REGEX REPLACE "(^|[/\\])[\\.][/\\]" "\\1" ${result_var} "${${result_var}}")
184   if("${${result_var}}" STREQUAL "")
185     set(${result_var} ".")
186   endif()
187   #message(STATUS "'${P1}' '${P2_}' => '${${result_var}}'")
188 endmacro()
189
190
191 # Used to parse Android SDK 'source.properties' files
192 # File lines format:
193 # - '<var_name>=<value>' (with possible 'space' symbols around '=')
194 # - '#<any comment>'
195 # Parsed values are saved into CMake variables:
196 # - '${var_prefix}_${var_name}'
197 # Flags:
198 # - 'CACHE_VAR <var1> <var2>' - put these properties into CMake internal cache
199 # - 'MSG_PREFIX <msg>' - prefix string for emitted messages
200 # - flag 'VALIDATE' - emit messages about missing values from required cached variables
201 # - flag 'WARNING' - emit CMake WARNING instead of STATUS messages
202 function(ocv_parse_properties_file file var_prefix)
203   cmake_parse_arguments(PARSE_PROPERTIES_PARAM "VALIDATE;WARNING" "" "CACHE_VAR;MSG_PREFIX" ${ARGN})
204
205   set(__msg_type STATUS)
206   if(PARSE_PROPERTIES_PARAM_WARNING)
207     set(__msg_type WARNING)
208   endif()
209
210   if(EXISTS "${file}")
211     set(SOURCE_PROPERTIES_REGEX "^[ ]*([^=:\n\"' ]+)[ ]*=[ ]*(.*)$")
212     file(STRINGS "${file}" SOURCE_PROPERTIES_LINES REGEX "^[ ]*[^#].*$")
213     foreach(line ${SOURCE_PROPERTIES_LINES})
214       if(line MATCHES "${SOURCE_PROPERTIES_REGEX}")
215         set(__name "${CMAKE_MATCH_1}")
216         set(__value "${CMAKE_MATCH_2}")
217         string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" __name ${__name})
218         if(";${PARSE_PROPERTIES_PARAM_CACHE_VAR};" MATCHES ";${__name};")
219           set(${var_prefix}_${__name} "${__value}" CACHE INTERNAL "from ${file}")
220         else()
221           set(${var_prefix}_${__name} "${__value}" PARENT_SCOPE)
222         endif()
223       else()
224         message(${__msg_type} "${PARSE_PROPERTIES_PARAM_MSG_PREFIX}Can't parse source property: '${line}' (from ${file})")
225       endif()
226     endforeach()
227     if(PARSE_PROPERTIES_PARAM_VALIDATE)
228       set(__missing "")
229       foreach(__name ${PARSE_PROPERTIES_PARAM_CACHE_VAR})
230         if(NOT DEFINED ${var_prefix}_${__name})
231           list(APPEND __missing ${__name})
232         endif()
233       endforeach()
234       if(__missing)
235         message(${__msg_type} "${PARSE_PROPERTIES_PARAM_MSG_PREFIX}Can't read properties '${__missing}' from '${file}'")
236       endif()
237     endif()
238   else()
239     message(${__msg_type} "${PARSE_PROPERTIES_PARAM_MSG_PREFIX}Can't find file: ${file}")
240   endif()
241 endfunction()
242
243
244
245 # rename modules target to world if needed
246 macro(_ocv_fix_target target_var)
247   if(BUILD_opencv_world)
248     if(OPENCV_MODULE_${${target_var}}_IS_PART_OF_WORLD)
249       set(${target_var} opencv_world)
250     endif()
251   endif()
252 endmacro()
253
254
255 # check if "sub" (file or dir) is below "dir"
256 function(ocv_is_subdir res dir sub )
257   get_filename_component(dir "${dir}" ABSOLUTE)
258   get_filename_component(sub "${sub}" ABSOLUTE)
259   file(TO_CMAKE_PATH "${dir}" dir)
260   file(TO_CMAKE_PATH "${sub}" sub)
261   set(dir "${dir}/")
262   string(LENGTH "${dir}" len)
263   string(LENGTH "${sub}" len_sub)
264   if(NOT len GREATER len_sub)
265     string(SUBSTRING "${sub}" 0 ${len} prefix)
266   endif()
267   if(prefix AND prefix STREQUAL dir)
268     set(${res} TRUE PARENT_SCOPE)
269   else()
270     set(${res} FALSE PARENT_SCOPE)
271   endif()
272 endfunction()
273
274
275 function(ocv_is_opencv_directory result_var dir)
276   set(result FALSE)
277   foreach(parent ${OpenCV_SOURCE_DIR} ${OpenCV_BINARY_DIR} ${OPENCV_EXTRA_MODULES_PATH})
278     ocv_is_subdir(result "${parent}" "${dir}")
279     if(result)
280       break()
281     endif()
282   endforeach()
283   set(${result_var} ${result} PARENT_SCOPE)
284 endfunction()
285
286
287 # adds include directories in such a way that directories from the OpenCV source tree go first
288 function(ocv_include_directories)
289   ocv_debug_message("ocv_include_directories( ${ARGN} )")
290   set(__add_before "")
291   foreach(dir ${ARGN})
292     ocv_is_opencv_directory(__is_opencv_dir "${dir}")
293     if(__is_opencv_dir)
294       list(APPEND __add_before "${dir}")
295     elseif(((CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0") OR CV_CLANG) AND
296            dir MATCHES "/usr/include$")
297       # workaround for GCC 6.x bug
298     else()
299       include_directories(AFTER SYSTEM "${dir}")
300     endif()
301   endforeach()
302   include_directories(BEFORE ${__add_before})
303 endfunction()
304
305 function(ocv_append_target_property target prop)
306   get_target_property(val ${target} ${prop})
307   if(val)
308     set(val "${val} ${ARGN}")
309     set_target_properties(${target} PROPERTIES ${prop} "${val}")
310   else()
311     set_target_properties(${target} PROPERTIES ${prop} "${ARGN}")
312   endif()
313 endfunction()
314
315 if(DEFINED OPENCV_DEPENDANT_TARGETS_LIST)
316   foreach(v ${OPENCV_DEPENDANT_TARGETS_LIST})
317     unset(${v} CACHE)
318   endforeach()
319   unset(OPENCV_DEPENDANT_TARGETS_LIST CACHE)
320 endif()
321
322 function(ocv_append_dependant_targets target)
323   #ocv_debug_message("ocv_append_dependant_targets(${target} ${ARGN})")
324   _ocv_fix_target(target)
325   list(FIND OPENCV_DEPENDANT_TARGETS_LIST "OPENCV_DEPENDANT_TARGETS_${target}" __id)
326   if(__id EQUAL -1)
327     list(APPEND OPENCV_DEPENDANT_TARGETS_LIST "OPENCV_DEPENDANT_TARGETS_${target}")
328     list(SORT OPENCV_DEPENDANT_TARGETS_LIST)
329     set(OPENCV_DEPENDANT_TARGETS_LIST "${OPENCV_DEPENDANT_TARGETS_LIST}" CACHE INTERNAL "")
330   endif()
331   set(OPENCV_DEPENDANT_TARGETS_${target} "${OPENCV_DEPENDANT_TARGETS_${target}};${ARGN}" CACHE INTERNAL "" FORCE)
332 endfunction()
333
334 # adds include directories in such a way that directories from the OpenCV source tree go first
335 function(ocv_target_include_directories target)
336   #ocv_debug_message("ocv_target_include_directories(${target} ${ARGN})")
337   _ocv_fix_target(target)
338   set(__params "")
339   if(CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND
340       ";${ARGN};" MATCHES "/usr/include;")
341     return() # workaround for GCC 6.x bug
342   endif()
343   set(__params "")
344   set(__system_params "")
345   set(__var_name __params)
346   foreach(dir ${ARGN})
347     if("${dir}" STREQUAL "SYSTEM")
348       set(__var_name __system_params)
349     else()
350       get_filename_component(__abs_dir "${dir}" ABSOLUTE)
351       ocv_is_opencv_directory(__is_opencv_dir "${dir}")
352       if(__is_opencv_dir)
353         list(APPEND ${__var_name} "${__abs_dir}")
354       else()
355         list(APPEND ${__var_name} "${dir}")
356       endif()
357     endif()
358   endforeach()
359   if(HAVE_CUDA OR CMAKE_VERSION VERSION_LESS 2.8.11)
360     include_directories(${__params})
361     include_directories(SYSTEM ${__system_params})
362   else()
363     if(TARGET ${target})
364       if(__params)
365         target_include_directories(${target} PRIVATE ${__params})
366         if(OPENCV_DEPENDANT_TARGETS_${target})
367           foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
368             target_include_directories(${t} PRIVATE ${__params})
369           endforeach()
370         endif()
371       endif()
372       if(__system_params)
373         target_include_directories(${target} SYSTEM PRIVATE ${__system_params})
374         if(OPENCV_DEPENDANT_TARGETS_${target})
375           foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
376             target_include_directories(${t} SYSTEM PRIVATE ${__system_params})
377           endforeach()
378         endif()
379       endif()
380     else()
381       if(__params)
382         set(__new_inc ${OCV_TARGET_INCLUDE_DIRS_${target}})
383         list(APPEND __new_inc ${__params})
384         set(OCV_TARGET_INCLUDE_DIRS_${target} "${__new_inc}" CACHE INTERNAL "")
385       endif()
386       if(__system_params)
387         set(__new_inc ${OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target}})
388         list(APPEND __new_inc ${__system_params})
389         set(OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target} "${__new_inc}" CACHE INTERNAL "")
390       endif()
391     endif()
392   endif()
393 endfunction()
394
395 # clears all passed variables
396 macro(ocv_clear_vars)
397   foreach(_var ${ARGN})
398     unset(${_var})
399     unset(${_var} CACHE)
400   endforeach()
401 endmacro()
402
403 set(OCV_COMPILER_FAIL_REGEX
404     "argument '.*' is not valid"                # GCC 9+
405     "command line option .* is valid for .* but not for C\\+\\+" # GNU
406     "command line option .* is valid for .* but not for C" # GNU
407     "unrecognized .*option"                     # GNU
408     "unknown .*option"                          # Clang
409     "ignoring unknown option"                   # MSVC
410     "warning D9002"                             # MSVC, any lang
411     "option .*not supported"                    # Intel
412     "[Uu]nknown option"                         # HP
413     "[Ww]arning: [Oo]ption"                     # SunPro
414     "command option .* is not recognized"       # XL
415     "not supported in this configuration, ignored"       # AIX (';' is replaced with ',')
416     "File with unknown suffix passed to linker" # PGI
417     "WARNING: unknown flag:"                    # Open64
418   )
419
420 MACRO(ocv_check_compiler_flag LANG FLAG RESULT)
421   set(_fname "${ARGN}")
422   if(NOT DEFINED ${RESULT})
423     if(_fname)
424       # nothing
425     elseif("_${LANG}_" MATCHES "_CXX_")
426       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx")
427       if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
428         FILE(WRITE "${_fname}" "int main() { return 0; }\n")
429       else()
430         FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
431       endif()
432     elseif("_${LANG}_" MATCHES "_C_")
433       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
434       if("${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
435         FILE(WRITE "${_fname}" "int main(void) { return 0; }\n")
436       else()
437         FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n")
438       endif()
439     elseif("_${LANG}_" MATCHES "_OBJCXX_")
440       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm")
441       if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
442         FILE(WRITE "${_fname}" "int main() { return 0; }\n")
443       else()
444         FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
445       endif()
446     else()
447       unset(_fname)
448     endif()
449     if(_fname)
450       if(NOT "x${ARGN}" STREQUAL "x")
451         file(RELATIVE_PATH __msg "${CMAKE_SOURCE_DIR}" "${ARGN}")
452         set(__msg " (check file: ${__msg})")
453       else()
454         set(__msg "")
455       endif()
456       if(CMAKE_REQUIRED_LIBRARIES)
457         set(__link_libs LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
458       else()
459         set(__link_libs)
460       endif()
461       set(__cmake_flags "")
462       if(CMAKE_EXE_LINKER_FLAGS)  # CMP0056 do this on new CMake
463         list(APPEND __cmake_flags "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}")
464       endif()
465
466       # CMP0067 do this on new CMake
467       if(DEFINED CMAKE_CXX_STANDARD)
468         list(APPEND __cmake_flags "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
469       endif()
470       if(DEFINED CMAKE_CXX_STANDARD_REQUIRED)
471         list(APPEND __cmake_flags "-DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED}")
472       endif()
473       if(DEFINED CMAKE_CXX_EXTENSIONS)
474         list(APPEND __cmake_flags "-DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}")
475       endif()
476
477       MESSAGE(STATUS "Performing Test ${RESULT}${__msg}")
478       TRY_COMPILE(${RESULT}
479         "${CMAKE_BINARY_DIR}"
480         "${_fname}"
481         CMAKE_FLAGS ${__cmake_flags}
482         COMPILE_DEFINITIONS "${FLAG}"
483         ${__link_libs}
484         OUTPUT_VARIABLE OUTPUT)
485
486       if(${RESULT})
487         string(REPLACE ";" "," OUTPUT_LINES "${OUTPUT}")
488         string(REPLACE "\n" ";" OUTPUT_LINES "${OUTPUT_LINES}")
489         foreach(_regex ${OCV_COMPILER_FAIL_REGEX})
490           if(NOT ${RESULT})
491             break()
492           endif()
493           foreach(_line ${OUTPUT_LINES})
494             if("${_line}" MATCHES "${_regex}")
495               file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
496                   "Build output check failed:\n"
497                   "    Regex: '${_regex}'\n"
498                   "    Output line: '${_line}'\n")
499               set(${RESULT} 0)
500               break()
501             endif()
502           endforeach()
503         endforeach()
504       endif()
505
506       IF(${RESULT})
507         SET(${RESULT} 1 CACHE INTERNAL "Test ${RESULT}")
508         MESSAGE(STATUS "Performing Test ${RESULT} - Success")
509       ELSE(${RESULT})
510         MESSAGE(STATUS "Performing Test ${RESULT} - Failed")
511         SET(${RESULT} "" CACHE INTERNAL "Test ${RESULT}")
512         file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
513             "Compilation failed:\n"
514             "    source file: '${_fname}'\n"
515             "    check option: '${FLAG}'\n"
516             "===== BUILD LOG =====\n"
517             "${OUTPUT}\n"
518             "===== END =====\n\n")
519       ENDIF(${RESULT})
520     else()
521       SET(${RESULT} 0)
522     endif()
523   endif()
524 ENDMACRO()
525
526 macro(ocv_check_flag_support lang flag varname base_options)
527   if(CMAKE_BUILD_TYPE)
528     set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
529   endif()
530
531   if("_${lang}_" MATCHES "_CXX_")
532     set(_lang CXX)
533   elseif("_${lang}_" MATCHES "_C_")
534     set(_lang C)
535   elseif("_${lang}_" MATCHES "_OBJCXX_")
536     set(_lang OBJCXX)
537   else()
538     set(_lang ${lang})
539   endif()
540
541   string(TOUPPER "${flag}" ${varname})
542   string(REGEX REPLACE "^(/|-)" "HAVE_${_lang}_" ${varname} "${${varname}}")
543   string(REGEX REPLACE " -|-|=| |\\." "_" ${varname} "${${varname}}")
544
545   ocv_check_compiler_flag("${_lang}" "${base_options} ${flag}" ${${varname}} ${ARGN})
546 endmacro()
547
548 macro(ocv_check_runtime_flag flag result)
549   set(_fname "${ARGN}")
550   if(NOT DEFINED ${result})
551     file(RELATIVE_PATH _rname "${CMAKE_SOURCE_DIR}" "${_fname}")
552     message(STATUS "Performing Runtime Test ${result} (check file: ${_rname})")
553     try_run(exec_return compile_result
554       "${CMAKE_BINARY_DIR}"
555       "${_fname}"
556       CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}" # CMP0056 do this on new CMake
557       COMPILE_DEFINITIONS "${flag}"
558       OUTPUT_VARIABLE OUTPUT)
559
560     if(${compile_result})
561       if(exec_return EQUAL 0)
562         set(${result} 1 CACHE INTERNAL "Runtime Test ${result}")
563         message(STATUS "Performing Runtime Test ${result} - Success")
564       else()
565         message(STATUS "Performing Runtime Test ${result} - Failed(${exec_return})")
566         set(${result} 0 CACHE INTERNAL "Runtime Test ${result}")
567       endif()
568     else()
569       set(${result} 0 CACHE INTERNAL "Runtime Test ${result}")
570       message(STATUS "Performing Runtime Test ${result} - Compiling Failed")
571     endif()
572
573     if(NOT ${result})
574       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
575         "Runtime Test failed:\n"
576         "    source file: '${_fname}'\n"
577         "    check option: '${flag}'\n"
578         "    exec return: ${exec_return}\n"
579         "===== BUILD AND RUNTIME LOG =====\n"
580         "${OUTPUT}\n"
581         "===== END =====\n\n")
582     endif()
583   endif()
584 endmacro()
585
586 # turns off warnings
587 macro(ocv_warnings_disable)
588   if(NOT ENABLE_NOISY_WARNINGS)
589     set(_flag_vars "")
590     set(_msvc_warnings "")
591     set(_gxx_warnings "")
592     set(_icc_warnings "")
593     foreach(arg ${ARGN})
594       if(arg MATCHES "^CMAKE_")
595         list(APPEND _flag_vars ${arg})
596       elseif(arg MATCHES "^/wd")
597         list(APPEND _msvc_warnings ${arg})
598       elseif(arg MATCHES "^-W")
599         list(APPEND _gxx_warnings ${arg})
600       elseif(arg MATCHES "^-wd" OR arg MATCHES "^-Qwd" OR arg MATCHES "^/Qwd")
601         list(APPEND _icc_warnings ${arg})
602       endif()
603     endforeach()
604     if(MSVC AND _msvc_warnings AND _flag_vars)
605       foreach(var ${_flag_vars})
606         foreach(warning ${_msvc_warnings})
607           set(${var} "${${var}} ${warning}")
608         endforeach()
609       endforeach()
610     elseif(((CV_GCC OR CV_CLANG) OR (UNIX AND CV_ICC)) AND _gxx_warnings AND _flag_vars)
611       foreach(var ${_flag_vars})
612         foreach(warning ${_gxx_warnings})
613           if(NOT warning MATCHES "^-Wno-")
614             string(REGEX REPLACE "(^|[ ]+)${warning}(=[^ ]*)?([ ]+|$)" " " ${var} "${${var}}")
615             string(REPLACE "-W" "-Wno-" warning "${warning}")
616           endif()
617           ocv_check_flag_support(${var} "${warning}" _varname "")
618           if(${_varname})
619             set(${var} "${${var}} ${warning}")
620           endif()
621         endforeach()
622       endforeach()
623     endif()
624     if(CV_ICC AND _icc_warnings AND _flag_vars)
625       foreach(var ${_flag_vars})
626         foreach(warning ${_icc_warnings})
627           if(UNIX)
628             string(REPLACE "-Qwd" "-wd" warning "${warning}")
629           else()
630             string(REPLACE "-wd" "-Qwd" warning "${warning}")
631           endif()
632           ocv_check_flag_support(${var} "${warning}" _varname "")
633           if(${_varname})
634             set(${var} "${${var}} ${warning}")
635           endif()
636         endforeach()
637       endforeach()
638     endif()
639     unset(_flag_vars)
640     unset(_msvc_warnings)
641     unset(_gxx_warnings)
642     unset(_icc_warnings)
643   endif(NOT ENABLE_NOISY_WARNINGS)
644 endmacro()
645
646 macro(ocv_append_source_file_compile_definitions source)
647   get_source_file_property(_value "${source}" COMPILE_DEFINITIONS)
648   if(_value)
649     set(_value ${_value} ${ARGN})
650   else()
651     set(_value ${ARGN})
652   endif()
653   set_source_files_properties("${source}" PROPERTIES COMPILE_DEFINITIONS "${_value}")
654 endmacro()
655
656 macro(add_apple_compiler_options the_module)
657   ocv_check_flag_support(OBJCXX "-fobjc-exceptions" HAVE_OBJC_EXCEPTIONS "")
658   if(HAVE_OBJC_EXCEPTIONS)
659     foreach(source ${OPENCV_MODULE_${the_module}_SOURCES})
660       if("${source}" MATCHES "\\.mm$")
661         get_source_file_property(flags "${source}" COMPILE_FLAGS)
662         if(flags)
663           set(flags "${_flags} -fobjc-exceptions")
664         else()
665           set(flags "-fobjc-exceptions")
666         endif()
667
668         set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
669       endif()
670     endforeach()
671   endif()
672 endmacro()
673
674 # Provides an option that the user can optionally select.
675 # Can accept condition to control when option is available for user.
676 # Usage:
677 #   option(<option_variable>
678 #          "help string describing the option"
679 #          <initial value or boolean expression>
680 #          [VISIBLE_IF <condition>]
681 #          [VERIFY <condition>])
682 macro(OCV_OPTION variable description value)
683   set(__value ${value})
684   set(__condition "")
685   set(__verification)
686   set(__varname "__value")
687   foreach(arg ${ARGN})
688     if(arg STREQUAL "IF" OR arg STREQUAL "if" OR arg STREQUAL "VISIBLE_IF")
689       set(__varname "__condition")
690     elseif(arg STREQUAL "VERIFY")
691       set(__varname "__verification")
692     else()
693       list(APPEND ${__varname} ${arg})
694     endif()
695   endforeach()
696   unset(__varname)
697   if(__condition STREQUAL "")
698     set(__condition 2 GREATER 1)
699   endif()
700
701   if(${__condition})
702     if(__value MATCHES ";")
703       if(${__value})
704         option(${variable} "${description}" ON)
705       else()
706         option(${variable} "${description}" OFF)
707       endif()
708     elseif(DEFINED ${__value})
709       if(${__value})
710         option(${variable} "${description}" ON)
711       else()
712         option(${variable} "${description}" OFF)
713       endif()
714     else()
715       option(${variable} "${description}" ${__value})
716     endif()
717   else()
718     if(DEFINED ${variable} AND "${${variable}}"  # emit warnings about turned ON options only.
719         AND NOT (OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION OR "$ENV{OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION}")
720     )
721       message(WARNING "Unexpected option: ${variable} (=${${variable}})\nCondition: IF (${__condition})")
722     endif()
723     if(OPENCV_UNSET_UNSUPPORTED_OPTION)
724       unset(${variable} CACHE)
725     endif()
726   endif()
727   if(__verification)
728     set(OPENCV_VERIFY_${variable} "${__verification}") # variable containing condition to verify
729     list(APPEND OPENCV_VERIFICATIONS "${variable}") # list of variable names (WITH_XXX;WITH_YYY;...)
730   endif()
731   unset(__condition)
732   unset(__value)
733 endmacro()
734
735
736 # Check that each variable stored in OPENCV_VERIFICATIONS list
737 # is consistent with actual detection result (stored as condition in OPENCV_VERIFY_...) variables
738 function(ocv_verify_config)
739   set(broken_options)
740   foreach(var ${OPENCV_VERIFICATIONS})
741     set(evaluated FALSE)
742     if(${OPENCV_VERIFY_${var}})
743       set(evaluated TRUE)
744     endif()
745     status("Verifying ${var}=${${var}} => '${OPENCV_VERIFY_${var}}'=${evaluated}")
746     if (${var} AND NOT evaluated)
747       list(APPEND broken_options ${var})
748       message(WARNING
749         "Option ${var} is enabled but corresponding dependency "
750         "have not been found: \"${OPENCV_VERIFY_${var}}\" is FALSE")
751     elseif(NOT ${var} AND evaluated)
752       list(APPEND broken_options ${var})
753       message(WARNING
754         "Option ${var} is disabled or unset but corresponding dependency "
755         "have been explicitly turned on: \"${OPENCV_VERIFY_${var}}\" is TRUE")
756     endif()
757   endforeach()
758   if(broken_options)
759     string(REPLACE ";" "\n" broken_options "${broken_options}")
760     message(FATAL_ERROR
761       "Some dependencies have not been found or have been forced, "
762       "unset ENABLE_CONFIG_VERIFICATION option to ignore these failures "
763       "or change following options:\n${broken_options}")
764   endif()
765 endfunction()
766
767 # Usage: ocv_append_build_options(HIGHGUI FFMPEG)
768 macro(ocv_append_build_options var_prefix pkg_prefix)
769   foreach(suffix INCLUDE_DIRS LIBRARIES LIBRARY_DIRS LINK_LIBRARIES)
770     if(${pkg_prefix}_${suffix})
771       list(APPEND ${var_prefix}_${suffix} ${${pkg_prefix}_${suffix}})
772       list(REMOVE_DUPLICATES ${var_prefix}_${suffix})
773     endif()
774   endforeach()
775 endmacro()
776
777 function(ocv_append_source_files_cxx_compiler_options files_var)
778   set(__flags "${ARGN}")
779   ocv_check_flag_support(CXX "${__flags}" __HAVE_COMPILER_OPTIONS_VAR "")
780   if(${__HAVE_COMPILER_OPTIONS_VAR})
781     foreach(source ${${files_var}})
782       if("${source}" MATCHES "\\.(cpp|cc|cxx)$")
783         get_source_file_property(flags "${source}" COMPILE_FLAGS)
784         if(flags)
785           set(flags "${flags} ${__flags}")
786         else()
787           set(flags "${__flags}")
788         endif()
789         set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
790       endif()
791     endforeach()
792   endif()
793 endfunction()
794
795 # Usage is similar to CMake 'pkg_check_modules' command
796 # It additionally controls HAVE_${define} and ${define}_${modname}_FOUND variables
797 macro(ocv_check_modules define)
798   unset(HAVE_${define})
799   foreach(m ${ARGN})
800     if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
801       set(__modname "${CMAKE_MATCH_1}")
802     else()
803       set(__modname "${m}")
804     endif()
805     unset(${define}_${__modname}_FOUND)
806   endforeach()
807   if(PKG_CONFIG_FOUND OR PkgConfig_FOUND)
808     pkg_check_modules(${define} ${ARGN})
809   endif()
810   if(${define}_FOUND)
811     set(HAVE_${define} 1)
812   endif()
813   foreach(m ${ARGN})
814     if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
815       set(__modname "${CMAKE_MATCH_1}")
816     else()
817       set(__modname "${m}")
818     endif()
819     if(NOT DEFINED ${define}_${__modname}_FOUND AND ${define}_FOUND)
820       set(${define}_${__modname}_FOUND 1)
821     endif()
822   endforeach()
823   if(${define}_FOUND AND ${define}_LIBRARIES)
824     if(${define}_LINK_LIBRARIES_XXXXX)  # CMake 3.12+: https://gitlab.kitware.com/cmake/cmake/merge_requests/2068
825       set(${define}_LIBRARIES "${${define}_LINK_LIBRARIES}" CACHE INTERNAL "")
826     else()
827       unset(_libs)          # absolute paths
828       unset(_libs_paths)  # -L args
829       foreach(flag ${${define}_LDFLAGS})
830         if(flag MATCHES "^-L(.*)")
831           list(APPEND _libs_paths ${CMAKE_MATCH_1})
832         elseif(IS_ABSOLUTE "${flag}")
833           list(APPEND _libs "${flag}")
834         elseif(flag MATCHES "^-l(.*)")
835           set(_lib "${CMAKE_MATCH_1}")
836           if(_libs_paths)
837             find_library(pkgcfg_lib_${define}_${_lib} NAMES ${_lib}
838                          HINTS ${_libs_paths} NO_DEFAULT_PATH)
839           endif()
840           find_library(pkgcfg_lib_${define}_${_lib} NAMES ${_lib})
841           mark_as_advanced(pkgcfg_lib_${define}_${_lib})
842           if(pkgcfg_lib_${define}_${_lib})
843             list(APPEND _libs "${pkgcfg_lib_${define}_${_lib}}")
844           else()
845             message(WARNING "ocv_check_modules(${define}): can't find library '${_lib}'. Specify 'pkgcfg_lib_${define}_${_lib}' manually")
846             list(APPEND _libs "${_lib}")
847           endif()
848         else()
849           # -pthread
850           #message(WARNING "ocv_check_modules(${define}): unknown LDFLAG '${flag}'")
851         endif()
852       endforeach()
853       set(${define}_LINK_LIBRARIES "${_libs}")
854       set(${define}_LIBRARIES "${_libs}" CACHE INTERNAL "")
855       unset(_lib)
856       unset(_libs)
857       unset(_libs_paths)
858     endif()
859   endif()
860 endmacro()
861
862
863
864 if(NOT DEFINED CMAKE_ARGC) # Guard CMake standalone invocations
865
866 # Use this option carefully, CMake's install() will install symlinks instead of real files
867 # It is fine for development, but should not be used by real installations
868 set(__symlink_default OFF)  # preprocessing is required for old CMake like 2.8.12
869 if(DEFINED ENV{BUILD_USE_SYMLINKS})
870   set(__symlink_default $ENV{BUILD_USE_SYMLINKS})
871 endif()
872 OCV_OPTION(BUILD_USE_SYMLINKS "Use symlinks instead of files copying during build (and !!INSTALL!!)" (${__symlink_default}) IF (UNIX OR DEFINED __symlink_default))
873
874 if(CMAKE_VERSION VERSION_LESS "3.2")
875   macro(ocv_cmake_byproducts var_name)
876     set(${var_name}) # nothing
877   endmacro()
878 else()
879   macro(ocv_cmake_byproducts var_name)
880     set(${var_name} BYPRODUCTS ${ARGN})
881   endmacro()
882 endif()
883
884 set(OPENCV_DEPHELPER "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/dephelper" CACHE INTERNAL "")
885 file(MAKE_DIRECTORY ${OPENCV_DEPHELPER})
886
887 if(BUILD_USE_SYMLINKS)
888   set(__file0 "${CMAKE_CURRENT_LIST_FILE}")
889   set(__file1 "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/symlink_test")
890   if(NOT IS_SYMLINK "${__file1}")
891     execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${__file0}" "${__file1}"
892         RESULT_VARIABLE SYMLINK_RESULT)
893     if(NOT SYMLINK_RESULT EQUAL 0)
894       file(REMOVE "${__file1}")
895     endif()
896     if(NOT IS_SYMLINK "${__file1}")
897       set(BUILD_USE_SYMLINKS 0 CACHE INTERNAL "")
898     endif()
899   endif()
900   if(NOT BUILD_USE_SYMLINKS)
901     message(STATUS "Build symlinks are not available (disabled)")
902   endif()
903 endif()
904
905 set(OPENCV_BUILD_INFO_STR "" CACHE INTERNAL "")
906 function(ocv_output_status msg)
907   message(STATUS "${msg}")
908   string(REPLACE "\\" "\\\\" msg "${msg}")
909   string(REPLACE "\"" "\\\"" msg "${msg}")
910   string(REGEX REPLACE "^\n+|\n+$" "" msg "${msg}")
911   if(msg MATCHES "\n")
912     message(WARNING "String to be inserted to version_string.inc has an unexpected line break: '${msg}'")
913     string(REPLACE "\n" "\\n" msg "${msg}")
914   endif()
915   set(OPENCV_BUILD_INFO_STR "${OPENCV_BUILD_INFO_STR}\"${msg}\\n\"\n" CACHE INTERNAL "")
916 endfunction()
917
918 macro(ocv_finalize_status)
919   set(OPENCV_BUILD_INFO_FILE "${CMAKE_BINARY_DIR}/version_string.tmp")
920   if(EXISTS "${OPENCV_BUILD_INFO_FILE}")
921     file(READ "${OPENCV_BUILD_INFO_FILE}" __content)
922   else()
923     set(__content "")
924   endif()
925   if("${__content}" STREQUAL "${OPENCV_BUILD_INFO_STR}")
926     #message(STATUS "${OPENCV_BUILD_INFO_FILE} contains the same content")
927   else()
928     file(WRITE "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_BUILD_INFO_STR}")
929   endif()
930   unset(__content)
931   unset(OPENCV_BUILD_INFO_STR CACHE)
932
933   if(NOT OPENCV_SKIP_STATUS_FINALIZATION)
934     if(DEFINED OPENCV_MODULE_opencv_core_BINARY_DIR)
935       execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
936     endif()
937   endif()
938
939   if(UNIX)
940     install(FILES "${OpenCV_SOURCE_DIR}/platforms/scripts/valgrind.supp"
941                   "${OpenCV_SOURCE_DIR}/platforms/scripts/valgrind_3rdparty.supp"
942             DESTINATION "${OPENCV_OTHER_INSTALL_PATH}" COMPONENT "dev")
943   endif()
944 endmacro()
945
946
947 # Status report function.
948 # Automatically align right column and selects text based on condition.
949 # Usage:
950 #   status(<text>)
951 #   status(<heading> <value1> [<value2> ...])
952 #   status(<heading> <condition> THEN <text for TRUE> ELSE <text for FALSE> )
953 function(status text)
954   set(status_cond)
955   set(status_then)
956   set(status_else)
957
958   set(status_current_name "cond")
959   foreach(arg ${ARGN})
960     if(arg STREQUAL "THEN")
961       set(status_current_name "then")
962     elseif(arg STREQUAL "ELSE")
963       set(status_current_name "else")
964     else()
965       list(APPEND status_${status_current_name} ${arg})
966     endif()
967   endforeach()
968
969   if(DEFINED status_cond)
970     set(status_placeholder_length 32)
971     string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder)
972     string(LENGTH "${text}" status_text_length)
973     if(status_text_length LESS status_placeholder_length)
974       string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text)
975     elseif(DEFINED status_then OR DEFINED status_else)
976       ocv_output_status("${text}")
977       set(status_text "${status_placeholder}")
978     else()
979       set(status_text "${text}")
980     endif()
981
982     if(DEFINED status_then OR DEFINED status_else)
983       if(${status_cond})
984         string(REPLACE ";" " " status_then "${status_then}")
985         string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}")
986         ocv_output_status("${status_text} ${status_then}")
987       else()
988         string(REPLACE ";" " " status_else "${status_else}")
989         string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}")
990         ocv_output_status("${status_text} ${status_else}")
991       endif()
992     else()
993       string(REPLACE ";" " " status_cond "${status_cond}")
994       string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}")
995       ocv_output_status("${status_text} ${status_cond}")
996     endif()
997   else()
998     ocv_output_status("${text}")
999   endif()
1000 endfunction()
1001
1002 endif() # NOT DEFINED CMAKE_ARGC
1003
1004 #
1005 # Generate a list of enabled features basing on conditions:
1006 #   IF <cond> THEN <title>: check condition and append title to the result if it is true
1007 #   ELSE <title>: return provided value instead of empty result
1008 #   EXCLUSIVE: break after first successful condition
1009 #
1010 # Usage:
1011 #   ocv_build_features_string(out [EXCLUSIVE] [IF feature THEN title] ... [ELSE title])
1012 #
1013 function(ocv_build_features_string out)
1014   set(result)
1015   list(REMOVE_AT ARGV 0)
1016   foreach(arg ${ARGV})
1017     if(arg STREQUAL "EXCLUSIVE")
1018       set(exclusive TRUE)
1019     elseif(arg STREQUAL "IF")
1020       set(then FALSE)
1021       set(cond)
1022     elseif(arg STREQUAL "THEN")
1023       set(then TRUE)
1024       set(title)
1025     elseif(arg STREQUAL "ELSE")
1026       set(then FALSE)
1027       set(else TRUE)
1028     else()
1029       if(then)
1030         if(${cond})
1031           list(APPEND result "${arg}")
1032           if(exclusive)
1033             break()
1034           endif()
1035         endif()
1036       elseif(else)
1037         if(NOT result)
1038           set(result "${arg}")
1039         endif()
1040       else()
1041         list(APPEND cond ${arg})
1042       endif()
1043     endif()
1044   endforeach()
1045   set(${out} ${result} PARENT_SCOPE)
1046 endfunction()
1047
1048
1049 # remove all matching elements from the list
1050 macro(ocv_list_filterout lst regex)
1051   foreach(item ${${lst}})
1052     if(item MATCHES "${regex}")
1053       list(REMOVE_ITEM ${lst} "${item}")
1054     endif()
1055   endforeach()
1056 endmacro()
1057
1058 # filter matching elements from the list
1059 macro(ocv_list_filter lst regex)
1060   set(dst ${ARGN})
1061   if(NOT dst)
1062     set(dst ${lst})
1063   endif()
1064   set(__result ${${lst}})
1065   foreach(item ${__result})
1066     if(NOT item MATCHES "${regex}")
1067       list(REMOVE_ITEM __result "${item}")
1068     endif()
1069   endforeach()
1070   set(${dst} ${__result})
1071 endmacro()
1072
1073
1074 # stable & safe duplicates removal macro
1075 macro(ocv_list_unique __lst)
1076   if(${__lst})
1077     list(REMOVE_DUPLICATES ${__lst})
1078   endif()
1079 endmacro()
1080
1081
1082 # safe list reversal macro
1083 macro(ocv_list_reverse __lst)
1084   if(${__lst})
1085     list(REVERSE ${__lst})
1086   endif()
1087 endmacro()
1088
1089
1090 # safe list sorting macro
1091 macro(ocv_list_sort __lst)
1092   if(${__lst})
1093     list(SORT ${__lst})
1094   endif()
1095 endmacro()
1096
1097
1098 # add prefix to each item in the list
1099 macro(ocv_list_add_prefix LST PREFIX)
1100   set(__tmp "")
1101   foreach(item ${${LST}})
1102     list(APPEND __tmp "${PREFIX}${item}")
1103   endforeach()
1104   set(${LST} ${__tmp})
1105   unset(__tmp)
1106 endmacro()
1107
1108
1109 # add suffix to each item in the list
1110 macro(ocv_list_add_suffix LST SUFFIX)
1111   set(__tmp "")
1112   foreach(item ${${LST}})
1113     list(APPEND __tmp "${item}${SUFFIX}")
1114   endforeach()
1115   set(${LST} ${__tmp})
1116   unset(__tmp)
1117 endmacro()
1118
1119
1120 # gets and removes the first element from the list
1121 macro(ocv_list_pop_front LST VAR)
1122   if(${LST})
1123     list(GET ${LST} 0 ${VAR})
1124     list(REMOVE_AT ${LST} 0)
1125   else()
1126     set(${VAR} "")
1127   endif()
1128 endmacro()
1129
1130 # Get list of duplicates in the list of input items.
1131 # ocv_get_duplicates(<output list> <element> [<element> ...])
1132 function(ocv_get_duplicates res)
1133   if(ARGC LESS 2)
1134     message(FATAL_ERROR "Invalid call to ocv_get_duplicates")
1135   endif()
1136   set(lst ${ARGN})
1137   list(SORT lst)
1138   set(prev_item)
1139   foreach(item ${lst})
1140     if(item STREQUAL prev_item)
1141       list(APPEND dups ${item})
1142     endif()
1143     set(prev_item ${item})
1144   endforeach()
1145   set(${res} ${dups} PARENT_SCOPE)
1146 endfunction()
1147
1148 # simple regex escaping routine (does not cover all cases!!!)
1149 macro(ocv_regex_escape var regex)
1150   string(REGEX REPLACE "([+.*^$])" "\\\\1" ${var} "${regex}")
1151 endmacro()
1152
1153
1154 # convert list of paths to full paths
1155 macro(ocv_convert_to_full_paths VAR)
1156   if(${VAR})
1157     set(__tmp "")
1158     foreach(path ${${VAR}})
1159       get_filename_component(${VAR} "${path}" ABSOLUTE)
1160       list(APPEND __tmp "${${VAR}}")
1161     endforeach()
1162     set(${VAR} ${__tmp})
1163     unset(__tmp)
1164   endif()
1165 endmacro()
1166
1167
1168 # convert list of paths to libraries names without lib prefix
1169 function(ocv_convert_to_lib_name var)
1170   set(tmp "")
1171   foreach(path ${ARGN})
1172     get_filename_component(tmp_name "${path}" NAME)
1173     ocv_get_libname(tmp_name "${tmp_name}")
1174     list(APPEND tmp "${tmp_name}")
1175   endforeach()
1176   set(${var} ${tmp} PARENT_SCOPE)
1177 endfunction()
1178
1179
1180 # add install command
1181 function(ocv_install_target)
1182   if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
1183     install(TARGETS ${ARGN} FRAMEWORK DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH})
1184   else()
1185     install(TARGETS ${ARGN})
1186   endif()
1187
1188   set(isPackage 0)
1189   unset(__package)
1190   unset(__target)
1191   foreach(e ${ARGN})
1192     if(NOT DEFINED __target)
1193       set(__target "${e}")
1194     endif()
1195     if(isPackage EQUAL 1)
1196       set(__package "${e}")
1197       break()
1198     endif()
1199     if(e STREQUAL "EXPORT")
1200       set(isPackage 1)
1201     endif()
1202   endforeach()
1203
1204   if(DEFINED __package)
1205     list(APPEND ${__package}_TARGETS ${__target})
1206     set(${__package}_TARGETS "${${__package}_TARGETS}" CACHE INTERNAL "List of ${__package} targets")
1207   endif()
1208
1209   if(MSVC)
1210     set(__target "${ARGV0}")
1211
1212     # don't move this into global scope of this file: compiler settings (like MSVC variable) are not available during processing
1213     if(BUILD_SHARED_LIBS)  # no defaults for static libs (modern CMake is required)
1214       if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
1215         option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default" ON)
1216         option(INSTALL_PDB "Add install PDB rules" ON)
1217       elseif(NOT CMAKE_VERSION VERSION_LESS 3.1.0)
1218         option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default (not supported)" OFF)
1219         option(INSTALL_PDB "Add install PDB rules" OFF)
1220       endif()
1221     endif()
1222
1223     if(INSTALL_PDB AND NOT INSTALL_IGNORE_PDB
1224         AND NOT OPENCV_${__target}_PDB_SKIP
1225     )
1226       set(__location_key "ARCHIVE")  # static libs
1227       get_target_property(__target_type ${__target} TYPE)
1228       if("${__target_type}" STREQUAL "SHARED_LIBRARY")
1229         set(__location_key "RUNTIME")  # shared libs (.DLL)
1230       endif()
1231
1232       set(processDst 0)
1233       set(isDst 0)
1234       unset(__dst)
1235       foreach(e ${ARGN})
1236         if(isDst EQUAL 1)
1237           set(__dst "${e}")
1238           break()
1239         endif()
1240         if(processDst EQUAL 1 AND e STREQUAL "DESTINATION")
1241           set(isDst 1)
1242         endif()
1243         if(e STREQUAL "${__location_key}")
1244           set(processDst 1)
1245         else()
1246           set(processDst 0)
1247         endif()
1248       endforeach()
1249
1250 #      message(STATUS "Process ${__target} dst=${__dst}...")
1251       if(DEFINED __dst)
1252         if(NOT CMAKE_VERSION VERSION_LESS 3.1.0)
1253           set(__pdb_install_component "pdb")
1254           if(DEFINED INSTALL_PDB_COMPONENT AND INSTALL_PDB_COMPONENT)
1255             set(__pdb_install_component "${INSTALL_PDB_COMPONENT}")
1256           endif()
1257           set(__pdb_exclude_from_all "")
1258           if(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL)
1259             if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
1260               set(__pdb_exclude_from_all EXCLUDE_FROM_ALL)
1261             else()
1262               message(WARNING "INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL requires CMake 3.6+")
1263             endif()
1264           endif()
1265
1266 #          message(STATUS "Adding PDB file installation rule: target=${__target} dst=${__dst} component=${__pdb_install_component}")
1267           if("${__target_type}" STREQUAL "SHARED_LIBRARY" OR "${__target_type}" STREQUAL "MODULE_LIBRARY")
1268             install(FILES "$<TARGET_PDB_FILE:${__target}>" DESTINATION "${__dst}"
1269                 COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
1270           else()
1271             # There is no generator expression similar to TARGET_PDB_FILE and TARGET_PDB_FILE can't be used: https://gitlab.kitware.com/cmake/cmake/issues/16932
1272             # However we still want .pdb files like: 'lib/Debug/opencv_core341d.pdb' or '3rdparty/lib/zlibd.pdb'
1273             install(FILES "$<TARGET_PROPERTY:${__target},ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<IF:$<BOOL:$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_DEBUG>>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_DEBUG>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME>>.pdb"
1274                 DESTINATION "${__dst}" CONFIGURATIONS Debug
1275                 COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
1276             install(FILES "$<TARGET_PROPERTY:${__target},ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<IF:$<BOOL:$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_RELEASE>>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_RELEASE>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME>>.pdb"
1277                 DESTINATION "${__dst}" CONFIGURATIONS Release
1278                 COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
1279           endif()
1280         else()
1281           message(WARNING "PDB files installation is not supported (need CMake >= 3.1.0)")
1282         endif()
1283       endif()
1284     endif()
1285   endif()
1286 endfunction()
1287
1288 # ocv_install_3rdparty_licenses(<library-name> <filename1> [<filename2> ..])
1289 function(ocv_install_3rdparty_licenses library)
1290   foreach(filename ${ARGN})
1291     set(filepath "${filename}")
1292     if(NOT IS_ABSOLUTE "${filepath}")
1293       set(filepath "${CMAKE_CURRENT_LIST_DIR}/${filepath}")
1294     endif()
1295     get_filename_component(name "${filename}" NAME)
1296     install(
1297       FILES "${filepath}"
1298       DESTINATION "${OPENCV_LICENSES_INSTALL_PATH}"
1299       COMPONENT licenses
1300       RENAME "${library}-${name}"
1301     )
1302   endforeach()
1303 endfunction()
1304
1305 # read set of version defines from the header file
1306 macro(ocv_parse_header FILENAME FILE_VAR)
1307   set(vars_regex "")
1308   set(__parnet_scope OFF)
1309   set(__add_cache OFF)
1310   foreach(name ${ARGN})
1311     if(${name} STREQUAL "PARENT_SCOPE")
1312       set(__parnet_scope ON)
1313     elseif(${name} STREQUAL "CACHE")
1314       set(__add_cache ON)
1315     elseif(vars_regex)
1316       set(vars_regex "${vars_regex}|${name}")
1317     else()
1318       set(vars_regex "${name}")
1319     endif()
1320   endforeach()
1321   if(EXISTS "${FILENAME}")
1322     file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" )
1323   else()
1324     unset(${FILE_VAR})
1325   endif()
1326   foreach(name ${ARGN})
1327     if(NOT ${name} STREQUAL "PARENT_SCOPE" AND NOT ${name} STREQUAL "CACHE")
1328       if(${FILE_VAR})
1329         if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*")
1330           string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}")
1331         else()
1332           set(${name} "")
1333         endif()
1334         if(__add_cache)
1335           set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE)
1336         elseif(__parnet_scope)
1337           set(${name} "${${name}}" PARENT_SCOPE)
1338         endif()
1339       else()
1340         unset(${name} CACHE)
1341       endif()
1342     endif()
1343   endforeach()
1344 endmacro()
1345
1346 # read single version define from the header file
1347 macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME)
1348   ocv_clear_vars(${LIBNAME}_VERSION_MAJOR
1349                  ${LIBNAME}_VERSION_MAJOR
1350                  ${LIBNAME}_VERSION_MINOR
1351                  ${LIBNAME}_VERSION_PATCH
1352                  ${LIBNAME}_VERSION_TWEAK
1353                  ${LIBNAME}_VERSION_STRING)
1354   set(${LIBNAME}_H "")
1355   if(EXISTS "${HDR_PATH}")
1356     file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1)
1357   endif()
1358
1359   if(${LIBNAME}_H)
1360     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}")
1361     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR  "${${LIBNAME}_H}")
1362     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}")
1363     set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN})
1364     set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN})
1365     set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN})
1366     set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}")
1367
1368     # append a TWEAK version if it exists:
1369     set(${LIBNAME}_VERSION_TWEAK "")
1370     if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
1371       set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN})
1372     endif()
1373     if(${LIBNAME}_VERSION_TWEAK)
1374       set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN})
1375     else()
1376       set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN})
1377     endif()
1378   endif()
1379 endmacro()
1380
1381 # TODO remove this
1382 # read single version info from the pkg file
1383 macro(ocv_parse_pkg ver_varname LIBNAME PKG_PATH)
1384   if(EXISTS "${PKG_PATH}/${LIBNAME}.pc")
1385     file(STRINGS "${PKG_PATH}/${LIBNAME}.pc" line_to_parse REGEX "^Version:[ \t]+[0-9.]*.*$" LIMIT_COUNT 1)
1386     STRING(REGEX REPLACE ".*Version: ([^ ]+).*" "\\1" ${ver_varname} "${line_to_parse}" )
1387   endif()
1388 endmacro()
1389
1390 ################################################################################################
1391 # short command to setup source group
1392 function(ocv_source_group group)
1393   if(BUILD_opencv_world AND OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD)
1394     set(group "${the_module}\\${group}")
1395   endif()
1396   cmake_parse_arguments(SG "" "DIRBASE" "GLOB;GLOB_RECURSE;FILES" ${ARGN})
1397   set(files "")
1398   if(SG_FILES)
1399     list(APPEND files ${SG_FILES})
1400   endif()
1401   if(SG_GLOB)
1402     file(GLOB srcs ${SG_GLOB})
1403     list(APPEND files ${srcs})
1404   endif()
1405   if(SG_GLOB_RECURSE)
1406     file(GLOB_RECURSE srcs ${SG_GLOB_RECURSE})
1407     list(APPEND files ${srcs})
1408   endif()
1409   if(SG_DIRBASE)
1410     foreach(f ${files})
1411       file(RELATIVE_PATH fpart "${SG_DIRBASE}" "${f}")
1412       if(fpart MATCHES "^\\.\\.")
1413         message(AUTHOR_WARNING "Can't detect subpath for source_group command: Group=${group} FILE=${f} DIRBASE=${SG_DIRBASE}")
1414         set(fpart "")
1415       else()
1416         get_filename_component(fpart "${fpart}" PATH)
1417         if(fpart)
1418           set(fpart "/${fpart}") # add '/'
1419           string(REPLACE "/" "\\" fpart "${fpart}")
1420         endif()
1421       endif()
1422       source_group("${group}${fpart}" FILES ${f})
1423     endforeach()
1424   else()
1425     source_group(${group} FILES ${files})
1426   endif()
1427 endfunction()
1428
1429 macro(__ocv_push_target_link_libraries)
1430   if(NOT TARGET ${target})
1431     if(NOT DEFINED OPENCV_MODULE_${target}_LOCATION)
1432       message(FATAL_ERROR "ocv_target_link_libraries: invalid target: '${target}'")
1433     endif()
1434     set(OPENCV_MODULE_${target}_LINK_DEPS ${OPENCV_MODULE_${target}_LINK_DEPS} ${ARGN} CACHE INTERNAL "" FORCE)
1435   else()
1436     target_link_libraries(${target} ${ARGN})
1437   endif()
1438 endmacro()
1439
1440 function(ocv_target_link_libraries target)
1441   set(LINK_DEPS ${ARGN})
1442   _ocv_fix_target(target)
1443   set(LINK_MODE "LINK_PRIVATE")
1444   set(LINK_PENDING "")
1445   foreach(dep ${LINK_DEPS})
1446     if(" ${dep}" STREQUAL " ${target}")
1447       # prevent "link to itself" warning (world problem)
1448     elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL "LINK_PUBLIC")
1449       if(NOT LINK_PENDING STREQUAL "")
1450         __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
1451         set(LINK_PENDING "")
1452         set(LINK_MODE "${dep}")
1453       endif()
1454     else()
1455       if(BUILD_opencv_world)
1456         if(OPENCV_MODULE_${dep}_IS_PART_OF_WORLD)
1457           set(dep opencv_world)
1458         endif()
1459       endif()
1460       list(APPEND LINK_PENDING "${dep}")
1461     endif()
1462   endforeach()
1463   if(NOT LINK_PENDING STREQUAL "")
1464     __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
1465   endif()
1466 endfunction()
1467
1468 function(ocv_target_compile_definitions target)
1469   _ocv_fix_target(target)
1470   if(NOT TARGET ${target})
1471     if(NOT DEFINED OPENCV_MODULE_${target}_LOCATION)
1472       message(FATAL_ERROR "ocv_target_compile_definitions: invalid target: '${target}'")
1473     endif()
1474     set(OPENCV_MODULE_${target}_COMPILE_DEFINITIONS ${OPENCV_MODULE_${target}_COMPILE_DEFINITIONS} ${ARGN} CACHE INTERNAL "" FORCE)
1475   else()
1476     target_compile_definitions(${target} ${ARGN})
1477   endif()
1478 endfunction()
1479
1480
1481 function(_ocv_append_target_includes target)
1482   if(DEFINED OCV_TARGET_INCLUDE_DIRS_${target})
1483     target_include_directories(${target} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
1484     if(OPENCV_DEPENDANT_TARGETS_${target})
1485       foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
1486         target_include_directories(${t} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
1487       endforeach()
1488     endif()
1489     unset(OCV_TARGET_INCLUDE_DIRS_${target} CACHE)
1490   endif()
1491
1492   if(DEFINED OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target})
1493     target_include_directories(${target} SYSTEM PRIVATE ${OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target}})
1494     if(OPENCV_DEPENDANT_TARGETS_${target})
1495       foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
1496         target_include_directories(${t} SYSTEM PRIVATE ${OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target}})
1497       endforeach()
1498     endif()
1499     unset(OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target} CACHE)
1500   endif()
1501 endfunction()
1502
1503 function(ocv_add_executable target)
1504   add_executable(${target} ${ARGN})
1505   _ocv_append_target_includes(${target})
1506 endfunction()
1507
1508 function(ocv_add_library target)
1509   if(HAVE_CUDA AND ARGN MATCHES "\\.cu")
1510     ocv_include_directories(${CUDA_INCLUDE_DIRS})
1511     ocv_cuda_compile(cuda_objs ${ARGN})
1512     set(OPENCV_MODULE_${target}_CUDA_OBJECTS ${cuda_objs} CACHE INTERNAL "Compiled CUDA object files")
1513   endif()
1514
1515   add_library(${target} ${ARGN} ${cuda_objs})
1516
1517   if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
1518     message(STATUS "Setting Apple target properties for ${target}")
1519
1520     set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1)
1521
1522     set_target_properties(${target} PROPERTIES
1523       FRAMEWORK TRUE
1524       MACOSX_FRAMEWORK_IDENTIFIER org.opencv
1525       MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_BINARY_DIR}/ios/Info.plist
1526       # "current version" in semantic format in Mach-O binary file
1527       VERSION ${OPENCV_LIBVERSION}
1528       # "compatibility version" in semantic format in Mach-O binary file
1529       SOVERSION ${OPENCV_LIBVERSION}
1530       INSTALL_RPATH ""
1531       INSTALL_NAME_DIR "@rpath"
1532       BUILD_WITH_INSTALL_RPATH 1
1533       LIBRARY_OUTPUT_NAME "opencv2"
1534       XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
1535       #PUBLIC_HEADER "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h"
1536       #XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
1537     )
1538   endif()
1539
1540   _ocv_append_target_includes(${target})
1541 endfunction()
1542
1543
1544 macro(ocv_get_libname var_name)
1545   get_filename_component(__libname "${ARGN}" NAME)
1546   # libopencv_core.so.3.3 -> opencv_core
1547   string(REGEX REPLACE "^lib(.+)\\.(a|so|dll)(\\.[.0-9]+)?$" "\\1" __libname "${__libname}")
1548   # MacOSX: libopencv_core.3.3.1.dylib -> opencv_core
1549   string(REGEX REPLACE "^lib(.+[^.0-9])\\.([.0-9]+\\.)?dylib$" "\\1" __libname "${__libname}")
1550   set(${var_name} "${__libname}")
1551 endmacro()
1552
1553 # build the list of opencv libs and dependencies for all modules
1554 #  _modules - variable to hold list of all modules
1555 #  _extra - variable to hold list of extra dependencies
1556 #  _3rdparty - variable to hold list of prebuilt 3rdparty libraries
1557 macro(ocv_get_all_libs _modules _extra _3rdparty)
1558   set(${_modules} "")
1559   set(${_extra} "")
1560   set(${_3rdparty} "")
1561   foreach(m ${OPENCV_MODULES_PUBLIC})
1562     if(TARGET ${m})
1563       get_target_property(deps ${m} INTERFACE_LINK_LIBRARIES)
1564       if(NOT deps)
1565         set(deps "")
1566       endif()
1567     else()
1568       set(deps "")
1569     endif()
1570     set(_rev_deps "${deps};${m}")
1571     ocv_list_reverse(_rev_deps)
1572     foreach (dep ${_rev_deps})
1573       if(DEFINED OPENCV_MODULE_${dep}_LOCATION)
1574         list(INSERT ${_modules} 0 ${dep})
1575       endif()
1576     endforeach()
1577     foreach (dep ${deps} ${OPENCV_LINKER_LIBS})
1578       if (NOT DEFINED OPENCV_MODULE_${dep}_LOCATION)
1579         if(dep MATCHES "^\\$<LINK_ONLY:([^>]+)>$")
1580           set(dep "${CMAKE_MATCH_1}")
1581         endif()
1582         if(dep MATCHES "^\\$<")
1583           message(WARNING "Unexpected CMake generator expression: ${dep}")
1584         endif()
1585         if (TARGET ${dep})
1586           get_target_property(_type ${dep} TYPE)
1587           if(_type STREQUAL "STATIC_LIBRARY" AND BUILD_SHARED_LIBS OR _type STREQUAL "INTERFACE_LIBRARY")
1588             # nothing
1589           else()
1590             get_target_property(_output ${dep} IMPORTED_LOCATION)
1591             if(NOT _output)
1592               get_target_property(_output ${dep} ARCHIVE_OUTPUT_DIRECTORY)
1593               get_target_property(_output_name ${dep} OUTPUT_NAME)
1594               if(NOT _output_name)
1595                 set(_output_name "${dep}")
1596               endif()
1597             else()
1598               get_filename_component(_output_name "${_output}" NAME)
1599             endif()
1600             string(FIND "${_output}" "${CMAKE_BINARY_DIR}" _POS)
1601             if (_POS EQUAL 0)
1602               ocv_get_libname(_libname "${_output_name}")
1603               list(INSERT ${_3rdparty} 0 ${dep})
1604             else()
1605               if(_output)
1606                 list(INSERT ${_extra} 0 ${_output})
1607               else()
1608                 list(INSERT ${_extra} 0 ${dep})
1609               endif()
1610             endif()
1611           endif()
1612         else()
1613           list(INSERT ${_extra} 0 ${dep})
1614         endif()
1615       endif()
1616     endforeach()
1617   endforeach()
1618
1619   ocv_list_filterout(${_modules} "^[\$]<")
1620   ocv_list_filterout(${_3rdparty} "^[\$]<")
1621   ocv_list_filterout(${_extra} "^[\$]<")
1622
1623   # convert CMake lists to makefile literals
1624   foreach(lst ${_modules} ${_3rdparty} ${_extra})
1625     ocv_list_unique(${lst})
1626     ocv_list_reverse(${lst})
1627   endforeach()
1628 endmacro()
1629
1630
1631 function(ocv_add_test_from_target test_name test_kind the_target)
1632   if(CMAKE_VERSION VERSION_GREATER "2.8" AND NOT CMAKE_CROSSCOMPILING)
1633     if(NOT "${test_kind}" MATCHES "^(Accuracy|Performance|Sanity)$")
1634       message(FATAL_ERROR "Unknown test kind : ${test_kind}")
1635     endif()
1636     if(NOT TARGET "${the_target}")
1637       message(FATAL_ERROR "${the_target} is not a CMake target")
1638     endif()
1639
1640     string(TOLOWER "${test_kind}" test_kind_lower)
1641     set(test_report_dir "${CMAKE_BINARY_DIR}/test-reports/${test_kind_lower}")
1642     file(MAKE_DIRECTORY "${test_report_dir}")
1643
1644     add_test(NAME "${test_name}"
1645       COMMAND "${the_target}"
1646               "--gtest_output=xml:${the_target}.xml"
1647               ${ARGN})
1648
1649     set_tests_properties("${test_name}" PROPERTIES
1650       LABELS "${OPENCV_MODULE_${the_module}_LABEL};${test_kind}"
1651       WORKING_DIRECTORY "${test_report_dir}")
1652
1653     if(OPENCV_TEST_DATA_PATH)
1654       set_tests_properties("${test_name}" PROPERTIES
1655         ENVIRONMENT "OPENCV_TEST_DATA_PATH=${OPENCV_TEST_DATA_PATH}")
1656     endif()
1657   endif()
1658 endfunction()
1659
1660 macro(ocv_add_testdata basedir dest_subdir)
1661   if(BUILD_TESTS)
1662     if(NOT CMAKE_CROSSCOMPILING AND NOT INSTALL_TESTS)
1663       file(COPY ${basedir}/
1664            DESTINATION ${CMAKE_BINARY_DIR}/${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir}
1665            ${ARGN}
1666       )
1667     endif()
1668     if(INSTALL_TESTS)
1669       install(DIRECTORY ${basedir}/
1670               DESTINATION ${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir}
1671               COMPONENT "tests"
1672               ${ARGN}
1673       )
1674     endif()
1675   endif()
1676 endmacro()
1677
1678 macro(ocv_generate_vs_version_file DESTINATION)
1679   cmake_parse_arguments(VS_VER "" "NAME;FILEDESCRIPTION;FILEVERSION;INTERNALNAME;COPYRIGHT;ORIGINALFILENAME;PRODUCTNAME;PRODUCTVERSION;COMMENTS;FILEVERSION_QUAD;PRODUCTVERSION_QUAD" "" ${ARGN})
1680
1681   macro(__vs_ver_update_variable name)
1682     if(VS_VER_NAME AND DEFINED OPENCV_${VS_VER_NAME}_VS_VER_${name})
1683       set(OPENCV_VS_VER_${name} "${OPENCV_${VS_VER_NAME}_VS_VER_${name}}")
1684     elseif(VS_VER_${name})
1685       set(OPENCV_VS_VER_${name} "${VS_VER_${name}}")
1686     endif()
1687   endmacro()
1688
1689   __vs_ver_update_variable(FILEVERSION_QUAD)
1690   __vs_ver_update_variable(PRODUCTVERSION_QUAD)
1691
1692   macro(__vs_ver_update_str_variable name)
1693     if(VS_VER_NAME AND DEFINED OPENCV_${VS_VER_NAME}_VS_VER_${name})
1694       set(OPENCV_VS_VER_${name}_STR "${OPENCV_${VS_VER_NAME}_VS_VER_${name}}")
1695     elseif(VS_VER_${name})
1696       set(OPENCV_VS_VER_${name}_STR "${VS_VER_${name}}")
1697     endif()
1698   endmacro()
1699
1700   __vs_ver_update_str_variable(FILEDESCRIPTION)
1701   __vs_ver_update_str_variable(FILEVERSION)
1702   __vs_ver_update_str_variable(INTERNALNAME)
1703   __vs_ver_update_str_variable(COPYRIGHT)
1704   __vs_ver_update_str_variable(ORIGINALFILENAME)
1705   __vs_ver_update_str_variable(PRODUCTNAME)
1706   __vs_ver_update_str_variable(PRODUCTVERSION)
1707   __vs_ver_update_str_variable(COMMENTS)
1708
1709   if(OPENCV_VS_VER_COPYRIGHT_STR)
1710     set(OPENCV_VS_VER_HAVE_COPYRIGHT_STR 1)
1711   else()
1712     set(OPENCV_VS_VER_HAVE_COPYRIGHT_STR 0)
1713   endif()
1714
1715   if(OPENCV_VS_VER_COMMENTS_STR)
1716     set(OPENCV_VS_VER_HAVE_COMMENTS_STR 1)
1717   else()
1718     set(OPENCV_VS_VER_HAVE_COMMENTS_STR 0)
1719   endif()
1720
1721   configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/vs_version.rc.in" "${DESTINATION}" @ONLY)
1722 endmacro()
1723
1724 macro(ocv_cmake_script_append_var content_var)
1725   foreach(var_name ${ARGN})
1726     set(${content_var} "${${content_var}}
1727 set(${var_name} \"${${var_name}}\")
1728 ")
1729   endforeach()
1730 endmacro()
1731
1732 macro(ocv_copyfiles_append_file list_var src dst)
1733   list(LENGTH ${list_var} __id)
1734   list(APPEND ${list_var} ${__id})
1735   set(${list_var}_SRC_${__id} "${src}")
1736   set(${list_var}_DST_${__id} "${dst}")
1737 endmacro()
1738
1739 macro(ocv_copyfiles_append_dir list_var src dst)
1740   set(__glob ${ARGN})
1741   list(LENGTH ${list_var} __id)
1742   list(APPEND ${list_var} ${__id})
1743   set(${list_var}_SRC_${__id} "${src}")
1744   set(${list_var}_DST_${__id} "${dst}")
1745   set(${list_var}_MODE_${__id} "COPYDIR")
1746   if(__glob)
1747     set(${list_var}_GLOB_${__id} ${__glob})
1748   endif()
1749 endmacro()
1750
1751 macro(ocv_copyfiles_make_config_string content_var list_var)
1752   set(var_name "${list_var}")
1753   set(${content_var} "${${content_var}}
1754 set(${var_name} \"${${var_name}}\")
1755 ")
1756   foreach(__id ${${list_var}})
1757     set(${content_var} "${${content_var}}
1758 set(${list_var}_SRC_${__id} \"${${list_var}_SRC_${__id}}\")
1759 set(${list_var}_DST_${__id} \"${${list_var}_DST_${__id}}\")
1760 ")
1761     if(DEFINED ${list_var}_MODE_${__id})
1762       set(${content_var} "${${content_var}}set(${list_var}_MODE_${__id} \"${${list_var}_MODE_${__id}}\")\n")
1763     endif()
1764     if(DEFINED ${list_var}_GLOB_${__id})
1765       set(${content_var} "${${content_var}}set(${list_var}_GLOB_${__id} \"${${list_var}_GLOB_${__id}}\")\n")
1766     endif()
1767   endforeach()
1768 endmacro()
1769
1770 macro(ocv_copyfiles_make_config_file filename_var list_var)
1771   ocv_copyfiles_make_config_string(${list_var}_CONFIG ${list_var})
1772   set(${filename_var} "${CMAKE_CURRENT_BINARY_DIR}/copyfiles-${list_var}.cmake")
1773   file(WRITE "${${filename_var}}" "${${list_var}_CONFIG}")
1774 endmacro()
1775
1776 macro(ocv_copyfiles_add_forced_target target list_var comment_str)
1777   ocv_copyfiles_make_config_file(CONFIG_FILE ${list_var})
1778   ocv_cmake_byproducts(__byproducts BYPRODUCTS "${OPENCV_DEPHELPER}/${target}")
1779   add_custom_target(${target}
1780       ${__byproducts}  # required for add_custom_target() by ninja
1781       COMMAND ${CMAKE_COMMAND}
1782         "-DCONFIG_FILE:PATH=${CONFIG_FILE}"
1783         "-DCOPYLIST_VAR:STRING=${list_var}"
1784         "-DDEPHELPER=${OPENCV_DEPHELPER}/${target}"
1785         -P "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake"
1786       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
1787       COMMENT "${comment_str}"
1788       DEPENDS "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake"
1789               # ninja warn about file(WRITE): "${SRC_COPY_CONFIG_FILE}"
1790   )
1791 endmacro()
1792
1793 macro(ocv_copyfiles_add_target target list_var comment_str)
1794   set(deps ${ARGN})
1795   ocv_copyfiles_make_config_file(CONFIG_FILE ${list_var})
1796   add_custom_command(OUTPUT "${OPENCV_DEPHELPER}/${target}"
1797       COMMAND ${CMAKE_COMMAND}
1798         "-DCONFIG_FILE:PATH=${CONFIG_FILE}"
1799         "-DCOPYLIST_VAR:STRING=${list_var}"
1800         "-DDEPHELPER=${OPENCV_DEPHELPER}/${target}"
1801         -P "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake"
1802       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
1803       COMMENT "${comment_str}"
1804       DEPENDS "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake" ${deps}
1805               # ninja warn about file(WRITE): "${SRC_COPY_CONFIG_FILE}"
1806   )
1807   add_custom_target(${target} DEPENDS "${OPENCV_DEPHELPER}/${target}")
1808 endmacro()
1809
1810 macro(ocv_get_smart_file_name output_var fpath)
1811   ocv_is_subdir(__subir "${OpenCV_BINARY_DIR}" "${fpath}")
1812   if(__subir)
1813     file(RELATIVE_PATH ${output_var} "${OpenCV_BINARY_DIR}" "${fpath}")
1814     set(${output_var} "<BUILD>/${${output_var}}")
1815   else()
1816     ocv_is_subdir(__subir "${OpenCV_SOURCE_DIR}" "${fpath}")
1817     if(__subir)
1818       file(RELATIVE_PATH ${output_var} "${OpenCV_SOURCE_DIR}" "${fpath}")
1819     else()
1820       set(${output_var} "${fpath}")
1821     endif()
1822   endif()
1823   unset(__subir)
1824 endmacro()
1825
1826 # Needed by install(DIRECTORY ...)
1827 if(NOT CMAKE_VERSION VERSION_LESS 3.1)
1828   set(compatible_MESSAGE_NEVER MESSAGE_NEVER)
1829 else()
1830   set(compatible_MESSAGE_NEVER "")
1831 endif()
1832
1833
1834 macro(ocv_git_describe var_name path)
1835   if(GIT_FOUND)
1836     execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --exact-match --dirty
1837       WORKING_DIRECTORY "${path}"
1838       OUTPUT_VARIABLE ${var_name}
1839       RESULT_VARIABLE GIT_RESULT
1840       ERROR_QUIET
1841       OUTPUT_STRIP_TRAILING_WHITESPACE
1842     )
1843     if(NOT GIT_RESULT EQUAL 0)
1844       execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --always --dirty --match "[0-9].[0-9].[0-9]*" --exclude "[^-]*-cvsdk"
1845         WORKING_DIRECTORY "${path}"
1846         OUTPUT_VARIABLE ${var_name}
1847         RESULT_VARIABLE GIT_RESULT
1848         ERROR_QUIET
1849         OUTPUT_STRIP_TRAILING_WHITESPACE
1850       )
1851       if(NOT GIT_RESULT EQUAL 0)  # --exclude is not supported by 'git'
1852         # match only tags with complete OpenCV versions (ignores -alpha/-beta/-rc suffixes)
1853         execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --always --dirty --match "[0-9].[0-9]*[0-9]"
1854           WORKING_DIRECTORY "${path}"
1855           OUTPUT_VARIABLE ${var_name}
1856           RESULT_VARIABLE GIT_RESULT
1857           ERROR_QUIET
1858           OUTPUT_STRIP_TRAILING_WHITESPACE
1859         )
1860         if(NOT GIT_RESULT EQUAL 0)
1861           set(${var_name} "unknown")
1862         endif()
1863       endif()
1864     endif()
1865   else()
1866     set(${var_name} "unknown")
1867   endif()
1868 endmacro()
1869
1870
1871 # ocv_update_file(filepath content [VERBOSE])
1872 # - write content to file
1873 # - will not change modification time in case when file already exists and content has not changed
1874 function(ocv_update_file filepath content)
1875   if(EXISTS "${filepath}")
1876     file(READ "${filepath}" actual_content)
1877   else()
1878     set(actual_content "")
1879   endif()
1880   if("${actual_content}" STREQUAL "${content}")
1881     if(";${ARGN};" MATCHES ";VERBOSE;")
1882       message(STATUS "${filepath} contains the same content")
1883     endif()
1884   else()
1885     file(WRITE "${filepath}" "${content}")
1886   endif()
1887 endfunction()