f3520966723eeabbf77a1de22cfe4601d55b1bd1
[occt.git] / adm / cmake / occt_macros.cmake
1 ##
2
3 if(OCCT_MACROS_ALREADY_INCLUDED)
4   return()
5 endif()
6 set(OCCT_MACROS_ALREADY_INCLUDED 1)
7
8
9 macro (OCCT_CHECK_AND_UNSET VARNAME)
10   if (DEFINED ${VARNAME})
11     unset (${VARNAME} CACHE)
12   endif()
13 endmacro()
14
15 macro (OCCT_CHECK_AND_UNSET_GROUP VARNAME)
16   OCCT_CHECK_AND_UNSET ("${VARNAME}_DIR")
17
18   OCCT_CHECK_AND_UNSET ("${VARNAME}_INCLUDE_DIR")
19
20   OCCT_CHECK_AND_UNSET ("${VARNAME}_LIBRARY")
21   OCCT_CHECK_AND_UNSET ("${VARNAME}_LIBRARY_DIR")
22
23   if (WIN32)
24     OCCT_CHECK_AND_UNSET ("${VARNAME}_DLL")
25     OCCT_CHECK_AND_UNSET ("${VARNAME}_DLL_DIR")
26   endif()
27 endmacro()
28
29 # COMPILER_BITNESS variable
30 macro (OCCT_MAKE_COMPILER_BITNESS)
31   math (EXPR COMPILER_BITNESS "32 + 32*(${CMAKE_SIZEOF_VOID_P}/8)")
32 endmacro()
33
34 # OS_WITH_BIT
35 macro (OCCT_MAKE_OS_WITH_BITNESS)
36
37   OCCT_MAKE_COMPILER_BITNESS()
38
39   if (WIN32)
40     set (OS_WITH_BIT "win${COMPILER_BITNESS}")
41   elseif(APPLE)
42     set (OS_WITH_BIT "mac${COMPILER_BITNESS}")
43   else()
44     set (OS_WITH_BIT "lin${COMPILER_BITNESS}")
45   endif()
46 endmacro()
47
48 # COMPILER variable
49 macro (OCCT_MAKE_COMPILER_SHORT_NAME)
50   if (MSVC)
51     if (MSVC70)
52       set (COMPILER vc7)
53     elseif (MSVC80)
54       set (COMPILER vc8)
55     elseif (MSVC90)
56       set (COMPILER vc9)
57     elseif (MSVC10)
58       set (COMPILER vc10)
59     elseif (MSVC11)
60       set (COMPILER vc11)
61     elseif (MSVC12)
62       set (COMPILER vc12)
63     elseif (MSVC14)
64       set (COMPILER vc14)
65     endif()
66   elseif (DEFINED CMAKE_COMPILER_IS_GNUCC)
67     set (COMPILER gcc)
68   elseif (DEFINED CMAKE_COMPILER_IS_GNUCXX)
69     set (COMPILER gxx)
70   elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
71     set (COMPILER clang)
72   elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
73     set (COMPILER icc)
74   else()
75     set (COMPILER ${CMAKE_GENERATOR})
76     string (REGEX REPLACE " " "" COMPILER ${COMPILER})
77   endif()
78 endmacro()
79
80 function (SUBDIRECTORY_NAMES MAIN_DIRECTORY RESULT)
81   file (GLOB SUB_ITEMS "${MAIN_DIRECTORY}/*")
82
83   foreach (ITEM ${SUB_ITEMS})
84     if (IS_DIRECTORY "${ITEM}")
85       get_filename_component (ITEM_NAME "${ITEM}" NAME)
86       list (APPEND LOCAL_RESULT "${ITEM_NAME}")
87     endif()
88   endforeach()
89   set (${RESULT} ${LOCAL_RESULT} PARENT_SCOPE)
90 endfunction()
91
92 function (OCCT_ORIGIN_AND_PATCHED_FILES RELATIVE_PATH SEARCH_TEMPLATE RESULT)
93
94   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${RELATIVE_PATH}")
95     file (GLOB FOUND_FILES "${BUILD_PATCH}/${RELATIVE_PATH}/${SEARCH_TEMPLATE}")
96   endif()
97
98   file (GLOB ORIGIN_FILES "${CMAKE_SOURCE_DIR}/${RELATIVE_PATH}/${SEARCH_TEMPLATE}")
99   foreach (ORIGIN_FILE ${ORIGIN_FILES})
100     # check for existence of patched version of current file
101     if (NOT BUILD_PATCH OR NOT EXISTS "${BUILD_PATCH}/${RELATIVE_PATH}")
102       list (APPEND FOUND_FILES ${ORIGIN_FILE})
103     else()
104       get_filename_component (ORIGIN_FILE_NAME "${ORIGIN_FILE}" NAME)
105       if (NOT EXISTS "${BUILD_PATCH}/${RELATIVE_PATH}/${ORIGIN_FILE_NAME}")
106         list (APPEND FOUND_FILES ${ORIGIN_FILE})
107       endif()
108     endif()
109   endforeach()
110
111   set (${RESULT} ${FOUND_FILES} PARENT_SCOPE)
112 endfunction()
113
114 function (FIND_PRODUCT_DIR ROOT_DIR PRODUCT_NAME RESULT)
115   OCCT_MAKE_COMPILER_SHORT_NAME()
116   OCCT_MAKE_COMPILER_BITNESS()
117
118   string (TOLOWER "${PRODUCT_NAME}" lower_PRODUCT_NAME)
119
120   list (APPEND SEARCH_TEMPLATES "^[^a-zA-Z]*${lower_PRODUCT_NAME}[^a-zA-Z]*${COMPILER}.*${COMPILER_BITNESS}")
121   list (APPEND SEARCH_TEMPLATES "^[^a-zA-Z]*${lower_PRODUCT_NAME}[^a-zA-Z]*[0-9.]+.*${COMPILER}.*${COMPILER_BITNESS}")
122   list (APPEND SEARCH_TEMPLATES "^[^a-zA-Z]*${lower_PRODUCT_NAME}[^a-zA-Z]*[0-9.]+.*${COMPILER_BITNESS}")
123   list (APPEND SEARCH_TEMPLATES "^[^a-zA-Z]*${lower_PRODUCT_NAME}[^a-zA-Z]*.*${COMPILER_BITNESS}")
124   list (APPEND SEARCH_TEMPLATES "^[^a-zA-Z]*${lower_PRODUCT_NAME}[^a-zA-Z]*[0-9.]+")
125   list (APPEND SEARCH_TEMPLATES "^[^a-zA-Z]*${lower_PRODUCT_NAME}[^a-zA-Z]*")
126
127   SUBDIRECTORY_NAMES ("${ROOT_DIR}" SUBDIR_NAME_LIST)
128
129   foreach (SEARCH_TEMPLATE ${SEARCH_TEMPLATES})
130     if (LOCAL_RESULT)
131       BREAK()
132     endif()
133
134     foreach (SUBDIR_NAME ${SUBDIR_NAME_LIST})
135       string (TOLOWER "${SUBDIR_NAME}" lower_SUBDIR_NAME)
136
137       string (REGEX MATCH "${SEARCH_TEMPLATE}" DUMMY_VAR "${lower_SUBDIR_NAME}")
138       if (DUMMY_VAR)
139         list (APPEND LOCAL_RESULT ${SUBDIR_NAME})
140       endif()
141     endforeach()
142   endforeach()
143
144   if (LOCAL_RESULT)
145     list (GET LOCAL_RESULT -1 DUMMY)
146     set (${RESULT} ${DUMMY} PARENT_SCOPE)
147   endif()
148 endfunction()
149
150 macro (OCCT_INSTALL_FILE_OR_DIR BEING_INSTALLED_OBJECT DESTINATION_PATH)
151   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${BEING_INSTALLED_OBJECT}")
152     if (IS_DIRECTORY "${BUILD_PATCH}/${BEING_INSTALLED_OBJECT}")
153       # first of all, install original files
154       install (DIRECTORY "${CMAKE_SOURCE_DIR}/${BEING_INSTALLED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
155
156       # secondly, rewrite original files with patched ones
157       install (DIRECTORY "${BUILD_PATCH}/${BEING_INSTALLED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
158     else()
159       install (FILES     "${BUILD_PATCH}/${BEING_INSTALLED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
160     endif()
161   else()
162     if (IS_DIRECTORY "${CMAKE_SOURCE_DIR}/${BEING_INSTALLED_OBJECT}")
163       install (DIRECTORY "${CMAKE_SOURCE_DIR}/${BEING_INSTALLED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
164     else()
165       install (FILES     "${CMAKE_SOURCE_DIR}/${BEING_INSTALLED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
166     endif()
167   endif()
168 endmacro()
169
170 macro (OCCT_CONFIGURE_AND_INSTALL BEING_CONGIRUGED_FILE BUILD_NAME INSTALL_NAME DESTINATION_PATH)
171   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${BEING_CONGIRUGED_FILE}")
172     configure_file("${BUILD_PATCH}/${BEING_CONGIRUGED_FILE}" "${BUILD_NAME}" @ONLY)
173   else()
174     configure_file("${CMAKE_SOURCE_DIR}/${BEING_CONGIRUGED_FILE}" "${BUILD_NAME}" @ONLY)
175   endif()
176
177   install(FILES "${OCCT_BINARY_DIR}/${BUILD_NAME}" DESTINATION  "${DESTINATION_PATH}" RENAME ${INSTALL_NAME})
178 endmacro()
179
180 macro (COLLECT_AND_INSTALL_OCCT_HEADER_FILES ROOT_TARGET_OCCT_DIR OCCT_BUILD_TOOLKITS)
181   set (OCCT_USED_PACKAGES)
182
183   # consider patched header.in template
184   set (TEMPLATE_HEADER_PATH "${CMAKE_SOURCE_DIR}/adm/templates/header.in")
185   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/adm/templates/header.in")
186     set (TEMPLATE_HEADER_PATH "${BUILD_PATCH}/adm/templates/header.in")
187   endif()
188
189   set (ROOT_OCCT_DIR ${CMAKE_SOURCE_DIR})
190
191   foreach (OCCT_USED_TOOLKIT ${OCCT_BUILD_TOOLKITS})
192     # append all required package folders
193     set (OCCT_TOOLKIT_PACKAGES)
194     if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/${OCCT_USED_TOOLKIT}/PACKAGES")
195       file (STRINGS "${BUILD_PATCH}/src/${OCCT_USED_TOOLKIT}/PACKAGES" OCCT_TOOLKIT_PACKAGES)
196     elseif (EXISTS "${CMAKE_SOURCE_DIR}/src/${OCCT_USED_TOOLKIT}/PACKAGES")
197       file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_USED_TOOLKIT}/PACKAGES" OCCT_TOOLKIT_PACKAGES)
198     endif()
199
200     list (APPEND OCCT_USED_PACKAGES ${OCCT_TOOLKIT_PACKAGES})
201   endforeach()
202
203   list (REMOVE_DUPLICATES OCCT_USED_PACKAGES)
204
205   set (OCCT_HEADER_FILES_COMPLETE)
206   set (OCCT_HEADER_FILE_NAMES_NOT_IN_FILES)
207   set (OCCT_HEADER_FILE_WITH_PROPER_NAMES)
208
209   string(TIMESTAMP CURRENT_TIME "%H:%M:%S")
210   message (STATUS "Info: \(${CURRENT_TIME}\) Compare FILES with files in package directories...")
211
212   foreach (OCCT_PACKAGE ${OCCT_USED_PACKAGES})
213     if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES")
214       file (STRINGS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES" OCCT_ALL_FILE_NAMES)
215     elseif (EXISTS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES")
216       file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES" OCCT_ALL_FILE_NAMES)
217     else()
218       message (WARNING "FILES has not been found in ${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}")
219       continue()
220     endif()
221
222     list (LENGTH OCCT_ALL_FILE_NAMES ALL_FILES_NB)
223     math (EXPR ALL_FILES_NB "${ALL_FILES_NB} - 1" )
224
225     # emit warnings if there is unprocessed headers
226     file (GLOB OCCT_ALL_FILES_IN_DIR "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/*.*")
227     file (GLOB OCCT_ALL_FILES_IN_PATCH_DIR "${BUILD_PATCH}/src/${OCCT_PACKAGE}/*.*")
228
229     # use patched header files
230     foreach (OCCT_FILE_IN_PATCH_DIR ${OCCT_ALL_FILES_IN_PATCH_DIR})
231       get_filename_component (OCCT_FILE_IN_PATCH_DIR_NAME ${OCCT_FILE_IN_PATCH_DIR} NAME)
232       list (REMOVE_ITEM OCCT_ALL_FILES_IN_DIR "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${OCCT_FILE_IN_PATCH_DIR_NAME}")
233       list (APPEND OCCT_ALL_FILES_IN_DIR "${OCCT_FILE_IN_PATCH_DIR}")
234     endforeach()
235
236     foreach (OCCT_FILE_IN_DIR ${OCCT_ALL_FILES_IN_DIR})
237       get_filename_component (OCCT_FILE_IN_DIR_NAME ${OCCT_FILE_IN_DIR} NAME)
238
239       set (OCCT_FILE_IN_DIR_STATUS OFF)
240
241       if (${ALL_FILES_NB} LESS 0)
242         break()
243       endif()
244
245       foreach (FILE_INDEX RANGE ${ALL_FILES_NB})
246         list (GET OCCT_ALL_FILE_NAMES ${FILE_INDEX} OCCT_FILE_NAME)
247
248         if ("${OCCT_FILE_IN_DIR_NAME}" STREQUAL "${OCCT_FILE_NAME}")
249           set (OCCT_FILE_IN_DIR_STATUS ON)
250
251           string (REGEX MATCH ".+\\.[hlg]xx|.+\\.h$" IS_HEADER_FOUND "${OCCT_FILE_NAME}")
252           if (IS_HEADER_FOUND)
253             list (APPEND OCCT_HEADER_FILES_COMPLETE ${OCCT_FILE_IN_DIR})
254
255             # collect header files with name that does not contain its package one
256             string (FIND "${OCCT_FILE_NAME}" "${OCCT_PACKAGE}_" FOUND_INDEX)
257             if (NOT ${FOUND_INDEX} EQUAL 0)
258               list (APPEND OCCT_HEADER_FILE_WITH_PROPER_NAMES "${OCCT_FILE_NAME}")
259             endif()
260           endif()
261
262           # remove found element from list
263           list (REMOVE_AT OCCT_ALL_FILE_NAMES ${FILE_INDEX})
264           math (EXPR ALL_FILES_NB "${ALL_FILES_NB} - 1" ) # decrement number
265
266           break()
267         endif()
268       endforeach()
269
270       if (NOT OCCT_FILE_IN_DIR_STATUS)
271         message (STATUS "Warning. File ${OCCT_FILE_IN_DIR} is not listed in ${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES")
272
273         string (REGEX MATCH ".+\\.[hlg]xx|.+\\.h$" IS_HEADER_FOUND "${OCCT_FILE_NAME}")
274         if (IS_HEADER_FOUND)
275           list (APPEND OCCT_HEADER_FILE_NAMES_NOT_IN_FILES ${OCCT_FILE_NAME})
276         endif()
277       endif()
278     endforeach()
279   endforeach()
280   
281   # create new file including found header
282   string(TIMESTAMP CURRENT_TIME "%H:%M:%S")
283   message (STATUS "Info: \(${CURRENT_TIME}\) Create header-links in inc folder...")
284
285   foreach (OCCT_HEADER_FILE ${OCCT_HEADER_FILES_COMPLETE})
286     get_filename_component (HEADER_FILE_NAME ${OCCT_HEADER_FILE} NAME)
287     configure_file ("${TEMPLATE_HEADER_PATH}" "${ROOT_TARGET_OCCT_DIR}/inc/${HEADER_FILE_NAME}" @ONLY)
288   endforeach()
289   
290   install (FILES ${OCCT_HEADER_FILES_COMPLETE} DESTINATION "${INSTALL_INCLUDE_DIR}")
291   
292   string(TIMESTAMP CURRENT_TIME "%H:%M:%S")
293   message (STATUS "Info: \(${CURRENT_TIME}\) Checking headers in inc folder...")
294     
295   file (GLOB OCCT_HEADER_FILES_OLD "${ROOT_TARGET_OCCT_DIR}/inc/*")
296   foreach (OCCT_HEADER_FILE_OLD ${OCCT_HEADER_FILES_OLD})
297     get_filename_component (HEADER_FILE_NAME ${OCCT_HEADER_FILE_OLD} NAME)
298     string (REGEX MATCH "^[a-zA-Z0-9]+" PACKAGE_NAME "${HEADER_FILE_NAME}")
299     
300     list (FIND OCCT_USED_PACKAGES ${PACKAGE_NAME} IS_HEADER_FOUND)
301     if (NOT ${IS_HEADER_FOUND} EQUAL -1)
302       if (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/${PACKAGE_NAME}/${HEADER_FILE_NAME}")
303         message (STATUS "Warning. ${OCCT_HEADER_FILE_OLD} is not presented in the sources and will be removed from ${ROOT_TARGET_OCCT_DIR}/inc")
304         file (REMOVE "${OCCT_HEADER_FILE_OLD}")
305       else()
306         list (FIND OCCT_HEADER_FILE_NAMES_NOT_IN_FILES ${PACKAGE_NAME} IS_HEADER_FOUND)
307         if (NOT ${IS_HEADER_FOUND} EQUAL -1)
308           message (STATUS "Warning. ${OCCT_HEADER_FILE_OLD} is presented in the sources but not involved in FILES and will be removed from ${ROOT_TARGET_OCCT_DIR}/inc")
309           file (REMOVE "${OCCT_HEADER_FILE_OLD}")
310         endif()
311       endif()
312     else()
313       set (IS_HEADER_FOUND -1)
314       if (NOT "${OCCT_HEADER_FILE_WITH_PROPER_NAMES}" STREQUAL "")
315         list (FIND OCCT_HEADER_FILE_WITH_PROPER_NAMES ${HEADER_FILE_NAME} IS_HEADER_FOUND)
316       endif()
317       
318       if (${IS_HEADER_FOUND} EQUAL -1)
319         message (STATUS "Warning. \(${PACKAGE_NAME}\) ${OCCT_HEADER_FILE_OLD} is not used and will be removed from ${ROOT_TARGET_OCCT_DIR}/inc")
320         file (REMOVE "${OCCT_HEADER_FILE_OLD}")
321       endif()
322     endif()
323   endforeach()
324 endmacro()
325
326 macro (OCCT_COPY_FILE_OR_DIR BEING_COPIED_OBJECT DESTINATION_PATH)
327   # first of all, copy original files
328   if (EXISTS "${CMAKE_SOURCE_DIR}/${BEING_COPIED_OBJECT}")
329     file (COPY "${CMAKE_SOURCE_DIR}/${BEING_COPIED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
330   endif()
331
332   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${BEING_COPIED_OBJECT}")
333     # secondly, rewrite original files with patched ones
334     file (COPY "${BUILD_PATCH}/${BEING_COPIED_OBJECT}" DESTINATION  "${DESTINATION_PATH}")
335   endif()
336 endmacro()
337
338 macro (OCCT_CONFIGURE BEING_CONGIRUGED_FILE FINAL_NAME)
339   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${BEING_CONGIRUGED_FILE}")
340     configure_file("${BUILD_PATCH}/${BEING_CONGIRUGED_FILE}" "${FINAL_NAME}" @ONLY)
341   else()
342     configure_file("${CMAKE_SOURCE_DIR}/${BEING_CONGIRUGED_FILE}" "${FINAL_NAME}" @ONLY)
343   endif()
344 endmacro()
345
346 macro (OCCT_ADD_SUBDIRECTORY BEING_ADDED_DIRECTORY)
347   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${BEING_ADDED_DIRECTORY}/CMakeLists.txt")
348     add_subdirectory(${BUILD_PATCH}/${BEING_ADDED_DIRECTORY})
349   elseif (EXISTS "${CMAKE_SOURCE_DIR}/${BEING_ADDED_DIRECTORY}/CMakeLists.txt")
350     add_subdirectory (${CMAKE_SOURCE_DIR}/${BEING_ADDED_DIRECTORY})
351   else()
352     message (STATUS "${BEING_ADDED_DIRECTORY} directory is not included")
353   endif()
354 endmacro()
355
356 function (OCCT_IS_PRODUCT_REQUIRED CSF_VAR_NAME USE_PRODUCT)
357   set (${USE_PRODUCT} OFF PARENT_SCOPE)
358
359   if (NOT BUILD_TOOLKITS)
360     message(STATUS "Warning: the list of being used toolkits is empty")
361   else()
362     foreach (USED_TOOLKIT ${BUILD_TOOLKITS})
363       if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/${USED_TOOLKIT}/EXTERNLIB")
364         file (READ "${BUILD_PATCH}/src/${USED_TOOLKIT}/EXTERNLIB" FILE_CONTENT)
365       elseif (EXISTS "${CMAKE_SOURCE_DIR}/src/${USED_TOOLKIT}/EXTERNLIB")
366         file (READ "${CMAKE_SOURCE_DIR}/src/${USED_TOOLKIT}/EXTERNLIB" FILE_CONTENT)
367       endif()
368
369       string (REGEX MATCH "${CSF_VAR_NAME}" DOES_FILE_CONTAIN "${FILE_CONTENT}")
370
371       if (DOES_FILE_CONTAIN)
372         set (${USE_PRODUCT} ON PARENT_SCOPE)
373         break()
374       endif()
375     endforeach()
376   endif()
377 endfunction()
378
379 function (FILE_TO_LIST FILE_NAME FILE_CONTENT)
380   set (LOCAL_FILE_CONTENT)
381   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${FILE_NAME}")
382     file (STRINGS "${BUILD_PATCH}/${FILE_NAME}" LOCAL_FILE_CONTENT)
383   elseif (EXISTS "${CMAKE_SOURCE_DIR}/${FILE_NAME}")
384     file (STRINGS "${CMAKE_SOURCE_DIR}/${FILE_NAME}" LOCAL_FILE_CONTENT)
385   endif()
386
387   set (${FILE_CONTENT} ${LOCAL_FILE_CONTENT} PARENT_SCOPE)
388 endfunction()
389
390 # Function to determine if TOOLKIT is OCCT toolkit
391 function (IS_OCCT_TOOLKIT TOOLKIT_NAME MODULES IS_TOOLKIT_FOUND)
392   set (${IS_TOOLKIT_FOUND} OFF PARENT_SCOPE)
393   foreach (MODULE ${${MODULES}})
394     set (TOOLKITS ${${MODULE}_TOOLKITS})
395     list (FIND TOOLKITS ${TOOLKIT_NAME} FOUND)
396
397     if (NOT ${FOUND} EQUAL -1)
398       set (${IS_TOOLKIT_FOUND} ON PARENT_SCOPE)
399     endif()
400   endforeach(MODULE)
401 endfunction()
402
403 # TOOLKIT_DEPS is defined with dependencies from file src/TOOLKIT_NAME/EXTERNLIB.
404 # CSF_ variables are ignored
405 function (OCCT_TOOLKIT_DEP TOOLKIT_NAME TOOLKIT_DEPS)
406   FILE_TO_LIST ("src/${TOOLKIT_NAME}/EXTERNLIB" FILE_CONTENT)
407
408   #list (APPEND LOCAL_TOOLKIT_DEPS ${TOOLKIT_NAME})
409   set (LOCAL_TOOLKIT_DEPS)
410   foreach (FILE_CONTENT_LINE ${FILE_CONTENT})
411     string (REGEX MATCH "^TK" TK_FOUND ${FILE_CONTENT_LINE})
412     if ("${FILE_CONTENT_LINE}" STREQUAL "DRAWEXE" OR NOT "${TK_FOUND}" STREQUAL "")
413       list (APPEND LOCAL_TOOLKIT_DEPS ${FILE_CONTENT_LINE})
414     endif()
415   endforeach()
416
417   set (${TOOLKIT_DEPS} ${LOCAL_TOOLKIT_DEPS} PARENT_SCOPE)
418 endfunction()
419
420 # TOOLKIT_FULL_DEPS is defined with complete dependencies (all levels)
421 function (OCCT_TOOLKIT_FULL_DEP TOOLKIT_NAME TOOLKIT_FULL_DEPS)
422   # first level dependencies are stored in LOCAL_TOOLKIT_FULL_DEPS
423   OCCT_TOOLKIT_DEP (${TOOLKIT_NAME} LOCAL_TOOLKIT_FULL_DEPS)
424
425   list (LENGTH LOCAL_TOOLKIT_FULL_DEPS LIST_LENGTH)
426   set (LIST_INDEX 0)
427   while (LIST_INDEX LESS LIST_LENGTH)
428     list (GET LOCAL_TOOLKIT_FULL_DEPS ${LIST_INDEX} CURRENT_TOOLKIT)
429     OCCT_TOOLKIT_DEP (${CURRENT_TOOLKIT} CURRENT_TOOLKIT_DEPS)
430
431     # append toolkits are not contained
432     foreach (CURRENT_TOOLKIT_DEP ${CURRENT_TOOLKIT_DEPS})
433       set (CURRENT_TOOLKIT_DEP_FOUND OFF)
434       foreach (LOCAL_TOOLKIT_FULL_DEP ${LOCAL_TOOLKIT_FULL_DEPS})
435         if ("${CURRENT_TOOLKIT_DEP}" STREQUAL "${LOCAL_TOOLKIT_FULL_DEP}")
436           set (CURRENT_TOOLKIT_DEP_FOUND ON)
437           break()
438         endif()
439       endforeach()
440       if ("${CURRENT_TOOLKIT_DEP_FOUND}" STREQUAL "OFF")
441         list (APPEND LOCAL_TOOLKIT_FULL_DEPS ${CURRENT_TOOLKIT_DEP})
442       endif()
443     endforeach()
444
445     # increment the list index
446     MATH(EXPR LIST_INDEX "${LIST_INDEX}+1")
447
448     # calculate new length
449     list (LENGTH LOCAL_TOOLKIT_FULL_DEPS LIST_LENGTH)
450   endwhile()
451
452   set (${TOOLKIT_FULL_DEPS} ${LOCAL_TOOLKIT_FULL_DEPS} PARENT_SCOPE)
453 endfunction()
454
455 # Function to get list of modules and toolkits from file adm/MODULES.
456 # Creates list <$MODULE_LIST> to store list of MODULES and
457 # <NAME_OF_MODULE>_TOOLKITS foreach module to store its toolkits.
458 function (OCCT_MODULES_AND_TOOLKITS MODULE_LIST)
459   FILE_TO_LIST ("adm/MODULES" FILE_CONTENT)
460
461   foreach (CONTENT_LINE ${FILE_CONTENT})
462     string (REPLACE " " ";" CONTENT_LINE ${CONTENT_LINE})
463     list (GET CONTENT_LINE 0 MODULE_NAME)
464     list (REMOVE_AT CONTENT_LINE 0)
465     list (APPEND ${MODULE_LIST} ${MODULE_NAME})
466     # (!) REMOVE THE LINE BELOW (implicit variables)
467     set (${MODULE_NAME}_TOOLKITS ${CONTENT_LINE} PARENT_SCOPE)
468   endforeach()
469
470   set (${MODULE_LIST} ${${MODULE_LIST}} PARENT_SCOPE)
471 endfunction()
472
473 # Returns OCC version string from file Standard_Version.hxx (if available)
474 function (OCC_VERSION OCC_VERSION_MAJOR OCC_VERSION_MINOR OCC_VERSION_MAINTENANCE OCC_VERSION_DEVELOPMENT OCC_VERSION_STRING_EXT)
475
476   set (OCC_VERSION_MAJOR         7)
477   set (OCC_VERSION_MINOR         0)
478   set (OCC_VERSION_MAINTENANCE   0)
479   set (OCC_VERSION_DEVELOPMENT   dev)
480   set (OCC_VERSION_COMPLETE      "7.0.0")
481  
482   set (STANDARD_VERSION_FILE "${CMAKE_SOURCE_DIR}/src/Standard/Standard_Version.hxx")
483   if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/Standard/Standard_Version.hxx")
484     set (STANDARD_VERSION_FILE "${BUILD_PATCH}/src/Standard/Standard_Version.hxx")
485   endif()
486
487   if (EXISTS "${STANDARD_VERSION_FILE}")
488     foreach (SOUGHT_VERSION OCC_VERSION_MAJOR OCC_VERSION_MINOR OCC_VERSION_MAINTENANCE)
489       file (STRINGS "${STANDARD_VERSION_FILE}" ${SOUGHT_VERSION} REGEX "^#define ${SOUGHT_VERSION} .*")
490       string (REGEX REPLACE ".*${SOUGHT_VERSION} .*([^ ]+).*" "\\1" ${SOUGHT_VERSION} "${${SOUGHT_VERSION}}" )
491     endforeach()
492     
493     foreach (SOUGHT_VERSION OCC_VERSION_DEVELOPMENT OCC_VERSION_COMPLETE)
494       file (STRINGS "${STANDARD_VERSION_FILE}" ${SOUGHT_VERSION} REGEX "^#define ${SOUGHT_VERSION} .*")
495       string (REGEX REPLACE ".*${SOUGHT_VERSION} .*\"([^ ]+)\".*" "\\1" ${SOUGHT_VERSION} "${${SOUGHT_VERSION}}" )
496     endforeach()
497   endif()
498  
499   set (OCC_VERSION_MAJOR "${OCC_VERSION_MAJOR}" PARENT_SCOPE)
500   set (OCC_VERSION_MINOR "${OCC_VERSION_MINOR}" PARENT_SCOPE)
501   set (OCC_VERSION_MAINTENANCE "${OCC_VERSION_MAINTENANCE}" PARENT_SCOPE)
502   set (OCC_VERSION_DEVELOPMENT "${OCC_VERSION_DEVELOPMENT}" PARENT_SCOPE)
503   
504   if (OCC_VERSION_DEVELOPMENT AND OCC_VERSION_COMPLETE)
505     set (OCC_VERSION_STRING_EXT "${OCC_VERSION_COMPLETE}.${OCC_VERSION_DEVELOPMENT}" PARENT_SCOPE)
506   else()
507     set (OCC_VERSION_STRING_EXT "${OCC_VERSION_COMPLETE}" PARENT_SCOPE)
508   endif()
509 endfunction()
510
511 macro (CHECK_PATH_FOR_CONSISTENCY THE_ROOT_PATH_NAME THE_BEING_CHECKED_PATH_NAME THE_VAR_TYPE THE_MESSAGE_OF_BEING_CHECKED_PATH)
512   
513   set (THE_ROOT_PATH "${${THE_ROOT_PATH_NAME}}")
514   set (THE_BEING_CHECKED_PATH "${${THE_BEING_CHECKED_PATH_NAME}}")
515
516   if (THE_BEING_CHECKED_PATH OR EXISTS "${THE_BEING_CHECKED_PATH}")
517     get_filename_component (THE_ROOT_PATH_ABS "${THE_ROOT_PATH}" ABSOLUTE)
518     get_filename_component (THE_BEING_CHECKED_PATH_ABS "${THE_BEING_CHECKED_PATH}" ABSOLUTE)
519
520     string (REGEX MATCH "${THE_ROOT_PATH_ABS}" DOES_PATH_CONTAIN "${THE_BEING_CHECKED_PATH_ABS}")
521
522     if (NOT DOES_PATH_CONTAIN) # if cmake found the being checked path at different place from THE_ROOT_PATH_ABS
523       set (${THE_BEING_CHECKED_PATH_NAME} "" CACHE ${THE_VAR_TYPE} "${THE_MESSAGE_OF_BEING_CHECKED_PATH}" FORCE)
524     endif()
525   else()
526     set (${THE_BEING_CHECKED_PATH_NAME} "" CACHE ${THE_VAR_TYPE} "${THE_MESSAGE_OF_BEING_CHECKED_PATH}" FORCE)
527   endif()
528
529 endmacro()