Merge remote-tracking branch 'upstream/3.4' into merge-3.4
[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
404 # Clears passed variables with INTERNAL type from CMake cache
405 macro(ocv_clear_internal_cache_vars)
406   foreach(_var ${ARGN})
407     get_property(_propertySet CACHE ${_var} PROPERTY TYPE SET)
408     if(_propertySet)
409       get_property(_type CACHE ${_var} PROPERTY TYPE)
410       if(_type STREQUAL "INTERNAL")
411         message("Cleaning INTERNAL cached variable: ${_var}")
412         unset(${_var} CACHE)
413       endif()
414     endif()
415   endforeach()
416   unset(_propertySet)
417   unset(_type)
418 endmacro()
419
420
421 set(OCV_COMPILER_FAIL_REGEX
422     "argument .* is not valid"                  # GCC 9+ (including support of unicode quotes)
423     "command[- ]line option .* is valid for .* but not for C\\+\\+" # GNU
424     "command[- ]line option .* is valid for .* but not for C" # GNU
425     "unrecognized .*option"                     # GNU
426     "unknown .*option"                          # Clang
427     "ignoring unknown option"                   # MSVC
428     "warning D9002"                             # MSVC, any lang
429     "option .*not supported"                    # Intel
430     "[Uu]nknown option"                         # HP
431     "[Ww]arning: [Oo]ption"                     # SunPro
432     "command option .* is not recognized"       # XL
433     "not supported in this configuration, ignored"       # AIX (';' is replaced with ',')
434     "File with unknown suffix passed to linker" # PGI
435     "WARNING: unknown flag:"                    # Open64
436   )
437
438 MACRO(ocv_check_compiler_flag LANG FLAG RESULT)
439   set(_fname "${ARGN}")
440   if(NOT DEFINED ${RESULT})
441     if(_fname)
442       # nothing
443     elseif("_${LANG}_" MATCHES "_CXX_")
444       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx")
445       if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
446         FILE(WRITE "${_fname}" "int main() { return 0; }\n")
447       else()
448         FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
449       endif()
450     elseif("_${LANG}_" MATCHES "_C_")
451       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
452       if("${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
453         FILE(WRITE "${_fname}" "int main(void) { return 0; }\n")
454       else()
455         FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n")
456       endif()
457     elseif("_${LANG}_" MATCHES "_OBJCXX_")
458       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm")
459       if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
460         FILE(WRITE "${_fname}" "int main() { return 0; }\n")
461       else()
462         FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
463       endif()
464     else()
465       unset(_fname)
466     endif()
467     if(_fname)
468       if(NOT "x${ARGN}" STREQUAL "x")
469         file(RELATIVE_PATH __msg "${CMAKE_SOURCE_DIR}" "${ARGN}")
470         set(__msg " (check file: ${__msg})")
471       else()
472         set(__msg "")
473       endif()
474       if(CMAKE_REQUIRED_LIBRARIES)
475         set(__link_libs LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
476       else()
477         set(__link_libs)
478       endif()
479       set(__cmake_flags "")
480       if(CMAKE_EXE_LINKER_FLAGS)  # CMP0056 do this on new CMake
481         list(APPEND __cmake_flags "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}")
482       endif()
483
484       # CMP0067 do this on new CMake
485       if(DEFINED CMAKE_CXX_STANDARD)
486         list(APPEND __cmake_flags "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
487       endif()
488       if(DEFINED CMAKE_CXX_STANDARD_REQUIRED)
489         list(APPEND __cmake_flags "-DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED}")
490       endif()
491       if(DEFINED CMAKE_CXX_EXTENSIONS)
492         list(APPEND __cmake_flags "-DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}")
493       endif()
494
495       MESSAGE(STATUS "Performing Test ${RESULT}${__msg}")
496       TRY_COMPILE(${RESULT}
497         "${CMAKE_BINARY_DIR}"
498         "${_fname}"
499         CMAKE_FLAGS ${__cmake_flags}
500         COMPILE_DEFINITIONS "${FLAG}"
501         ${__link_libs}
502         OUTPUT_VARIABLE OUTPUT)
503
504       if(${RESULT})
505         string(REPLACE ";" "," OUTPUT_LINES "${OUTPUT}")
506         string(REPLACE "\n" ";" OUTPUT_LINES "${OUTPUT_LINES}")
507         foreach(_regex ${OCV_COMPILER_FAIL_REGEX})
508           if(NOT ${RESULT})
509             break()
510           endif()
511           foreach(_line ${OUTPUT_LINES})
512             if("${_line}" MATCHES "${_regex}")
513               file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
514                   "Build output check failed:\n"
515                   "    Regex: '${_regex}'\n"
516                   "    Output line: '${_line}'\n")
517               set(${RESULT} 0)
518               break()
519             endif()
520           endforeach()
521         endforeach()
522       endif()
523
524       IF(${RESULT})
525         SET(${RESULT} 1 CACHE INTERNAL "Test ${RESULT}")
526         MESSAGE(STATUS "Performing Test ${RESULT} - Success")
527       ELSE(${RESULT})
528         MESSAGE(STATUS "Performing Test ${RESULT} - Failed")
529         SET(${RESULT} "" CACHE INTERNAL "Test ${RESULT}")
530         file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
531             "Compilation failed:\n"
532             "    source file: '${_fname}'\n"
533             "    check option: '${FLAG}'\n"
534             "===== BUILD LOG =====\n"
535             "${OUTPUT}\n"
536             "===== END =====\n\n")
537       ENDIF(${RESULT})
538     else()
539       SET(${RESULT} 0)
540     endif()
541   endif()
542 ENDMACRO()
543
544 macro(ocv_check_flag_support lang flag varname base_options)
545   if(CMAKE_BUILD_TYPE)
546     set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
547   endif()
548
549   if("_${lang}_" MATCHES "_CXX_")
550     set(_lang CXX)
551   elseif("_${lang}_" MATCHES "_C_")
552     set(_lang C)
553   elseif("_${lang}_" MATCHES "_OBJCXX_")
554     set(_lang OBJCXX)
555   else()
556     set(_lang ${lang})
557   endif()
558
559   string(TOUPPER "${flag}" ${varname})
560   string(REGEX REPLACE "^(/|-)" "HAVE_${_lang}_" ${varname} "${${varname}}")
561   string(REGEX REPLACE " -|-|=| |\\.|," "_" ${varname} "${${varname}}")
562
563   ocv_check_compiler_flag("${_lang}" "${base_options} ${flag}" ${${varname}} ${ARGN})
564 endmacro()
565
566 macro(ocv_check_runtime_flag flag result)
567   set(_fname "${ARGN}")
568   if(NOT DEFINED ${result})
569     file(RELATIVE_PATH _rname "${CMAKE_SOURCE_DIR}" "${_fname}")
570     message(STATUS "Performing Runtime Test ${result} (check file: ${_rname})")
571     try_run(exec_return compile_result
572       "${CMAKE_BINARY_DIR}"
573       "${_fname}"
574       CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}" # CMP0056 do this on new CMake
575       COMPILE_DEFINITIONS "${flag}"
576       OUTPUT_VARIABLE OUTPUT)
577
578     if(${compile_result})
579       if(exec_return EQUAL 0)
580         set(${result} 1 CACHE INTERNAL "Runtime Test ${result}")
581         message(STATUS "Performing Runtime Test ${result} - Success")
582       else()
583         message(STATUS "Performing Runtime Test ${result} - Failed(${exec_return})")
584         set(${result} 0 CACHE INTERNAL "Runtime Test ${result}")
585       endif()
586     else()
587       set(${result} 0 CACHE INTERNAL "Runtime Test ${result}")
588       message(STATUS "Performing Runtime Test ${result} - Compiling Failed")
589     endif()
590
591     if(NOT ${result})
592       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
593         "Runtime Test failed:\n"
594         "    source file: '${_fname}'\n"
595         "    check option: '${flag}'\n"
596         "    exec return: ${exec_return}\n"
597         "===== BUILD AND RUNTIME LOG =====\n"
598         "${OUTPUT}\n"
599         "===== END =====\n\n")
600     endif()
601   endif()
602 endmacro()
603
604 # turns off warnings
605 macro(ocv_warnings_disable)
606   if(NOT ENABLE_NOISY_WARNINGS)
607     set(_flag_vars "")
608     set(_msvc_warnings "")
609     set(_gxx_warnings "")
610     set(_icc_warnings "")
611     foreach(arg ${ARGN})
612       if(arg MATCHES "^CMAKE_")
613         list(APPEND _flag_vars ${arg})
614       elseif(arg MATCHES "^/wd")
615         list(APPEND _msvc_warnings ${arg})
616       elseif(arg MATCHES "^-W")
617         list(APPEND _gxx_warnings ${arg})
618       elseif(arg MATCHES "^-wd" OR arg MATCHES "^-Qwd" OR arg MATCHES "^/Qwd")
619         list(APPEND _icc_warnings ${arg})
620       endif()
621     endforeach()
622     if(MSVC AND _msvc_warnings AND _flag_vars)
623       foreach(var ${_flag_vars})
624         foreach(warning ${_msvc_warnings})
625           set(${var} "${${var}} ${warning}")
626         endforeach()
627       endforeach()
628     elseif(((CV_GCC OR CV_CLANG) OR (UNIX AND CV_ICC)) AND _gxx_warnings AND _flag_vars)
629       foreach(var ${_flag_vars})
630         foreach(warning ${_gxx_warnings})
631           if(NOT warning MATCHES "^-Wno-")
632             string(REGEX REPLACE "(^|[ ]+)${warning}(=[^ ]*)?([ ]+|$)" " " ${var} "${${var}}")
633             string(REPLACE "-W" "-Wno-" warning "${warning}")
634           endif()
635           ocv_check_flag_support(${var} "${warning}" _varname "")
636           if(${_varname})
637             set(${var} "${${var}} ${warning}")
638           endif()
639         endforeach()
640       endforeach()
641     endif()
642     if(CV_ICC AND _icc_warnings AND _flag_vars)
643       foreach(var ${_flag_vars})
644         foreach(warning ${_icc_warnings})
645           if(UNIX)
646             string(REPLACE "-Qwd" "-wd" warning "${warning}")
647           else()
648             string(REPLACE "-wd" "-Qwd" warning "${warning}")
649           endif()
650           ocv_check_flag_support(${var} "${warning}" _varname "")
651           if(${_varname})
652             set(${var} "${${var}} ${warning}")
653           endif()
654         endforeach()
655       endforeach()
656     endif()
657     unset(_flag_vars)
658     unset(_msvc_warnings)
659     unset(_gxx_warnings)
660     unset(_icc_warnings)
661   endif(NOT ENABLE_NOISY_WARNINGS)
662 endmacro()
663
664 macro(ocv_append_source_file_compile_definitions source)
665   get_source_file_property(_value "${source}" COMPILE_DEFINITIONS)
666   if(_value)
667     set(_value ${_value} ${ARGN})
668   else()
669     set(_value ${ARGN})
670   endif()
671   set_source_files_properties("${source}" PROPERTIES COMPILE_DEFINITIONS "${_value}")
672 endmacro()
673
674 macro(add_apple_compiler_options the_module)
675   ocv_check_flag_support(OBJCXX "-fobjc-exceptions" HAVE_OBJC_EXCEPTIONS "")
676   if(HAVE_OBJC_EXCEPTIONS)
677     foreach(source ${OPENCV_MODULE_${the_module}_SOURCES})
678       if("${source}" MATCHES "\\.mm$")
679         get_source_file_property(flags "${source}" COMPILE_FLAGS)
680         if(flags)
681           set(flags "${_flags} -fobjc-exceptions")
682         else()
683           set(flags "-fobjc-exceptions")
684         endif()
685
686         set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
687       endif()
688     endforeach()
689   endif()
690 endmacro()
691
692 # Provides an option that the user can optionally select.
693 # Can accept condition to control when option is available for user.
694 # Usage:
695 #   option(<option_variable>
696 #          "help string describing the option"
697 #          <initial value or boolean expression>
698 #          [VISIBLE_IF <condition>]
699 #          [VERIFY <condition>])
700 macro(OCV_OPTION variable description value)
701   set(__value ${value})
702   set(__condition "")
703   set(__verification)
704   set(__varname "__value")
705   foreach(arg ${ARGN})
706     if(arg STREQUAL "IF" OR arg STREQUAL "if" OR arg STREQUAL "VISIBLE_IF")
707       set(__varname "__condition")
708     elseif(arg STREQUAL "VERIFY")
709       set(__varname "__verification")
710     else()
711       list(APPEND ${__varname} ${arg})
712     endif()
713   endforeach()
714   unset(__varname)
715   if(__condition STREQUAL "")
716     set(__condition 2 GREATER 1)
717   endif()
718
719   if(${__condition})
720     if(__value MATCHES ";")
721       if(${__value})
722         option(${variable} "${description}" ON)
723       else()
724         option(${variable} "${description}" OFF)
725       endif()
726     elseif(DEFINED ${__value})
727       if(${__value})
728         option(${variable} "${description}" ON)
729       else()
730         option(${variable} "${description}" OFF)
731       endif()
732     else()
733       option(${variable} "${description}" ${__value})
734     endif()
735   else()
736     if(DEFINED ${variable} AND "${${variable}}"  # emit warnings about turned ON options only.
737         AND NOT (OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION OR "$ENV{OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION}")
738     )
739       message(WARNING "Unexpected option: ${variable} (=${${variable}})\nCondition: IF (${__condition})")
740     endif()
741     if(OPENCV_UNSET_UNSUPPORTED_OPTION)
742       unset(${variable} CACHE)
743     endif()
744   endif()
745   if(__verification)
746     set(OPENCV_VERIFY_${variable} "${__verification}") # variable containing condition to verify
747     list(APPEND OPENCV_VERIFICATIONS "${variable}") # list of variable names (WITH_XXX;WITH_YYY;...)
748   endif()
749   unset(__condition)
750   unset(__value)
751 endmacro()
752
753
754 # Check that each variable stored in OPENCV_VERIFICATIONS list
755 # is consistent with actual detection result (stored as condition in OPENCV_VERIFY_...) variables
756 function(ocv_verify_config)
757   set(broken_options)
758   foreach(var ${OPENCV_VERIFICATIONS})
759     set(evaluated FALSE)
760     if(${OPENCV_VERIFY_${var}})
761       set(evaluated TRUE)
762     endif()
763     status("Verifying ${var}=${${var}} => '${OPENCV_VERIFY_${var}}'=${evaluated}")
764     if (${var} AND NOT evaluated)
765       list(APPEND broken_options ${var})
766       message(WARNING
767         "Option ${var} is enabled but corresponding dependency "
768         "have not been found: \"${OPENCV_VERIFY_${var}}\" is FALSE")
769     elseif(NOT ${var} AND evaluated)
770       list(APPEND broken_options ${var})
771       message(WARNING
772         "Option ${var} is disabled or unset but corresponding dependency "
773         "have been explicitly turned on: \"${OPENCV_VERIFY_${var}}\" is TRUE")
774     endif()
775   endforeach()
776   if(broken_options)
777     string(REPLACE ";" "\n" broken_options "${broken_options}")
778     message(FATAL_ERROR
779       "Some dependencies have not been found or have been forced, "
780       "unset ENABLE_CONFIG_VERIFICATION option to ignore these failures "
781       "or change following options:\n${broken_options}")
782   endif()
783 endfunction()
784
785 # Usage: ocv_append_build_options(HIGHGUI FFMPEG)
786 macro(ocv_append_build_options var_prefix pkg_prefix)
787   foreach(suffix INCLUDE_DIRS LIBRARIES LIBRARY_DIRS LINK_LIBRARIES)
788     if(${pkg_prefix}_${suffix})
789       list(APPEND ${var_prefix}_${suffix} ${${pkg_prefix}_${suffix}})
790       list(REMOVE_DUPLICATES ${var_prefix}_${suffix})
791     endif()
792   endforeach()
793 endmacro()
794
795 function(ocv_append_source_files_cxx_compiler_options files_var)
796   set(__flags "${ARGN}")
797   ocv_check_flag_support(CXX "${__flags}" __HAVE_COMPILER_OPTIONS_VAR "")
798   if(${__HAVE_COMPILER_OPTIONS_VAR})
799     foreach(source ${${files_var}})
800       if("${source}" MATCHES "\\.(cpp|cc|cxx)$")
801         get_source_file_property(flags "${source}" COMPILE_FLAGS)
802         if(flags)
803           set(flags "${flags} ${__flags}")
804         else()
805           set(flags "${__flags}")
806         endif()
807         set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
808       endif()
809     endforeach()
810   endif()
811 endfunction()
812
813 # Usage is similar to CMake 'pkg_check_modules' command
814 # It additionally controls HAVE_${define} and ${define}_${modname}_FOUND variables
815 macro(ocv_check_modules define)
816   unset(HAVE_${define})
817   foreach(m ${ARGN})
818     if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
819       set(__modname "${CMAKE_MATCH_1}")
820     else()
821       set(__modname "${m}")
822     endif()
823     unset(${define}_${__modname}_FOUND)
824   endforeach()
825   if(PKG_CONFIG_FOUND OR PkgConfig_FOUND)
826     pkg_check_modules(${define} ${ARGN})
827   endif()
828   if(${define}_FOUND)
829     set(HAVE_${define} 1)
830   endif()
831   foreach(m ${ARGN})
832     if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
833       set(__modname "${CMAKE_MATCH_1}")
834     else()
835       set(__modname "${m}")
836     endif()
837     if(NOT DEFINED ${define}_${__modname}_FOUND AND ${define}_FOUND)
838       set(${define}_${__modname}_FOUND 1)
839     endif()
840   endforeach()
841   if(${define}_FOUND AND ${define}_LIBRARIES)
842     if(${define}_LINK_LIBRARIES_XXXXX)  # CMake 3.12+: https://gitlab.kitware.com/cmake/cmake/merge_requests/2068
843       set(${define}_LIBRARIES "${${define}_LINK_LIBRARIES}" CACHE INTERNAL "")
844     else()
845       unset(_libs)          # absolute paths
846       unset(_libs_paths)  # -L args
847       foreach(flag ${${define}_LDFLAGS})
848         if(flag MATCHES "^-L(.*)")
849           list(APPEND _libs_paths ${CMAKE_MATCH_1})
850         elseif(IS_ABSOLUTE "${flag}")
851           list(APPEND _libs "${flag}")
852         elseif(flag MATCHES "^-l(.*)")
853           set(_lib "${CMAKE_MATCH_1}")
854           if(_libs_paths)
855             find_library(pkgcfg_lib_${define}_${_lib} NAMES ${_lib}
856                          HINTS ${_libs_paths} NO_DEFAULT_PATH)
857           endif()
858           find_library(pkgcfg_lib_${define}_${_lib} NAMES ${_lib})
859           mark_as_advanced(pkgcfg_lib_${define}_${_lib})
860           if(pkgcfg_lib_${define}_${_lib})
861             list(APPEND _libs "${pkgcfg_lib_${define}_${_lib}}")
862           else()
863             message(WARNING "ocv_check_modules(${define}): can't find library '${_lib}'. Specify 'pkgcfg_lib_${define}_${_lib}' manually")
864             list(APPEND _libs "${_lib}")
865           endif()
866         else()
867           # -pthread
868           #message(WARNING "ocv_check_modules(${define}): unknown LDFLAG '${flag}'")
869         endif()
870       endforeach()
871       set(${define}_LINK_LIBRARIES "${_libs}")
872       set(${define}_LIBRARIES "${_libs}" CACHE INTERNAL "")
873       unset(_lib)
874       unset(_libs)
875       unset(_libs_paths)
876     endif()
877   endif()
878 endmacro()
879
880
881
882 if(NOT DEFINED CMAKE_ARGC) # Guard CMake standalone invocations
883
884 # Use this option carefully, CMake's install() will install symlinks instead of real files
885 # It is fine for development, but should not be used by real installations
886 set(__symlink_default OFF)  # preprocessing is required for old CMake like 2.8.12
887 if(DEFINED ENV{BUILD_USE_SYMLINKS})
888   set(__symlink_default $ENV{BUILD_USE_SYMLINKS})
889 endif()
890 OCV_OPTION(BUILD_USE_SYMLINKS "Use symlinks instead of files copying during build (and !!INSTALL!!)" (${__symlink_default}) IF (UNIX OR DEFINED __symlink_default))
891
892 if(CMAKE_VERSION VERSION_LESS "3.2")
893   macro(ocv_cmake_byproducts var_name)
894     set(${var_name}) # nothing
895   endmacro()
896 else()
897   macro(ocv_cmake_byproducts var_name)
898     set(${var_name} BYPRODUCTS ${ARGN})
899   endmacro()
900 endif()
901
902 set(OPENCV_DEPHELPER "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/dephelper" CACHE INTERNAL "")
903 file(MAKE_DIRECTORY ${OPENCV_DEPHELPER})
904
905 if(BUILD_USE_SYMLINKS)
906   set(__file0 "${CMAKE_CURRENT_LIST_FILE}")
907   set(__file1 "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/symlink_test")
908   if(NOT IS_SYMLINK "${__file1}")
909     execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${__file0}" "${__file1}"
910         RESULT_VARIABLE SYMLINK_RESULT)
911     if(NOT SYMLINK_RESULT EQUAL 0)
912       file(REMOVE "${__file1}")
913     endif()
914     if(NOT IS_SYMLINK "${__file1}")
915       set(BUILD_USE_SYMLINKS 0 CACHE INTERNAL "")
916     endif()
917   endif()
918   if(NOT BUILD_USE_SYMLINKS)
919     message(STATUS "Build symlinks are not available (disabled)")
920   endif()
921 endif()
922
923 set(OPENCV_BUILD_INFO_STR "" CACHE INTERNAL "")
924 function(ocv_output_status msg)
925   message(STATUS "${msg}")
926   string(REPLACE "\\" "\\\\" msg "${msg}")
927   string(REPLACE "\"" "\\\"" msg "${msg}")
928   string(REGEX REPLACE "^\n+|\n+$" "" msg "${msg}")
929   if(msg MATCHES "\n")
930     message(WARNING "String to be inserted to version_string.inc has an unexpected line break: '${msg}'")
931     string(REPLACE "\n" "\\n" msg "${msg}")
932   endif()
933   set(OPENCV_BUILD_INFO_STR "${OPENCV_BUILD_INFO_STR}\"${msg}\\n\"\n" CACHE INTERNAL "")
934 endfunction()
935
936 macro(ocv_finalize_status)
937   set(OPENCV_BUILD_INFO_FILE "${CMAKE_BINARY_DIR}/version_string.tmp")
938   if(EXISTS "${OPENCV_BUILD_INFO_FILE}")
939     file(READ "${OPENCV_BUILD_INFO_FILE}" __content)
940   else()
941     set(__content "")
942   endif()
943   if("${__content}" STREQUAL "${OPENCV_BUILD_INFO_STR}")
944     #message(STATUS "${OPENCV_BUILD_INFO_FILE} contains the same content")
945   else()
946     file(WRITE "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_BUILD_INFO_STR}")
947   endif()
948   unset(__content)
949   unset(OPENCV_BUILD_INFO_STR CACHE)
950
951   if(NOT OPENCV_SKIP_STATUS_FINALIZATION)
952     if(DEFINED OPENCV_MODULE_opencv_core_BINARY_DIR)
953       execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
954     endif()
955   endif()
956
957   if(UNIX)
958     install(FILES "${OpenCV_SOURCE_DIR}/platforms/scripts/valgrind.supp"
959                   "${OpenCV_SOURCE_DIR}/platforms/scripts/valgrind_3rdparty.supp"
960             DESTINATION "${OPENCV_OTHER_INSTALL_PATH}" COMPONENT "dev")
961   endif()
962 endmacro()
963
964
965 # Status report function.
966 # Automatically align right column and selects text based on condition.
967 # Usage:
968 #   status(<text>)
969 #   status(<heading> <value1> [<value2> ...])
970 #   status(<heading> <condition> THEN <text for TRUE> ELSE <text for FALSE> )
971 function(status text)
972   set(status_cond)
973   set(status_then)
974   set(status_else)
975
976   set(status_current_name "cond")
977   foreach(arg ${ARGN})
978     if(arg STREQUAL "THEN")
979       set(status_current_name "then")
980     elseif(arg STREQUAL "ELSE")
981       set(status_current_name "else")
982     else()
983       list(APPEND status_${status_current_name} ${arg})
984     endif()
985   endforeach()
986
987   if(DEFINED status_cond)
988     set(status_placeholder_length 32)
989     string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder)
990     string(LENGTH "${text}" status_text_length)
991     if(status_text_length LESS status_placeholder_length)
992       string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text)
993     elseif(DEFINED status_then OR DEFINED status_else)
994       ocv_output_status("${text}")
995       set(status_text "${status_placeholder}")
996     else()
997       set(status_text "${text}")
998     endif()
999
1000     if(DEFINED status_then OR DEFINED status_else)
1001       if(${status_cond})
1002         string(REPLACE ";" " " status_then "${status_then}")
1003         string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}")
1004         ocv_output_status("${status_text} ${status_then}")
1005       else()
1006         string(REPLACE ";" " " status_else "${status_else}")
1007         string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}")
1008         ocv_output_status("${status_text} ${status_else}")
1009       endif()
1010     else()
1011       string(REPLACE ";" " " status_cond "${status_cond}")
1012       string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}")
1013       ocv_output_status("${status_text} ${status_cond}")
1014     endif()
1015   else()
1016     ocv_output_status("${text}")
1017   endif()
1018 endfunction()
1019
1020 endif() # NOT DEFINED CMAKE_ARGC
1021
1022 #
1023 # Generate a list of enabled features basing on conditions:
1024 #   IF <cond> THEN <title>: check condition and append title to the result if it is true
1025 #   ELSE <title>: return provided value instead of empty result
1026 #   EXCLUSIVE: break after first successful condition
1027 #
1028 # Usage:
1029 #   ocv_build_features_string(out [EXCLUSIVE] [IF feature THEN title] ... [ELSE title])
1030 #
1031 function(ocv_build_features_string out)
1032   set(result)
1033   list(REMOVE_AT ARGV 0)
1034   foreach(arg ${ARGV})
1035     if(arg STREQUAL "EXCLUSIVE")
1036       set(exclusive TRUE)
1037     elseif(arg STREQUAL "IF")
1038       set(then FALSE)
1039       set(cond)
1040     elseif(arg STREQUAL "THEN")
1041       set(then TRUE)
1042       set(title)
1043     elseif(arg STREQUAL "ELSE")
1044       set(then FALSE)
1045       set(else TRUE)
1046     else()
1047       if(then)
1048         if(${cond})
1049           list(APPEND result "${arg}")
1050           if(exclusive)
1051             break()
1052           endif()
1053         endif()
1054       elseif(else)
1055         if(NOT result)
1056           set(result "${arg}")
1057         endif()
1058       else()
1059         list(APPEND cond ${arg})
1060       endif()
1061     endif()
1062   endforeach()
1063   set(${out} ${result} PARENT_SCOPE)
1064 endfunction()
1065
1066
1067 # remove all matching elements from the list
1068 macro(ocv_list_filterout lst regex)
1069   foreach(item ${${lst}})
1070     if(item MATCHES "${regex}")
1071       list(REMOVE_ITEM ${lst} "${item}")
1072     endif()
1073   endforeach()
1074 endmacro()
1075
1076 # filter matching elements from the list
1077 macro(ocv_list_filter lst regex)
1078   set(dst ${ARGN})
1079   if(NOT dst)
1080     set(dst ${lst})
1081   endif()
1082   set(__result ${${lst}})
1083   foreach(item ${__result})
1084     if(NOT item MATCHES "${regex}")
1085       list(REMOVE_ITEM __result "${item}")
1086     endif()
1087   endforeach()
1088   set(${dst} ${__result})
1089 endmacro()
1090
1091
1092 # stable & safe duplicates removal macro
1093 macro(ocv_list_unique __lst)
1094   if(${__lst})
1095     list(REMOVE_DUPLICATES ${__lst})
1096   endif()
1097 endmacro()
1098
1099
1100 # safe list reversal macro
1101 macro(ocv_list_reverse __lst)
1102   if(${__lst})
1103     list(REVERSE ${__lst})
1104   endif()
1105 endmacro()
1106
1107
1108 # safe list sorting macro
1109 macro(ocv_list_sort __lst)
1110   if(${__lst})
1111     list(SORT ${__lst})
1112   endif()
1113 endmacro()
1114
1115
1116 # add prefix to each item in the list
1117 macro(ocv_list_add_prefix LST PREFIX)
1118   set(__tmp "")
1119   foreach(item ${${LST}})
1120     list(APPEND __tmp "${PREFIX}${item}")
1121   endforeach()
1122   set(${LST} ${__tmp})
1123   unset(__tmp)
1124 endmacro()
1125
1126
1127 # add suffix to each item in the list
1128 macro(ocv_list_add_suffix LST SUFFIX)
1129   set(__tmp "")
1130   foreach(item ${${LST}})
1131     list(APPEND __tmp "${item}${SUFFIX}")
1132   endforeach()
1133   set(${LST} ${__tmp})
1134   unset(__tmp)
1135 endmacro()
1136
1137
1138 # gets and removes the first element from the list
1139 macro(ocv_list_pop_front LST VAR)
1140   if(${LST})
1141     list(GET ${LST} 0 ${VAR})
1142     list(REMOVE_AT ${LST} 0)
1143   else()
1144     set(${VAR} "")
1145   endif()
1146 endmacro()
1147
1148 # Get list of duplicates in the list of input items.
1149 # ocv_get_duplicates(<output list> <element> [<element> ...])
1150 function(ocv_get_duplicates res)
1151   if(ARGC LESS 2)
1152     message(FATAL_ERROR "Invalid call to ocv_get_duplicates")
1153   endif()
1154   set(lst ${ARGN})
1155   list(SORT lst)
1156   set(prev_item)
1157   foreach(item ${lst})
1158     if(item STREQUAL prev_item)
1159       list(APPEND dups ${item})
1160     endif()
1161     set(prev_item ${item})
1162   endforeach()
1163   set(${res} ${dups} PARENT_SCOPE)
1164 endfunction()
1165
1166 # simple regex escaping routine (does not cover all cases!!!)
1167 macro(ocv_regex_escape var regex)
1168   string(REGEX REPLACE "([+.*^$])" "\\\\1" ${var} "${regex}")
1169 endmacro()
1170
1171
1172 # convert list of paths to full paths
1173 macro(ocv_convert_to_full_paths VAR)
1174   if(${VAR})
1175     set(__tmp "")
1176     foreach(path ${${VAR}})
1177       get_filename_component(${VAR} "${path}" ABSOLUTE)
1178       list(APPEND __tmp "${${VAR}}")
1179     endforeach()
1180     set(${VAR} ${__tmp})
1181     unset(__tmp)
1182   endif()
1183 endmacro()
1184
1185
1186 # convert list of paths to libraries names without lib prefix
1187 function(ocv_convert_to_lib_name var)
1188   set(tmp "")
1189   foreach(path ${ARGN})
1190     get_filename_component(tmp_name "${path}" NAME)
1191     ocv_get_libname(tmp_name "${tmp_name}")
1192     list(APPEND tmp "${tmp_name}")
1193   endforeach()
1194   set(${var} ${tmp} PARENT_SCOPE)
1195 endfunction()
1196
1197
1198 # add install command
1199 function(ocv_install_target)
1200   if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
1201     install(TARGETS ${ARGN} FRAMEWORK DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH})
1202   else()
1203     install(TARGETS ${ARGN})
1204   endif()
1205
1206   set(isPackage 0)
1207   unset(__package)
1208   unset(__target)
1209   foreach(e ${ARGN})
1210     if(NOT DEFINED __target)
1211       set(__target "${e}")
1212     endif()
1213     if(isPackage EQUAL 1)
1214       set(__package "${e}")
1215       break()
1216     endif()
1217     if(e STREQUAL "EXPORT")
1218       set(isPackage 1)
1219     endif()
1220   endforeach()
1221
1222   if(DEFINED __package)
1223     list(APPEND ${__package}_TARGETS ${__target})
1224     set(${__package}_TARGETS "${${__package}_TARGETS}" CACHE INTERNAL "List of ${__package} targets")
1225   endif()
1226
1227   if(MSVC)
1228     set(__target "${ARGV0}")
1229
1230     # don't move this into global scope of this file: compiler settings (like MSVC variable) are not available during processing
1231     if(BUILD_SHARED_LIBS)  # no defaults for static libs (modern CMake is required)
1232       if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
1233         option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default" ON)
1234         option(INSTALL_PDB "Add install PDB rules" ON)
1235       elseif(NOT CMAKE_VERSION VERSION_LESS 3.1.0)
1236         option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default (not supported)" OFF)
1237         option(INSTALL_PDB "Add install PDB rules" OFF)
1238       endif()
1239     endif()
1240
1241     if(INSTALL_PDB AND NOT INSTALL_IGNORE_PDB
1242         AND NOT OPENCV_${__target}_PDB_SKIP
1243     )
1244       set(__location_key "ARCHIVE")  # static libs
1245       get_target_property(__target_type ${__target} TYPE)
1246       if("${__target_type}" STREQUAL "SHARED_LIBRARY")
1247         set(__location_key "RUNTIME")  # shared libs (.DLL)
1248       endif()
1249
1250       set(processDst 0)
1251       set(isDst 0)
1252       unset(__dst)
1253       foreach(e ${ARGN})
1254         if(isDst EQUAL 1)
1255           set(__dst "${e}")
1256           break()
1257         endif()
1258         if(processDst EQUAL 1 AND e STREQUAL "DESTINATION")
1259           set(isDst 1)
1260         endif()
1261         if(e STREQUAL "${__location_key}")
1262           set(processDst 1)
1263         else()
1264           set(processDst 0)
1265         endif()
1266       endforeach()
1267
1268 #      message(STATUS "Process ${__target} dst=${__dst}...")
1269       if(DEFINED __dst)
1270         if(NOT CMAKE_VERSION VERSION_LESS 3.1.0)
1271           set(__pdb_install_component "pdb")
1272           if(DEFINED INSTALL_PDB_COMPONENT AND INSTALL_PDB_COMPONENT)
1273             set(__pdb_install_component "${INSTALL_PDB_COMPONENT}")
1274           endif()
1275           set(__pdb_exclude_from_all "")
1276           if(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL)
1277             if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
1278               set(__pdb_exclude_from_all EXCLUDE_FROM_ALL)
1279             else()
1280               message(WARNING "INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL requires CMake 3.6+")
1281             endif()
1282           endif()
1283
1284 #          message(STATUS "Adding PDB file installation rule: target=${__target} dst=${__dst} component=${__pdb_install_component}")
1285           if("${__target_type}" STREQUAL "SHARED_LIBRARY" OR "${__target_type}" STREQUAL "MODULE_LIBRARY")
1286             install(FILES "$<TARGET_PDB_FILE:${__target}>" DESTINATION "${__dst}"
1287                 COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
1288           else()
1289             # 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
1290             # However we still want .pdb files like: 'lib/Debug/opencv_core341d.pdb' or '3rdparty/lib/zlibd.pdb'
1291             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"
1292                 DESTINATION "${__dst}" CONFIGURATIONS Debug
1293                 COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
1294             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"
1295                 DESTINATION "${__dst}" CONFIGURATIONS Release
1296                 COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
1297           endif()
1298         else()
1299           message(WARNING "PDB files installation is not supported (need CMake >= 3.1.0)")
1300         endif()
1301       endif()
1302     endif()
1303   endif()
1304 endfunction()
1305
1306 # ocv_install_3rdparty_licenses(<library-name> <filename1> [<filename2> ..])
1307 function(ocv_install_3rdparty_licenses library)
1308   foreach(filename ${ARGN})
1309     set(filepath "${filename}")
1310     if(NOT IS_ABSOLUTE "${filepath}")
1311       set(filepath "${CMAKE_CURRENT_LIST_DIR}/${filepath}")
1312     endif()
1313     get_filename_component(name "${filename}" NAME)
1314     install(
1315       FILES "${filepath}"
1316       DESTINATION "${OPENCV_LICENSES_INSTALL_PATH}"
1317       COMPONENT licenses
1318       RENAME "${library}-${name}"
1319     )
1320   endforeach()
1321 endfunction()
1322
1323 # read set of version defines from the header file
1324 macro(ocv_parse_header FILENAME FILE_VAR)
1325   set(vars_regex "")
1326   set(__parnet_scope OFF)
1327   set(__add_cache OFF)
1328   foreach(name ${ARGN})
1329     if(${name} STREQUAL "PARENT_SCOPE")
1330       set(__parnet_scope ON)
1331     elseif(${name} STREQUAL "CACHE")
1332       set(__add_cache ON)
1333     elseif(vars_regex)
1334       set(vars_regex "${vars_regex}|${name}")
1335     else()
1336       set(vars_regex "${name}")
1337     endif()
1338   endforeach()
1339   if(EXISTS "${FILENAME}")
1340     file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" )
1341   else()
1342     unset(${FILE_VAR})
1343   endif()
1344   foreach(name ${ARGN})
1345     if(NOT ${name} STREQUAL "PARENT_SCOPE" AND NOT ${name} STREQUAL "CACHE")
1346       if(${FILE_VAR})
1347         if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*")
1348           string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}")
1349         else()
1350           set(${name} "")
1351         endif()
1352         if(__add_cache)
1353           set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE)
1354         elseif(__parnet_scope)
1355           set(${name} "${${name}}" PARENT_SCOPE)
1356         endif()
1357       else()
1358         unset(${name} CACHE)
1359       endif()
1360     endif()
1361   endforeach()
1362 endmacro()
1363
1364 # read single version define from the header file
1365 macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME)
1366   ocv_clear_vars(${LIBNAME}_VERSION_MAJOR
1367                  ${LIBNAME}_VERSION_MAJOR
1368                  ${LIBNAME}_VERSION_MINOR
1369                  ${LIBNAME}_VERSION_PATCH
1370                  ${LIBNAME}_VERSION_TWEAK
1371                  ${LIBNAME}_VERSION_STRING)
1372   set(${LIBNAME}_H "")
1373   if(EXISTS "${HDR_PATH}")
1374     file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1)
1375   endif()
1376
1377   if(${LIBNAME}_H)
1378     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}")
1379     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR  "${${LIBNAME}_H}")
1380     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}")
1381     set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN})
1382     set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN})
1383     set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN})
1384     set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}")
1385
1386     # append a TWEAK version if it exists:
1387     set(${LIBNAME}_VERSION_TWEAK "")
1388     if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
1389       set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN})
1390     endif()
1391     if(${LIBNAME}_VERSION_TWEAK)
1392       set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN})
1393     else()
1394       set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN})
1395     endif()
1396   endif()
1397 endmacro()
1398
1399 ################################################################################################
1400 # short command to setup source group
1401 function(ocv_source_group group)
1402   if(BUILD_opencv_world AND OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD)
1403     set(group "${the_module}\\${group}")
1404   endif()
1405   cmake_parse_arguments(SG "" "DIRBASE" "GLOB;GLOB_RECURSE;FILES" ${ARGN})
1406   set(files "")
1407   if(SG_FILES)
1408     list(APPEND files ${SG_FILES})
1409   endif()
1410   if(SG_GLOB)
1411     file(GLOB srcs ${SG_GLOB})
1412     list(APPEND files ${srcs})
1413   endif()
1414   if(SG_GLOB_RECURSE)
1415     file(GLOB_RECURSE srcs ${SG_GLOB_RECURSE})
1416     list(APPEND files ${srcs})
1417   endif()
1418   if(SG_DIRBASE)
1419     foreach(f ${files})
1420       file(RELATIVE_PATH fpart "${SG_DIRBASE}" "${f}")
1421       if(fpart MATCHES "^\\.\\.")
1422         message(AUTHOR_WARNING "Can't detect subpath for source_group command: Group=${group} FILE=${f} DIRBASE=${SG_DIRBASE}")
1423         set(fpart "")
1424       else()
1425         get_filename_component(fpart "${fpart}" PATH)
1426         if(fpart)
1427           set(fpart "/${fpart}") # add '/'
1428           string(REPLACE "/" "\\" fpart "${fpart}")
1429         endif()
1430       endif()
1431       source_group("${group}${fpart}" FILES ${f})
1432     endforeach()
1433   else()
1434     source_group(${group} FILES ${files})
1435   endif()
1436 endfunction()
1437
1438 macro(__ocv_push_target_link_libraries)
1439   if(NOT TARGET ${target})
1440     if(NOT DEFINED OPENCV_MODULE_${target}_LOCATION)
1441       message(FATAL_ERROR "ocv_target_link_libraries: invalid target: '${target}'")
1442     endif()
1443     set(OPENCV_MODULE_${target}_LINK_DEPS ${OPENCV_MODULE_${target}_LINK_DEPS} ${ARGN} CACHE INTERNAL "" FORCE)
1444   else()
1445     target_link_libraries(${target} ${ARGN})
1446   endif()
1447 endmacro()
1448
1449 function(ocv_target_link_libraries target)
1450   set(LINK_DEPS ${ARGN})
1451   _ocv_fix_target(target)
1452   set(LINK_MODE "PRIVATE")
1453   set(LINK_PENDING "")
1454   foreach(dep ${LINK_DEPS})
1455     if(" ${dep}" STREQUAL " ${target}")
1456       # prevent "link to itself" warning (world problem)
1457     elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL " LINK_PUBLIC"  # deprecated
1458         OR " ${dep}" STREQUAL " PRIVATE" OR " ${dep}" STREQUAL " PUBLIC" OR " ${dep}" STREQUAL " INTERFACE"
1459     )
1460       if(NOT LINK_PENDING STREQUAL "")
1461         __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
1462         set(LINK_PENDING "")
1463         set(LINK_MODE "${dep}")
1464       endif()
1465     else()
1466       if(BUILD_opencv_world)
1467         if(OPENCV_MODULE_${dep}_IS_PART_OF_WORLD)
1468           set(dep opencv_world)
1469         endif()
1470       endif()
1471       list(APPEND LINK_PENDING "${dep}")
1472     endif()
1473   endforeach()
1474   if(NOT LINK_PENDING STREQUAL "")
1475     __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
1476   endif()
1477 endfunction()
1478
1479 function(ocv_target_compile_definitions target)
1480   _ocv_fix_target(target)
1481   if(NOT TARGET ${target})
1482     if(NOT DEFINED OPENCV_MODULE_${target}_LOCATION)
1483       message(FATAL_ERROR "ocv_target_compile_definitions: invalid target: '${target}'")
1484     endif()
1485     set(OPENCV_MODULE_${target}_COMPILE_DEFINITIONS ${OPENCV_MODULE_${target}_COMPILE_DEFINITIONS} ${ARGN} CACHE INTERNAL "" FORCE)
1486   else()
1487     target_compile_definitions(${target} ${ARGN})
1488   endif()
1489 endfunction()
1490
1491
1492 function(_ocv_append_target_includes target)
1493   if(DEFINED OCV_TARGET_INCLUDE_DIRS_${target})
1494     target_include_directories(${target} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
1495     if(OPENCV_DEPENDANT_TARGETS_${target})
1496       foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
1497         target_include_directories(${t} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
1498       endforeach()
1499     endif()
1500     unset(OCV_TARGET_INCLUDE_DIRS_${target} CACHE)
1501   endif()
1502
1503   if(DEFINED OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target})
1504     target_include_directories(${target} SYSTEM PRIVATE ${OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target}})
1505     if(OPENCV_DEPENDANT_TARGETS_${target})
1506       foreach(t ${OPENCV_DEPENDANT_TARGETS_${target}})
1507         target_include_directories(${t} SYSTEM PRIVATE ${OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target}})
1508       endforeach()
1509     endif()
1510     unset(OCV_TARGET_INCLUDE_SYSTEM_DIRS_${target} CACHE)
1511   endif()
1512 endfunction()
1513
1514 function(ocv_add_executable target)
1515   add_executable(${target} ${ARGN})
1516   _ocv_append_target_includes(${target})
1517 endfunction()
1518
1519 function(ocv_add_library target)
1520   if(HAVE_CUDA AND ARGN MATCHES "\\.cu")
1521     ocv_include_directories(${CUDA_INCLUDE_DIRS})
1522     ocv_cuda_compile(cuda_objs ${ARGN})
1523     set(OPENCV_MODULE_${target}_CUDA_OBJECTS ${cuda_objs} CACHE INTERNAL "Compiled CUDA object files")
1524   endif()
1525
1526   add_library(${target} ${ARGN} ${cuda_objs})
1527
1528   if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
1529     message(STATUS "Setting Apple target properties for ${target}")
1530
1531     set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1)
1532
1533     if(IOS AND NOT MAC_CATALYST)
1534       set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/ios/Info.plist")
1535     else()
1536       set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/osx/Info.plist")
1537     endif()
1538
1539     set_target_properties(${target} PROPERTIES
1540       FRAMEWORK TRUE
1541       MACOSX_FRAMEWORK_IDENTIFIER org.opencv
1542       MACOSX_FRAMEWORK_INFO_PLIST ${OPENCV_APPLE_INFO_PLIST}
1543       # "current version" in semantic format in Mach-O binary file
1544       VERSION ${OPENCV_LIBVERSION}
1545       # "compatibility version" in semantic format in Mach-O binary file
1546       SOVERSION ${OPENCV_LIBVERSION}
1547       INSTALL_RPATH ""
1548       INSTALL_NAME_DIR "@rpath"
1549       BUILD_WITH_INSTALL_RPATH 1
1550       LIBRARY_OUTPUT_NAME "opencv2"
1551       XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
1552       #PUBLIC_HEADER "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h"
1553       #XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
1554     )
1555   endif()
1556
1557   _ocv_append_target_includes(${target})
1558 endfunction()
1559
1560
1561 macro(ocv_get_libname var_name)
1562   get_filename_component(__libname "${ARGN}" NAME)
1563   # libopencv_core.so.3.3 -> opencv_core
1564   string(REGEX REPLACE "^lib(.+)\\.(a|so|dll)(\\.[.0-9]+)?$" "\\1" __libname "${__libname}")
1565   # MacOSX: libopencv_core.3.3.1.dylib -> opencv_core
1566   string(REGEX REPLACE "^lib(.+[^.0-9])\\.([.0-9]+\\.)?dylib$" "\\1" __libname "${__libname}")
1567   set(${var_name} "${__libname}")
1568 endmacro()
1569
1570 # build the list of opencv libs and dependencies for all modules
1571 #  _modules - variable to hold list of all modules
1572 #  _extra - variable to hold list of extra dependencies
1573 #  _3rdparty - variable to hold list of prebuilt 3rdparty libraries
1574 macro(ocv_get_all_libs _modules _extra _3rdparty)
1575   set(${_modules} "")
1576   set(${_extra} "")
1577   set(${_3rdparty} "")
1578   foreach(m ${OPENCV_MODULES_PUBLIC})
1579     if(TARGET ${m})
1580       get_target_property(deps ${m} INTERFACE_LINK_LIBRARIES)
1581       if(NOT deps)
1582         set(deps "")
1583       endif()
1584     else()
1585       set(deps "")
1586     endif()
1587     set(_rev_deps "${deps};${m}")
1588     ocv_list_reverse(_rev_deps)
1589     foreach (dep ${_rev_deps})
1590       if(DEFINED OPENCV_MODULE_${dep}_LOCATION)
1591         list(INSERT ${_modules} 0 ${dep})
1592       endif()
1593     endforeach()
1594     foreach (dep ${deps} ${OPENCV_LINKER_LIBS})
1595       if (NOT DEFINED OPENCV_MODULE_${dep}_LOCATION)
1596         if(dep MATCHES "^\\$<LINK_ONLY:([^>]+)>$")
1597           set(dep "${CMAKE_MATCH_1}")
1598         endif()
1599         if(dep MATCHES "^\\$<")
1600           message(WARNING "Unexpected CMake generator expression: ${dep}")
1601         endif()
1602         if (TARGET ${dep})
1603           get_target_property(_type ${dep} TYPE)
1604           if((_type STREQUAL "STATIC_LIBRARY" AND BUILD_SHARED_LIBS)
1605               OR _type STREQUAL "INTERFACE_LIBRARY"
1606               OR DEFINED OPENCV_MODULE_${dep}_LOCATION  # OpenCV modules
1607           )
1608             # nothing
1609           else()
1610             get_target_property(_output ${dep} IMPORTED_LOCATION)
1611             if(NOT _output)
1612               get_target_property(_output ${dep} ARCHIVE_OUTPUT_DIRECTORY)
1613               get_target_property(_output_name ${dep} OUTPUT_NAME)
1614               if(NOT _output_name)
1615                 set(_output_name "${dep}")
1616               endif()
1617             else()
1618               get_filename_component(_output_name "${_output}" NAME)
1619             endif()
1620             string(FIND "${_output}" "${CMAKE_BINARY_DIR}" _POS)
1621             if (_POS EQUAL 0)
1622               ocv_get_libname(_libname "${_output_name}")
1623               list(INSERT ${_3rdparty} 0 ${dep})
1624             else()
1625               if(_output)
1626                 list(INSERT ${_extra} 0 ${_output})
1627               else()
1628                 list(INSERT ${_extra} 0 ${dep})
1629               endif()
1630             endif()
1631           endif()
1632         else()
1633           list(INSERT ${_extra} 0 ${dep})
1634         endif()
1635       endif()
1636     endforeach()
1637   endforeach()
1638
1639   ocv_list_filterout(${_modules} "^[\$]<")
1640   ocv_list_filterout(${_3rdparty} "^[\$]<")
1641   ocv_list_filterout(${_extra} "^[\$]<")
1642
1643   # convert CMake lists to makefile literals
1644   foreach(lst ${_modules} ${_3rdparty} ${_extra})
1645     ocv_list_unique(${lst})
1646     ocv_list_reverse(${lst})
1647   endforeach()
1648 endmacro()
1649
1650
1651 function(ocv_add_test_from_target test_name test_kind the_target)
1652   if(CMAKE_VERSION VERSION_GREATER "2.8" AND NOT CMAKE_CROSSCOMPILING)
1653     if(NOT "${test_kind}" MATCHES "^(Accuracy|Performance|Sanity)$")
1654       message(FATAL_ERROR "Unknown test kind : ${test_kind}")
1655     endif()
1656     if(NOT TARGET "${the_target}")
1657       message(FATAL_ERROR "${the_target} is not a CMake target")
1658     endif()
1659
1660     string(TOLOWER "${test_kind}" test_kind_lower)
1661     set(test_report_dir "${CMAKE_BINARY_DIR}/test-reports/${test_kind_lower}")
1662     file(MAKE_DIRECTORY "${test_report_dir}")
1663
1664     add_test(NAME "${test_name}"
1665       COMMAND "${the_target}"
1666               "--gtest_output=xml:${the_target}.xml"
1667               ${ARGN})
1668
1669     set_tests_properties("${test_name}" PROPERTIES
1670       LABELS "${OPENCV_MODULE_${the_module}_LABEL};${test_kind}"
1671       WORKING_DIRECTORY "${test_report_dir}")
1672
1673     if(OPENCV_TEST_DATA_PATH)
1674       set_tests_properties("${test_name}" PROPERTIES
1675         ENVIRONMENT "OPENCV_TEST_DATA_PATH=${OPENCV_TEST_DATA_PATH}")
1676     endif()
1677   endif()
1678 endfunction()
1679
1680 macro(ocv_add_testdata basedir dest_subdir)
1681   if(BUILD_TESTS)
1682     if(NOT CMAKE_CROSSCOMPILING AND NOT INSTALL_TESTS)
1683       file(COPY ${basedir}/
1684            DESTINATION ${CMAKE_BINARY_DIR}/${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir}
1685            ${ARGN}
1686       )
1687     endif()
1688     if(INSTALL_TESTS)
1689       install(DIRECTORY ${basedir}/
1690               DESTINATION ${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir}
1691               COMPONENT "tests"
1692               ${ARGN}
1693       )
1694     endif()
1695   endif()
1696 endmacro()
1697
1698 macro(ocv_generate_vs_version_file DESTINATION)
1699   cmake_parse_arguments(VS_VER "" "NAME;FILEDESCRIPTION;FILEVERSION;INTERNALNAME;COPYRIGHT;ORIGINALFILENAME;PRODUCTNAME;PRODUCTVERSION;COMMENTS;FILEVERSION_QUAD;PRODUCTVERSION_QUAD" "" ${ARGN})
1700
1701   macro(__vs_ver_update_variable name)
1702     if(VS_VER_NAME AND DEFINED OPENCV_${VS_VER_NAME}_VS_VER_${name})
1703       set(OPENCV_VS_VER_${name} "${OPENCV_${VS_VER_NAME}_VS_VER_${name}}")
1704     elseif(VS_VER_${name})
1705       set(OPENCV_VS_VER_${name} "${VS_VER_${name}}")
1706     endif()
1707   endmacro()
1708
1709   __vs_ver_update_variable(FILEVERSION_QUAD)
1710   __vs_ver_update_variable(PRODUCTVERSION_QUAD)
1711
1712   macro(__vs_ver_update_str_variable name)
1713     if(VS_VER_NAME AND DEFINED OPENCV_${VS_VER_NAME}_VS_VER_${name})
1714       set(OPENCV_VS_VER_${name}_STR "${OPENCV_${VS_VER_NAME}_VS_VER_${name}}")
1715     elseif(VS_VER_${name})
1716       set(OPENCV_VS_VER_${name}_STR "${VS_VER_${name}}")
1717     endif()
1718   endmacro()
1719
1720   __vs_ver_update_str_variable(FILEDESCRIPTION)
1721   __vs_ver_update_str_variable(FILEVERSION)
1722   __vs_ver_update_str_variable(INTERNALNAME)
1723   __vs_ver_update_str_variable(COPYRIGHT)
1724   __vs_ver_update_str_variable(ORIGINALFILENAME)
1725   __vs_ver_update_str_variable(PRODUCTNAME)
1726   __vs_ver_update_str_variable(PRODUCTVERSION)
1727   __vs_ver_update_str_variable(COMMENTS)
1728
1729   if(OPENCV_VS_VER_COPYRIGHT_STR)
1730     set(OPENCV_VS_VER_HAVE_COPYRIGHT_STR 1)
1731   else()
1732     set(OPENCV_VS_VER_HAVE_COPYRIGHT_STR 0)
1733   endif()
1734
1735   if(OPENCV_VS_VER_COMMENTS_STR)
1736     set(OPENCV_VS_VER_HAVE_COMMENTS_STR 1)
1737   else()
1738     set(OPENCV_VS_VER_HAVE_COMMENTS_STR 0)
1739   endif()
1740
1741   configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/vs_version.rc.in" "${DESTINATION}" @ONLY)
1742 endmacro()
1743
1744 macro(ocv_cmake_script_append_var content_var)
1745   foreach(var_name ${ARGN})
1746     set(${content_var} "${${content_var}}
1747 set(${var_name} \"${${var_name}}\")
1748 ")
1749   endforeach()
1750 endmacro()
1751
1752 macro(ocv_copyfiles_append_file list_var src dst)
1753   list(LENGTH ${list_var} __id)
1754   list(APPEND ${list_var} ${__id})
1755   set(${list_var}_SRC_${__id} "${src}")
1756   set(${list_var}_DST_${__id} "${dst}")
1757 endmacro()
1758
1759 macro(ocv_copyfiles_append_dir list_var src dst)
1760   set(__glob ${ARGN})
1761   list(LENGTH ${list_var} __id)
1762   list(APPEND ${list_var} ${__id})
1763   set(${list_var}_SRC_${__id} "${src}")
1764   set(${list_var}_DST_${__id} "${dst}")
1765   set(${list_var}_MODE_${__id} "COPYDIR")
1766   if(__glob)
1767     set(${list_var}_GLOB_${__id} ${__glob})
1768   endif()
1769 endmacro()
1770
1771 macro(ocv_copyfiles_make_config_string content_var list_var)
1772   set(var_name "${list_var}")
1773   set(${content_var} "${${content_var}}
1774 set(${var_name} \"${${var_name}}\")
1775 ")
1776   foreach(__id ${${list_var}})
1777     set(${content_var} "${${content_var}}
1778 set(${list_var}_SRC_${__id} \"${${list_var}_SRC_${__id}}\")
1779 set(${list_var}_DST_${__id} \"${${list_var}_DST_${__id}}\")
1780 ")
1781     if(DEFINED ${list_var}_MODE_${__id})
1782       set(${content_var} "${${content_var}}set(${list_var}_MODE_${__id} \"${${list_var}_MODE_${__id}}\")\n")
1783     endif()
1784     if(DEFINED ${list_var}_GLOB_${__id})
1785       set(${content_var} "${${content_var}}set(${list_var}_GLOB_${__id} \"${${list_var}_GLOB_${__id}}\")\n")
1786     endif()
1787   endforeach()
1788 endmacro()
1789
1790 macro(ocv_copyfiles_make_config_file filename_var list_var)
1791   ocv_copyfiles_make_config_string(${list_var}_CONFIG ${list_var})
1792   set(${filename_var} "${CMAKE_CURRENT_BINARY_DIR}/copyfiles-${list_var}.cmake")
1793   file(WRITE "${${filename_var}}" "${${list_var}_CONFIG}")
1794 endmacro()
1795
1796 macro(ocv_copyfiles_add_forced_target target list_var comment_str)
1797   ocv_copyfiles_make_config_file(CONFIG_FILE ${list_var})
1798   ocv_cmake_byproducts(__byproducts BYPRODUCTS "${OPENCV_DEPHELPER}/${target}")
1799   add_custom_target(${target}
1800       ${__byproducts}  # required for add_custom_target() by ninja
1801       COMMAND ${CMAKE_COMMAND}
1802         "-DCONFIG_FILE:PATH=${CONFIG_FILE}"
1803         "-DCOPYLIST_VAR:STRING=${list_var}"
1804         "-DDEPHELPER=${OPENCV_DEPHELPER}/${target}"
1805         -P "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake"
1806       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
1807       COMMENT "${comment_str}"
1808       DEPENDS "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake"
1809               # ninja warn about file(WRITE): "${SRC_COPY_CONFIG_FILE}"
1810   )
1811 endmacro()
1812
1813 macro(ocv_copyfiles_add_target target list_var comment_str)
1814   set(deps ${ARGN})
1815   ocv_copyfiles_make_config_file(CONFIG_FILE ${list_var})
1816   add_custom_command(OUTPUT "${OPENCV_DEPHELPER}/${target}"
1817       COMMAND ${CMAKE_COMMAND}
1818         "-DCONFIG_FILE:PATH=${CONFIG_FILE}"
1819         "-DCOPYLIST_VAR:STRING=${list_var}"
1820         "-DDEPHELPER=${OPENCV_DEPHELPER}/${target}"
1821         -P "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake"
1822       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
1823       COMMENT "${comment_str}"
1824       DEPENDS "${OpenCV_SOURCE_DIR}/cmake/copy_files.cmake" ${deps}
1825               # ninja warn about file(WRITE): "${SRC_COPY_CONFIG_FILE}"
1826   )
1827   add_custom_target(${target} DEPENDS "${OPENCV_DEPHELPER}/${target}")
1828 endmacro()
1829
1830 macro(ocv_get_smart_file_name output_var fpath)
1831   ocv_is_subdir(__subir "${OpenCV_BINARY_DIR}" "${fpath}")
1832   if(__subir)
1833     file(RELATIVE_PATH ${output_var} "${OpenCV_BINARY_DIR}" "${fpath}")
1834     set(${output_var} "<BUILD>/${${output_var}}")
1835   else()
1836     ocv_is_subdir(__subir "${OpenCV_SOURCE_DIR}" "${fpath}")
1837     if(__subir)
1838       file(RELATIVE_PATH ${output_var} "${OpenCV_SOURCE_DIR}" "${fpath}")
1839     else()
1840       set(${output_var} "${fpath}")
1841     endif()
1842   endif()
1843   unset(__subir)
1844 endmacro()
1845
1846 # Needed by install(DIRECTORY ...)
1847 if(NOT CMAKE_VERSION VERSION_LESS 3.1)
1848   set(compatible_MESSAGE_NEVER MESSAGE_NEVER)
1849 else()
1850   set(compatible_MESSAGE_NEVER "")
1851 endif()
1852
1853
1854 macro(ocv_git_describe var_name path)
1855   if(GIT_FOUND)
1856     execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --exact-match --dirty
1857       WORKING_DIRECTORY "${path}"
1858       OUTPUT_VARIABLE ${var_name}
1859       RESULT_VARIABLE GIT_RESULT
1860       ERROR_QUIET
1861       OUTPUT_STRIP_TRAILING_WHITESPACE
1862     )
1863     if(NOT GIT_RESULT EQUAL 0)
1864       execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --always --dirty --match "[0-9].[0-9].[0-9]*" --exclude "[^-]*-cvsdk"
1865         WORKING_DIRECTORY "${path}"
1866         OUTPUT_VARIABLE ${var_name}
1867         RESULT_VARIABLE GIT_RESULT
1868         ERROR_QUIET
1869         OUTPUT_STRIP_TRAILING_WHITESPACE
1870       )
1871       if(NOT GIT_RESULT EQUAL 0)  # --exclude is not supported by 'git'
1872         # match only tags with complete OpenCV versions (ignores -alpha/-beta/-rc suffixes)
1873         execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --always --dirty --match "[0-9].[0-9]*[0-9]"
1874           WORKING_DIRECTORY "${path}"
1875           OUTPUT_VARIABLE ${var_name}
1876           RESULT_VARIABLE GIT_RESULT
1877           ERROR_QUIET
1878           OUTPUT_STRIP_TRAILING_WHITESPACE
1879         )
1880         if(NOT GIT_RESULT EQUAL 0)
1881           set(${var_name} "unknown")
1882         endif()
1883       endif()
1884     endif()
1885   else()
1886     set(${var_name} "unknown")
1887   endif()
1888 endmacro()
1889
1890
1891 # ocv_update_file(filepath content [VERBOSE])
1892 # - write content to file
1893 # - will not change modification time in case when file already exists and content has not changed
1894 function(ocv_update_file filepath content)
1895   if(EXISTS "${filepath}")
1896     file(READ "${filepath}" actual_content)
1897   else()
1898     set(actual_content "")
1899   endif()
1900   if("${actual_content}" STREQUAL "${content}")
1901     if(";${ARGN};" MATCHES ";VERBOSE;")
1902       message(STATUS "${filepath} contains the same content")
1903     endif()
1904   else()
1905     file(WRITE "${filepath}" "${content}")
1906   endif()
1907 endfunction()
1908
1909 if(NOT BUILD_SHARED_LIBS AND (CMAKE_VERSION VERSION_LESS "3.14.0"))
1910   ocv_update(OPENCV_3RDPARTY_EXCLUDE_FROM_ALL "")  # avoid CMake warnings: https://gitlab.kitware.com/cmake/cmake/-/issues/18938
1911 else()
1912   ocv_update(OPENCV_3RDPARTY_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
1913 endif()