Merge pull request #540 from hgaspar:244
[profile/ivi/opencv.git] / cmake / OpenCVUtils.cmake
1 # Search packages for host system instead of packages for target system
2 # in case of cross compilation thess macro should be defined by toolchain file
3 if(NOT COMMAND find_host_package)
4   macro(find_host_package)
5     find_package(${ARGN})
6   endmacro()
7 endif()
8 if(NOT COMMAND find_host_program)
9   macro(find_host_program)
10     find_program(${ARGN})
11   endmacro()
12 endif()
13
14 # adds include directories in such way that directories from the OpenCV source tree go first
15 function(ocv_include_directories)
16   set(__add_before "")
17   foreach(dir ${ARGN})
18     get_filename_component(__abs_dir "${dir}" ABSOLUTE)
19     if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}" OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}")
20       list(APPEND __add_before "${dir}")
21     else()
22       include_directories(AFTER SYSTEM "${dir}")
23     endif()
24   endforeach()
25   include_directories(BEFORE ${__add_before})
26 endfunction()
27
28 # clears all passed variables
29 macro(ocv_clear_vars)
30   foreach(_var ${ARGN})
31     unset(${_var} CACHE)
32   endforeach()
33 endmacro()
34
35 set(OCV_COMPILER_FAIL_REGEX
36     "command line option .* is valid for .* but not for C\\+\\+" # GNU
37     "command line option .* is valid for .* but not for C" # GNU
38     "unrecognized .*option"                     # GNU
39     "unknown .*option"                          # Clang
40     "ignoring unknown option"                   # MSVC
41     "warning D9002"                             # MSVC, any lang
42     "option .*not supported"                    # Intel
43     "[Uu]nknown option"                         # HP
44     "[Ww]arning: [Oo]ption"                     # SunPro
45     "command option .* is not recognized"       # XL
46     "not supported in this configuration; ignored"       # AIX
47     "File with unknown suffix passed to linker" # PGI
48     "WARNING: unknown flag:"                    # Open64
49   )
50
51 MACRO(ocv_check_compiler_flag LANG FLAG RESULT)
52   if(NOT DEFINED ${RESULT})
53     if("_${LANG}_" MATCHES "_CXX_")
54       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx")
55       if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
56         FILE(WRITE "${_fname}" "int main() { return 0; }\n")
57       else()
58         FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
59       endif()
60     elseif("_${LANG}_" MATCHES "_C_")
61       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
62       if("${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
63         FILE(WRITE "${_fname}" "int main(void) { return 0; }\n")
64       else()
65         FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n")
66       endif()
67     elseif("_${LANG}_" MATCHES "_OBJCXX_")
68       set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm")
69       if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
70         FILE(WRITE "${_fname}" "int main() { return 0; }\n")
71       else()
72         FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
73       endif()
74     else()
75       unset(_fname)
76     endif()
77     if(_fname)
78       MESSAGE(STATUS "Performing Test ${RESULT}")
79       TRY_COMPILE(${RESULT}
80         ${CMAKE_BINARY_DIR}
81         "${_fname}"
82         COMPILE_DEFINITIONS "${FLAG}"
83         OUTPUT_VARIABLE OUTPUT)
84
85       FOREACH(_regex ${OCV_COMPILER_FAIL_REGEX})
86         IF("${OUTPUT}" MATCHES "${_regex}")
87           SET(${RESULT} 0)
88           break()
89         ENDIF()
90       ENDFOREACH()
91
92       IF(${RESULT})
93         SET(${RESULT} 1 CACHE INTERNAL "Test ${RESULT}")
94         MESSAGE(STATUS "Performing Test ${RESULT} - Success")
95       ELSE(${RESULT})
96         MESSAGE(STATUS "Performing Test ${RESULT} - Failed")
97         SET(${RESULT} "" CACHE INTERNAL "Test ${RESULT}")
98       ENDIF(${RESULT})
99     else()
100       SET(${RESULT} 0)
101     endif()
102   endif()
103 ENDMACRO()
104
105 macro(ocv_check_flag_support lang flag varname)
106   if("_${lang}_" MATCHES "_CXX_")
107     set(_lang CXX)
108   elseif("_${lang}_" MATCHES "_C_")
109     set(_lang C)
110   elseif("_${lang}_" MATCHES "_OBJCXX_")
111     set(_lang OBJCXX)
112   else()
113     set(_lang ${lang})
114   endif()
115
116   string(TOUPPER "${flag}" ${varname})
117   string(REGEX REPLACE "^(/|-)" "HAVE_${_lang}_" ${varname} "${${varname}}")
118   string(REGEX REPLACE " -|-|=| |\\." "_" ${varname} "${${varname}}")
119
120   ocv_check_compiler_flag("${_lang}" "${ARGN} ${flag}" ${${varname}})
121 endmacro()
122
123 # turns off warnings
124 macro(ocv_warnings_disable)
125   if(NOT ENABLE_NOISY_WARNINGS)
126     set(_flag_vars "")
127     set(_msvc_warnings "")
128     set(_gxx_warnings "")
129     foreach(arg ${ARGN})
130       if(arg MATCHES "^CMAKE_")
131         list(APPEND _flag_vars ${arg})
132       elseif(arg MATCHES "^/wd")
133         list(APPEND _msvc_warnings ${arg})
134       elseif(arg MATCHES "^-W")
135         list(APPEND _gxx_warnings ${arg})
136       endif()
137     endforeach()
138     if(MSVC AND _msvc_warnings AND _flag_vars)
139       foreach(var ${_flag_vars})
140         foreach(warning ${_msvc_warnings})
141           set(${var} "${${var}} ${warning}")
142         endforeach()
143       endforeach()
144     elseif((CMAKE_COMPILER_IS_GNUCXX OR (UNIX AND CV_ICC)) AND _gxx_warnings AND _flag_vars)
145       foreach(var ${_flag_vars})
146         foreach(warning ${_gxx_warnings})
147           if(NOT warning MATCHES "^-Wno-")
148             string(REPLACE "${warning}" "" ${var} "${${var}}")
149             string(REPLACE "-W" "-Wno-" warning "${warning}")
150           endif()
151           ocv_check_flag_support(${var} "${warning}" _varname)
152           if(${_varname})
153             set(${var} "${${var}} ${warning}")
154           endif()
155         endforeach()
156       endforeach()
157     endif()
158     unset(_flag_vars)
159     unset(_msvc_warnings)
160     unset(_gxx_warnings)
161   endif(NOT ENABLE_NOISY_WARNINGS)
162 endmacro()
163
164 # Provides an option that the user can optionally select.
165 # Can accept condition to control when option is available for user.
166 # Usage:
167 #   option(<option_variable> "help string describing the option" <initial value or boolean expression> [IF <condition>])
168 macro(OCV_OPTION variable description value)
169   set(__value ${value})
170   set(__condition "")
171   set(__varname "__value")
172   foreach(arg ${ARGN})
173     if(arg STREQUAL "IF" OR arg STREQUAL "if")
174       set(__varname "__condition")
175     else()
176       list(APPEND ${__varname} ${arg})
177     endif()
178   endforeach()
179   unset(__varname)
180   if("${__condition}" STREQUAL "")
181     set(__condition 2 GREATER 1)
182   endif()
183
184   if(${__condition})
185     if("${__value}" MATCHES ";")
186       if(${__value})
187         option(${variable} "${description}" ON)
188       else()
189         option(${variable} "${description}" OFF)
190       endif()
191     elseif(DEFINED ${__value})
192       if(${__value})
193         option(${variable} "${description}" ON)
194       else()
195         option(${variable} "${description}" OFF)
196       endif()
197     else()
198       option(${variable} "${description}" ${__value})
199     endif()
200   else()
201     unset(${variable} CACHE)
202   endif()
203   unset(__condition)
204   unset(__value)
205 endmacro()
206
207
208 # Macros that checks if module have been installed.
209 # After it adds module to build and define
210 # constants passed as second arg
211 macro(CHECK_MODULE module_name define)
212   set(${define} 0)
213   if(PKG_CONFIG_FOUND)
214     set(ALIAS               ALIASOF_${module_name})
215     set(ALIAS_FOUND                 ${ALIAS}_FOUND)
216     set(ALIAS_INCLUDE_DIRS   ${ALIAS}_INCLUDE_DIRS)
217     set(ALIAS_LIBRARY_DIRS   ${ALIAS}_LIBRARY_DIRS)
218     set(ALIAS_LIBRARIES         ${ALIAS}_LIBRARIES)
219
220     PKG_CHECK_MODULES(${ALIAS} ${module_name})
221
222     if(${ALIAS_FOUND})
223       set(${define} 1)
224       foreach(P "${ALIAS_INCLUDE_DIRS}")
225         if(${P})
226           list(APPEND HIGHGUI_INCLUDE_DIRS ${${P}})
227         endif()
228       endforeach()
229
230       foreach(P "${ALIAS_LIBRARY_DIRS}")
231         if(${P})
232           list(APPEND HIGHGUI_LIBRARY_DIRS ${${P}})
233         endif()
234       endforeach()
235
236       list(APPEND HIGHGUI_LIBRARIES ${${ALIAS_LIBRARIES}})
237     endif()
238   endif()
239 endmacro()
240
241
242 set(OPENCV_BUILD_INFO_FILE "${OpenCV_BINARY_DIR}/version_string.tmp")
243 file(REMOVE "${OPENCV_BUILD_INFO_FILE}")
244 function(ocv_output_status msg)
245   message(STATUS "${msg}")
246   string(REPLACE "\\" "\\\\" msg "${msg}")
247   string(REPLACE "\"" "\\\"" msg "${msg}")
248   file(APPEND "${OPENCV_BUILD_INFO_FILE}" "\"${msg}\\n\"\n")
249 endfunction()
250
251 macro(ocv_finalize_status)
252   if(NOT OPENCV_SKIP_STATUS_FINALIZATION)
253     if(TARGET opencv_core)
254       execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
255     endif()
256   endif()
257 endmacro()
258
259
260 # Status report function.
261 # Automatically align right column and selects text based on condition.
262 # Usage:
263 #   status(<text>)
264 #   status(<heading> <value1> [<value2> ...])
265 #   status(<heading> <condition> THEN <text for TRUE> ELSE <text for FALSE> )
266 function(status text)
267   set(status_cond)
268   set(status_then)
269   set(status_else)
270
271   set(status_current_name "cond")
272   foreach(arg ${ARGN})
273     if(arg STREQUAL "THEN")
274       set(status_current_name "then")
275     elseif(arg STREQUAL "ELSE")
276       set(status_current_name "else")
277     else()
278       list(APPEND status_${status_current_name} ${arg})
279     endif()
280   endforeach()
281
282   if(DEFINED status_cond)
283     set(status_placeholder_length 32)
284     string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder)
285     string(LENGTH "${text}" status_text_length)
286     if(status_text_length LESS status_placeholder_length)
287       string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text)
288     elseif(DEFINED status_then OR DEFINED status_else)
289       ocv_output_status("${text}")
290       set(status_text "${status_placeholder}")
291     else()
292       set(status_text "${text}")
293     endif()
294
295     if(DEFINED status_then OR DEFINED status_else)
296       if(${status_cond})
297         string(REPLACE ";" " " status_then "${status_then}")
298         string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}")
299         ocv_output_status("${status_text} ${status_then}")
300       else()
301         string(REPLACE ";" " " status_else "${status_else}")
302         string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}")
303         ocv_output_status("${status_text} ${status_else}")
304       endif()
305     else()
306       string(REPLACE ";" " " status_cond "${status_cond}")
307       string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}")
308       ocv_output_status("${status_text} ${status_cond}")
309     endif()
310   else()
311     ocv_output_status("${text}")
312   endif()
313 endfunction()
314
315
316 # splits cmake libraries list of format "general;item1;debug;item2;release;item3" to two lists
317 macro(ocv_split_libs_list lst lstdbg lstopt)
318   set(${lstdbg} "")
319   set(${lstopt} "")
320   set(perv_keyword "")
321   foreach(word ${${lst}})
322     if(word STREQUAL "debug" OR word STREQUAL "optimized")
323       set(perv_keyword ${word})
324     elseif(word STREQUAL "general")
325       set(perv_keyword "")
326     elseif(perv_keyword STREQUAL "debug")
327       list(APPEND ${lstdbg} "${word}")
328       set(perv_keyword "")
329     elseif(perv_keyword STREQUAL "optimized")
330       list(APPEND ${lstopt} "${word}")
331       set(perv_keyword "")
332     else()
333       list(APPEND ${lstdbg} "${word}")
334       list(APPEND ${lstopt} "${word}")
335       set(perv_keyword "")
336     endif()
337   endforeach()
338 endmacro()
339
340
341 # remove all matching elements from the list
342 macro(ocv_list_filterout lst regex)
343   foreach(item ${${lst}})
344     if(item MATCHES "${regex}")
345       list(REMOVE_ITEM ${lst} "${item}")
346     endif()
347   endforeach()
348 endmacro()
349
350
351 # stable & safe duplicates removal macro
352 macro(ocv_list_unique __lst)
353   if(${__lst})
354     list(REMOVE_DUPLICATES ${__lst})
355   endif()
356 endmacro()
357
358
359 # safe list reversal macro
360 macro(ocv_list_reverse __lst)
361   if(${__lst})
362     list(REVERSE ${__lst})
363   endif()
364 endmacro()
365
366
367 # safe list sorting macro
368 macro(ocv_list_sort __lst)
369   if(${__lst})
370     list(SORT ${__lst})
371   endif()
372 endmacro()
373
374
375 # add prefix to each item in the list
376 macro(ocv_list_add_prefix LST PREFIX)
377   set(__tmp "")
378   foreach(item ${${LST}})
379     list(APPEND __tmp "${PREFIX}${item}")
380   endforeach()
381   set(${LST} ${__tmp})
382   unset(__tmp)
383 endmacro()
384
385
386 # add suffix to each item in the list
387 macro(ocv_list_add_suffix LST SUFFIX)
388   set(__tmp "")
389   foreach(item ${${LST}})
390     list(APPEND __tmp "${item}${SUFFIX}")
391   endforeach()
392   set(${LST} ${__tmp})
393   unset(__tmp)
394 endmacro()
395
396
397 # gets and removes the first element from list
398 macro(ocv_list_pop_front LST VAR)
399   if(${LST})
400     list(GET ${LST} 0 ${VAR})
401     list(REMOVE_AT ${LST} 0)
402   else()
403     set(${VAR} "")
404   endif()
405 endmacro()
406
407
408 # simple regex escaping routine (does not cover all cases!!!)
409 macro(ocv_regex_escape var regex)
410   string(REGEX REPLACE "([+.*^$])" "\\\\1" ${var} "${regex}")
411 endmacro()
412
413
414 # get absolute path with symlinks resolved
415 macro(ocv_get_real_path VAR PATHSTR)
416   if(CMAKE_VERSION VERSION_LESS 2.8)
417     get_filename_component(${VAR} "${PATHSTR}" ABSOLUTE)
418   else()
419     get_filename_component(${VAR} "${PATHSTR}" REALPATH)
420   endif()
421 endmacro()
422
423
424 # convert list of paths to full paths
425 macro(ocv_convert_to_full_paths VAR)
426   if(${VAR})
427     set(__tmp "")
428     foreach(path ${${VAR}})
429       get_filename_component(${VAR} "${path}" ABSOLUTE)
430       list(APPEND __tmp "${${VAR}}")
431     endforeach()
432     set(${VAR} ${__tmp})
433     unset(__tmp)
434   endif()
435 endmacro()
436
437
438 # read set of version defines from the header file
439 macro(ocv_parse_header FILENAME FILE_VAR)
440   set(vars_regex "")
441   set(__parnet_scope OFF)
442   set(__add_cache OFF)
443   foreach(name ${ARGN})
444     if("${name}" STREQUAL "PARENT_SCOPE")
445       set(__parnet_scope ON)
446     elseif("${name}" STREQUAL "CACHE")
447       set(__add_cache ON)
448     elseif(vars_regex)
449       set(vars_regex "${vars_regex}|${name}")
450     else()
451       set(vars_regex "${name}")
452     endif()
453   endforeach()
454   if(EXISTS "${FILENAME}")
455     file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" )
456   else()
457     unset(${FILE_VAR})
458   endif()
459   foreach(name ${ARGN})
460     if(NOT "${name}" STREQUAL "PARENT_SCOPE" AND NOT "${name}" STREQUAL "CACHE")
461       if(${FILE_VAR})
462         if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*")
463           string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}")
464         else()
465           set(${name} "")
466         endif()
467         if(__add_cache)
468           set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE)
469         elseif(__parnet_scope)
470           set(${name} "${${name}}" PARENT_SCOPE)
471         endif()
472       else()
473         unset(${name} CACHE)
474       endif()
475     endif()
476   endforeach()
477 endmacro()
478
479 # read single version define from the header file
480 macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME)
481   ocv_clear_vars(${LIBNAME}_VERSION_MAJOR
482                  ${LIBNAME}_VERSION_MAJOR
483                  ${LIBNAME}_VERSION_MINOR
484                  ${LIBNAME}_VERSION_PATCH
485                  ${LIBNAME}_VERSION_TWEAK
486                  ${LIBNAME}_VERSION_STRING)
487   set(${LIBNAME}_H "")
488   if(EXISTS "${HDR_PATH}")
489     file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1)
490   endif()
491
492   if(${LIBNAME}_H)
493     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}")
494     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR  "${${LIBNAME}_H}")
495     string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}")
496     set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN})
497     set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN})
498     set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN})
499     set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}")
500
501     # append a TWEAK version if it exists:
502     set(${LIBNAME}_VERSION_TWEAK "")
503     if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
504       set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN})
505     endif()
506     if(${LIBNAME}_VERSION_TWEAK)
507       set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN})
508     else()
509       set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN})
510     endif()
511   endif()
512 endmacro()
513
514
515 ################################################################################################
516 # short command to setup source group
517 function(ocv_source_group group)
518   cmake_parse_arguments(OCV_SOURCE_GROUP "" "" "GLOB" ${ARGN})
519   file(GLOB srcs ${OCV_SOURCE_GROUP_GLOB})
520   source_group(${group} FILES ${srcs})
521 endfunction()