0030691: Data Exchange - implement import of mesh data from files in glTF format
[occt.git] / adm / genconfdeps.tcl
1 # =======================================================================
2 # Created on: 2012-01-26
3 # Created by: Kirill GAVRILOV
4 # Copyright (c) 2012 OPEN CASCADE SAS
5 #
6 # This file is part of Open CASCADE Technology software library.
7 #
8 # This library is free software; you can redistribute it and/or modify it under
9 # the terms of the GNU Lesser General Public License version 2.1 as published
10 # by the Free Software Foundation, with special exception defined in the file
11 # OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 # distribution for complete text of the license and disclaimer of any warranty.
13 #
14 # Alternatively, this file may be used under the terms of Open CASCADE
15 # commercial license or contractual agreement.
16
17 # =======================================================================
18 # Tools for search of third-party libraries and generation on environment
19 # customization script
20 # =======================================================================
21
22 set ARCH "64"
23
24 if { "$tcl_platform(platform)" == "unix" } {
25   set SYS_PATH_SPLITTER ":"
26   set SYS_LIB_PREFIX    "lib"
27   set SYS_EXE_SUFFIX    ""
28   if { "$tcl_platform(os)" == "Darwin" } {
29     set SYS_LIB_SUFFIX "dylib"
30     set PRJFMT "xcd"
31   } else {
32     set SYS_LIB_SUFFIX "so"
33     set PRJFMT "cbp"
34   }
35   set VCVER "gcc"
36   set VCVARS ""
37 } elseif { "$tcl_platform(platform)" == "windows" } {
38   set SYS_PATH_SPLITTER ";"
39   set SYS_LIB_PREFIX    ""
40   set SYS_LIB_SUFFIX    "lib"
41   set SYS_EXE_SUFFIX    ".exe"
42   set VCVER  "vc10"
43   set VCVARS ""
44   set PRJFMT "vcxproj"
45 }
46
47 set SHORTCUT_HEADERS "ShortCut"
48
49 set PRODUCTS_PATH ""
50 set CSF_OPT_INC   [list]
51 set CSF_OPT_LIB32 [list]
52 set CSF_OPT_LIB64 [list]
53 set CSF_OPT_BIN32 [list]
54 set CSF_OPT_BIN64 [list]
55
56 if { "$tcl_platform(pointerSize)" == "4" } {
57   set ARCH "32"
58 }
59 if { [info exists ::env(ARCH)] } {
60   set ARCH "$::env(ARCH)"
61 }
62
63 if { [info exists ::env(SHORTCUT_HEADERS)] } {
64   set SHORTCUT_HEADERS "$::env(SHORTCUT_HEADERS)"
65   if { $SHORTCUT_HEADERS == "true" } {
66     set SHORTCUT_HEADERS "ShortCut"
67   }
68 }
69
70 # fetch environment variables (e.g. set by custom.sh or custom.bat) and set them as tcl variables with the same name
71 set THE_ENV_VARIABLES {HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK HAVE_ZLIB HAVE_LIBLZMA HAVE_RAPIDJSON HAVE_OPENCL CHECK_QT4 CHECK_JDK MACOSX_USE_GLX HAVE_RelWithDebInfo}
72 foreach anEnvIter $THE_ENV_VARIABLES {
73   set ${anEnvIter} "false"
74   if { [info exists ::env(${anEnvIter})] } {
75     set ${anEnvIter} "$::env(${anEnvIter})"
76   }
77 }
78 # do not export platform-specific variables
79 if { "$::tcl_platform(os)" == "Darwin" } {
80   set HAVE_GLES2 ""
81 } else {
82   set MACOSX_USE_GLX ""
83 }
84 if { "$tcl_platform(platform)" != "windows" } {
85   set HAVE_D3D ""
86   set HAVE_RelWithDebInfo ""
87 }
88 foreach anEnvIter {ARCH VCVER VCVARS PRJFMT PRODUCTS_PATH} {
89   if { [info exists ::env(${anEnvIter})] } {
90     set ${anEnvIter} "$::env(${anEnvIter})"
91   }
92 }
93
94 if { [info exists ::env(CSF_OPT_INC)] } {
95   set CSF_OPT_INC [split "$::env(CSF_OPT_INC)" $::SYS_PATH_SPLITTER]
96 }
97 if { [info exists ::env(CSF_OPT_LIB32)] } {
98   set CSF_OPT_LIB32 [split "$::env(CSF_OPT_LIB32)" $::SYS_PATH_SPLITTER]
99 }
100 if { [info exists ::env(CSF_OPT_LIB64)] } {
101   set CSF_OPT_LIB64 [split "$::env(CSF_OPT_LIB64)" $::SYS_PATH_SPLITTER]
102 }
103 if { [info exists ::env(CSF_OPT_BIN32)] } {
104   set CSF_OPT_BIN32 [split "$::env(CSF_OPT_BIN32)" $::SYS_PATH_SPLITTER]
105 }
106 if { [info exists ::env(CSF_OPT_BIN64)] } {
107   set CSF_OPT_BIN64 [split "$::env(CSF_OPT_BIN64)" $::SYS_PATH_SPLITTER]
108 }
109
110 # Search header file in $::CSF_OPT_INC and standard paths
111 proc wokdep:SearchHeader {theHeader} {
112   # search in custom paths
113   foreach anIncPath $::CSF_OPT_INC {
114     set aPath "${anIncPath}/${theHeader}"
115     if { [file exists "$aPath"] } {
116       return "$aPath"
117     }
118   }
119
120   # search in system
121   set aPath "/usr/include/${theHeader}"
122   if { [file exists "$aPath"] } {
123     return "$aPath"
124   }
125
126   if { "$::tcl_platform(os)" == "Linux" } {
127     if { "$::ARCH" == "64" } {
128       set aPath "/usr/include/x86_64-linux-gnu/${theHeader}"
129       if { [file exists "$aPath"] } {
130         return "$aPath"
131       }
132     } else {
133       set aPath "/usr/include/i386-linux-gnu/${theHeader}"
134       if { [file exists "$aPath"] } {
135         return "$aPath"
136       }
137     }
138   }
139
140   return ""
141 }
142
143 # Search library file in $::CSF_OPT_LIB* and standard paths
144 proc wokdep:SearchLib {theLib theBitness {theSearchPath ""}} {
145   if { "$theSearchPath" != "" } {
146     set aPath "${theSearchPath}/${::SYS_LIB_PREFIX}${theLib}.${::SYS_LIB_SUFFIX}"
147     if { [file exists "$aPath"] } {
148       return "$aPath"
149     } else {
150       return ""
151     }
152   }
153
154   # search in custom paths
155   foreach aLibPath [set ::CSF_OPT_LIB$theBitness] {
156     set aPath "${aLibPath}/${::SYS_LIB_PREFIX}${theLib}.${::SYS_LIB_SUFFIX}"
157     if { [file exists "$aPath"] } {
158       return "$aPath"
159     }
160   }
161
162   # search in system
163   if { "$::ARCH" == "$theBitness"} {
164     set aPath "/usr/lib/${::SYS_LIB_PREFIX}${theLib}.${::SYS_LIB_SUFFIX}"
165     if { [file exists "$aPath"] } {
166       return "$aPath"
167     }
168   }
169
170
171   if { "$::tcl_platform(os)" == "Linux" } {
172     if { "$theBitness" == "64" } {
173       set aPath "/usr/lib/x86_64-linux-gnu/lib${theLib}.so"
174       if { [file exists "$aPath"] } {
175         return "$aPath"
176       }
177     } else {
178       set aPath "/usr/lib/i386-linux-gnu/lib${theLib}.so"
179       if { [file exists "$aPath"] } {
180         return "$aPath"
181       }
182     }
183   }
184
185   return ""
186 }
187
188 # Search file in $::CSF_OPT_BIN* and standard paths
189 proc wokdep:SearchBin {theBin theBitness {theSearchPath ""}} {
190   if { "$theSearchPath" != "" } {
191     set aPath "${theSearchPath}/${theBin}"
192     if { [file exists "$aPath"] } {
193       return "$aPath"
194     } else {
195       return ""
196     }
197   }
198
199   # search in custom paths
200   foreach aBinPath [set ::CSF_OPT_BIN$theBitness] {
201     set aPath "${aBinPath}/${theBin}"
202     if { [file exists "$aPath"] } {
203       return "$aPath"
204     }
205   }
206
207   # search in system
208   if { "$::ARCH" == "$theBitness"} {
209     set aPath "/usr/bin/${theBin}"
210     if { [file exists "$aPath"] } {
211       return "$aPath"
212     }
213   }
214
215   return ""
216 }
217
218 # Detect compiler C-runtime version 'vc*' and architecture '32'/'64'
219 # to determine preferred path.
220 proc wokdep:Preferred {theList theCmpl theArch} {
221   if { [llength $theList] == 0 } {
222     return ""
223   }
224
225   # keep only two first digits in "vc141"
226   if { ! [regexp {^vc[0-9][0-9]} $theCmpl aCmpl] } {
227     set aCmpl $theCmpl
228   }
229
230   set aShortList {}
231   foreach aPath $theList {
232     if { [string first "$aCmpl" "$aPath"] != "-1" } {
233       lappend aShortList "$aPath"
234     }
235   }
236
237   if { [llength $aShortList] == 0 } {
238     #return [lindex $theList 0]
239     set aShortList $theList
240   }
241
242   set aVeryShortList {}
243   foreach aPath $aShortList {
244     if { [string first "$theArch" "$aPath"] != "-1" } {
245       lappend aVeryShortList "$aPath"
246     }
247   }
248   if { [llength $aVeryShortList] == 0 } {
249     return [lindex [lsort -decreasing $aShortList] 0]
250   }
251
252   return [lindex [lsort -decreasing $aVeryShortList] 0]
253 }
254
255 # Search library placement
256 proc wokdep:SearchStandardLibrary {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64 theName theCheckHeader theCheckLib theCheckFolders} {
257   upvar $theErrInc   anErrInc
258   upvar $theErrLib32 anErrLib32
259   upvar $theErrLib64 anErrLib64
260   upvar $theErrBin32 anErrBin32
261   upvar $theErrBin64 anErrBin64
262
263   set isFound "true"
264   set aHeaderPath [wokdep:SearchHeader "$theCheckHeader"]
265   if { "$aHeaderPath"  == "" } {
266     set hasHeader false
267     foreach aFolderIter $theCheckFolders {
268       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{$aFolderIter}*] "$::VCVER" "$::ARCH" ]
269       if { "$aPath" != "" && [file exists "$aPath/include/$theCheckHeader"] } {
270         lappend ::CSF_OPT_INC "$aPath/include"
271         set hasHeader true
272         break
273       }
274     }
275     if { !$hasHeader } {
276       lappend anErrInc "Error: '$theCheckHeader' not found ($theName)"
277       set isFound "false"
278     }
279   }
280
281   foreach anArchIter {64 32} {
282     set aLibPath [wokdep:SearchLib "$theCheckLib" "$anArchIter"]
283     if { "$aLibPath" == "" } {
284       set hasLib false
285       foreach aFolderIter $theCheckFolders {
286         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{$aFolderIter}*] "$::VCVER" "$anArchIter" ]
287         set aLibPath [wokdep:SearchLib "$theCheckLib" "$anArchIter" "$aPath/lib"]
288         if { "$aLibPath" != "" } {
289           lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
290           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
291           set hasLib true
292           break
293         }
294       }
295       if { !$hasLib } {
296         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}$theCheckLib.${::SYS_LIB_SUFFIX}' not found ($theName)"
297         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
298       }
299     }
300
301     if { "$::tcl_platform(platform)" == "windows" } {
302       set aDllPath [wokdep:SearchBin "$theCheckLib.dll" "$anArchIter"]
303       if { "$aDllPath" == "" } {
304         set hasDll false
305         foreach aFolderIter $theCheckFolders {
306           set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{$aFolderIter}*] "$::VCVER" "$anArchIter" ]
307           set aDllPath [wokdep:SearchBin "$theCheckLib.dll" "$anArchIter" "$aPath/bin"]
308           if { "$aDllPath" != "" } {
309             lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
310             set hasDll true
311             break
312           } else {
313             set aDllPath [wokdep:SearchBin "$theCheckLib.dll" "$anArchIter" "$aPath/lib"]
314             if { "$aDllPath" != "" } {
315               lappend ::CSF_OPT_BIN$anArchIter "$aPath/lib"
316               set hasDll true
317               break
318             }
319           }
320         }
321         if { !$hasDll } {
322           lappend anErrBin$anArchIter "Error: '$theCheckLib.dll' not found ($theName)"
323           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
324         }
325       }
326     }
327   }
328
329   return "$isFound"
330 }
331
332 # Search Tcl/Tk libraries placement
333 proc wokdep:SearchTclTk {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
334   upvar $theErrInc   anErrInc
335   upvar $theErrLib32 anErrLib32
336   upvar $theErrLib64 anErrLib64
337   upvar $theErrBin32 anErrBin32
338   upvar $theErrBin64 anErrBin64
339
340   set tclver_maj 8
341   set tclver_min 6
342   
343   set isFound "true"
344   set aTclHPath [wokdep:SearchHeader "tcl.h"]
345   set aTkHPath  [wokdep:SearchHeader "tk.h"]
346   if { "$aTclHPath" == "" || "$aTkHPath" == "" } {
347     if { [file exists "/usr/include/tcl8.6/tcl.h"]
348       && [file exists "/usr/include/tcl8.6/tk.h" ] } {
349       lappend ::CSF_OPT_INC "/usr/include/tcl8.6"
350       set aTclHPath "/usr/include/tcl8.6/tcl.h"
351     } else {
352       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tcl}*] "$::VCVER" "$::ARCH" ]
353       if { "$aPath" != "" && [file exists "$aPath/include/tcl.h"] && [file exists "$aPath/include/tk.h"] } {
354         lappend ::CSF_OPT_INC "$aPath/include"
355         set aTclHPath "$aPath/include/tcl.h"
356       } else {
357         lappend anErrInc "Error: 'tcl.h' or 'tk.h' not found (Tcl/Tk)"
358         set isFound "false"
359       }
360     }
361   }
362
363   # detect tcl version by parsing header file
364   if { $isFound } {
365     set fh [open $aTclHPath]
366     set tcl_h [read $fh]
367     close $fh
368     regexp {define\s+TCL_MAJOR_VERSION\s+([0-9]+)} $tcl_h dummy tclver_maj
369     regexp {define\s+TCL_MINOR_VERSION\s+([0-9]+)} $tcl_h dummy tclver_min
370   }
371
372   if { "$::tcl_platform(platform)" == "windows" } {
373     set aTclLibName "tcl${tclver_maj}${tclver_min}"
374     set aTkLibName  "tk${tclver_maj}${tclver_min}"
375   } else {
376     set aTclLibName "tcl${tclver_maj}.${tclver_min}"
377     set aTkLibName  "tk${tclver_maj}.${tclver_min}"
378   }
379
380   foreach anArchIter {64 32} {
381     set aTclLibPath [wokdep:SearchLib "$aTclLibName" "$anArchIter"]
382     set aTkLibPath  [wokdep:SearchLib "$aTkLibName"  "$anArchIter"]
383     if { "$aTclLibPath" == "" || "$aTkLibPath" == "" } {
384       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tcl}*] "$::VCVER" "$anArchIter" ]
385       set aTclLibPath [wokdep:SearchLib "$aTclLibName" "$anArchIter" "$aPath/lib"]
386       set aTkLibPath  [wokdep:SearchLib "$aTkLibName"  "$anArchIter" "$aPath/lib"]
387       if { "$aTclLibPath" != "" && "$aTkLibPath" != "" } {
388         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
389       } else {
390         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}${aTclLibName}.${::SYS_LIB_SUFFIX}' or '${::SYS_LIB_PREFIX}${aTkLibName}.${::SYS_LIB_SUFFIX}' not found (Tcl/Tk)"
391         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
392       }
393     }
394
395     if { "$::tcl_platform(platform)" == "windows" } {
396       set aTclDllPath [wokdep:SearchBin "${aTclLibName}.dll" "$anArchIter"]
397       set aTkDllPath  [wokdep:SearchBin "${aTkLibName}.dll"  "$anArchIter"]
398       if { "$aTclDllPath" == "" || "$aTkDllPath" == "" } {
399         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tcl}*] "$::VCVER" "$anArchIter" ]
400         set aTclDllPath [wokdep:SearchBin "${aTclLibName}.dll" "$anArchIter" "$aPath/bin"]
401         set aTkDllPath  [wokdep:SearchBin "${aTkLibName}.dll"  "$anArchIter" "$aPath/bin"]
402         if { "$aTclDllPath" != "" && "$aTkDllPath" != "" } {
403           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
404         } else {
405           lappend anErrBin$anArchIter "Error: '${aTclLibName}.dll' or '${aTkLibName}.dll' not found (Tcl/Tk)"
406           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
407         }
408       }
409     }
410   }
411
412   return "$isFound"
413 }
414
415 # Search FreeType library placement
416 proc wokdep:SearchFreeType {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
417   upvar $theErrInc   anErrInc
418   upvar $theErrLib32 anErrLib32
419   upvar $theErrLib64 anErrLib64
420   upvar $theErrBin32 anErrBin32
421   upvar $theErrBin64 anErrBin64
422
423   set isFound "true"
424   set aFtBuildPath [wokdep:SearchHeader "ft2build.h"]
425
426   if { "$aFtBuildPath" == "" } {
427     # TODO - use `freetype-config --cflags` instead
428     set aSysFreeType "/usr/include/freetype2"
429     if { [file exists "$aSysFreeType/ft2build.h"] } {
430       lappend ::CSF_OPT_INC "$aSysFreeType"
431     } elseif { [file exists "$aSysFreeType/freetype2/ft2build.h"] } {
432       lappend ::CSF_OPT_INC "$aSysFreeType/freetype2"
433     } else {
434       set aSysFreeType "/usr/X11/include/freetype2"
435       if { [file exists "$aSysFreeType/ft2build.h"] } {
436         lappend ::CSF_OPT_INC "/usr/X11/include"
437         lappend ::CSF_OPT_INC "$aSysFreeType"
438       } else {
439         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{freetype}*] "$::VCVER" "$::ARCH" ]
440         if {"$aPath" != ""} {
441           if {[file exists "$aPath/include/ft2build.h"]} {
442             lappend ::CSF_OPT_INC "$aPath/include"
443           } elseif {[file exists "$aPath/include/freetype2/ft2build.h"]} {
444             lappend ::CSF_OPT_INC "$aPath/include/freetype2"
445           }
446         } else {
447           lappend anErrInc "Error: 'freetype.h' not found (FreeType2)"
448           set isFound "false"
449         }
450       }
451     }
452   }
453
454   # parse 'freetype-config --libs'
455   set aConfLibPath ""
456   if { [catch { set aConfLibs [exec freetype-config --libs] } ] == 0 } {
457     foreach aPath [split $aConfLibs " "] {
458       if { [string first "-L" "$aPath"] == 0 } {
459         set aConfLibPath [string range "$aPath" 2 [string length "$aPath"]]
460       }
461     }
462   }
463
464   foreach anArchIter {64 32} {
465     set aFtLibPath [wokdep:SearchLib "freetype" "$anArchIter"]
466     if { "$aFtLibPath" == "" } {
467       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{freetype}*] "$::VCVER" "$anArchIter" ]
468       set aFtLibPath [wokdep:SearchLib "freetype" "$anArchIter" "$aPath/lib"]
469       if { "$aFtLibPath" != "" } {
470         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
471       } else {
472         set aFtLibPath [wokdep:SearchLib "freetype" "$anArchIter" "$aConfLibPath"]
473         if { "$aFtLibPath" != "" } {
474           lappend ::CSF_OPT_LIB$anArchIter "$aConfLibPath"
475         } else {
476           lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}freetype.${::SYS_LIB_SUFFIX}' not found (FreeType2)"
477           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
478         }
479       }
480     }
481     if { "$::tcl_platform(platform)" == "windows" } {
482       set aFtDllPath [wokdep:SearchBin "freetype.dll" "$anArchIter"]
483       if { "$aFtDllPath" == "" } {
484         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{freetype}*] "$::VCVER" "$anArchIter" ]
485         set aFtDllPath [wokdep:SearchBin "freetype.dll" "$anArchIter" "$aPath/bin"]
486         if { "$aFtDllPath" != "" } {
487           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
488         } else {
489           set aFtDllPath [wokdep:SearchBin "freetype.dll" "$anArchIter" "$aPath/lib"]
490           if { "$aFtDllPath" != "" } {
491             lappend ::CSF_OPT_BIN$anArchIter "$aPath/lib"
492           } else {
493             lappend anErrBin$anArchIter "Error: 'freetype.dll' not found (FreeType2)"
494             if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
495           }
496         }
497       }
498     }
499   }
500
501   return "$isFound"
502 }
503
504 # Search FreeImage library placement
505 proc wokdep:SearchFreeImage {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
506   upvar $theErrInc   anErrInc
507   upvar $theErrLib32 anErrLib32
508   upvar $theErrLib64 anErrLib64
509   upvar $theErrBin32 anErrBin32
510   upvar $theErrBin64 anErrBin64
511
512   # binary distribution has another layout
513   set aFImageDist     "Dist"
514
515   set isFound "true"
516   set aFImageHPath [wokdep:SearchHeader "FreeImage.h"]
517   if { "$aFImageHPath" == "" } {
518     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{freeimage}*] "$::VCVER" "$::ARCH" ]
519     if { "$aPath" != "" && [file exists "$aPath/include/FreeImage.h"] } {
520       lappend ::CSF_OPT_INC "$aPath/include"
521     } elseif { "$aPath" != "" && [file exists "$aPath/$aFImageDist/FreeImage.h"] } {
522       lappend ::CSF_OPT_INC "$aPath/$aFImageDist"
523     } else {
524       lappend anErrInc "Error: 'FreeImage.h' not found (FreeImage)"
525       set isFound "false"
526     }
527   }
528
529   foreach anArchIter {64 32} {
530     set aFImageLibPath [wokdep:SearchLib "freeimage"     "$anArchIter"]
531     if { "$aFImageLibPath" == "" } {
532       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{freeimage}*] "$::VCVER" "$anArchIter" ]
533       set aFImageLibPath [wokdep:SearchLib "freeimage" "$anArchIter" "$aPath/lib"]
534       if { "$aFImageLibPath" != "" } {
535         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
536       } else {
537         set aFImageLibPath [wokdep:SearchLib "freeimage" "$anArchIter" "$aPath/$aFImageDist"]
538         if { "$aFImageLibPath" != "" } {
539           lappend ::CSF_OPT_LIB$anArchIter "$aPath/$aFImageDist"
540         } else {
541           lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}freeimage.${::SYS_LIB_SUFFIX}' not found (FreeImage)"
542           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
543         }
544       }
545     }
546     if { "$::tcl_platform(platform)" == "windows" } {
547       set aFImageDllPath [wokdep:SearchBin "freeimage.dll" "$anArchIter"]
548       if { "$aFImageDllPath" == "" } {
549         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{freeimage}*] "$::VCVER" "$anArchIter" ]
550         set aFImageDllPath [wokdep:SearchBin "freeimage.dll" "$anArchIter" "$aPath/bin"]
551         if { "$aFImageDllPath" != "" } {
552           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
553         } else {
554           set aFImageDllPath [wokdep:SearchBin "freeimage.dll" "$anArchIter" "$aPath/$aFImageDist"]
555           if { "$aFImageDllPath" != "" } {
556             lappend ::CSF_OPT_BIN$anArchIter "$aPath/$aFImageDist"
557           } else {
558             lappend anErrBin$anArchIter "Error: 'freeimage.dll' is not found (FreeImage)"
559             if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
560           }
561         }
562       }
563     }
564   }
565
566   return "$isFound"
567 }
568
569 # Search FFmpeg framework placement
570 proc wokdep:SearchFFmpeg {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
571   upvar $theErrInc   anErrInc
572   upvar $theErrLib32 anErrLib32
573   upvar $theErrLib64 anErrLib64
574   upvar $theErrBin32 anErrBin32
575   upvar $theErrBin64 anErrBin64
576
577   set isFound "true"
578   set aFFmpegHPath [wokdep:SearchHeader "libavutil/avutil.h"]
579   if { "$aFFmpegHPath"  == "" } {
580     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{ffmpeg}*] "$::VCVER" "$::ARCH" ]
581     if { "$aPath" != "" && [file exists "$aPath/include/libavutil/avutil.h"] } {
582       lappend ::CSF_OPT_INC "$aPath/include"
583     } else {
584       lappend anErrInc "Error: 'libavutil/avutil.h' not found (FFmpeg)"
585       set isFound "false"
586     }
587   }
588
589   foreach anArchIter {64 32} {
590     set aFFmpegLibPath [wokdep:SearchLib "avutil" "$anArchIter"]
591     if { "$aFFmpegLibPath" == "" } {
592       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{ffmpeg}*] "$::VCVER" "$anArchIter" ]
593       set aFFmpegLibPath [wokdep:SearchLib "avutil" "$anArchIter" "$aPath/lib"]
594       if { "$aFFmpegLibPath" != "" } {
595         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
596         lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
597       } else {
598         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}avutil.${::SYS_LIB_SUFFIX}' not found (FFmpeg)"
599         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
600       }
601     }
602   }
603
604   return "$isFound"
605 }
606
607 # Search TBB library placement
608 proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
609   upvar $theErrInc   anErrInc
610   upvar $theErrLib32 anErrLib32
611   upvar $theErrLib64 anErrLib64
612   upvar $theErrBin32 anErrBin32
613   upvar $theErrBin64 anErrBin64
614
615   # keep only two first digits in "vc141"
616   if { ! [regexp {^vc[0-9][0-9]} ${::VCVER} aVcLib] } {
617     set aVcLib ${::VCVER}
618   }
619
620   set isFound "true"
621   set aTbbHPath [wokdep:SearchHeader "tbb/scalable_allocator.h"]
622   if { "$aTbbHPath"  == "" } {
623     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] "$::VCVER" "$::ARCH" ]
624     if { "$aPath" != "" && [file exists "$aPath/include/tbb/scalable_allocator.h"] } {
625       lappend ::CSF_OPT_INC "$aPath/include"
626     } else {
627       lappend anErrInc "Error: 'tbb/scalable_allocator.h' not found (Intel TBB)"
628       set isFound "false"
629     }
630   }
631
632   foreach anArchIter {64 32} {
633     set aSubDir "ia32"
634     if { "$anArchIter" == "64"} {
635       set aSubDir "intel64"
636     }
637
638     set aTbbLibPath [wokdep:SearchLib "tbb" "$anArchIter"]
639     if { "$aTbbLibPath" == "" } {
640       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] $aVcLib "$anArchIter" ]
641       set aTbbLibPath [wokdep:SearchLib "tbb" "$anArchIter" "$aPath/lib/$aSubDir/$aVcLib"]
642       if { "$aTbbLibPath" == "" } {
643         # Set the path to the TBB library for Linux
644         if { "$::tcl_platform(platform)" != "windows" } {
645           set aSubDir "$aSubDir/cc4.1.0_libc2.4_kernel2.6.16.21"
646         }
647         set aTbbLibPath [wokdep:SearchLib "tbb" "$anArchIter" "$aPath/lib/$aSubDir"]
648         if { "$aTbbLibPath" != "" } {
649           lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/$aSubDir"
650         }
651       } else {
652         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/$aSubDir/$aVcLib"
653       }
654       if { "$aTbbLibPath" == "" } {
655         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}tbb.${::SYS_LIB_SUFFIX}' not found (Intel TBB)"
656         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
657       }
658     }
659     if { "$::tcl_platform(platform)" == "windows" } {
660       set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter"]
661       if { "$aTbbDllPath" == "" } {
662         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] $aVcLib "$anArchIter" ]
663         set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter" "$aPath/bin/$aSubDir/$aVcLib"]
664         if { "$aTbbDllPath" != "" } {
665           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin/$aSubDir/$aVcLib"
666         } else {
667           lappend anErrBin$anArchIter "Error: 'tbb.dll' not found (Intel TBB)"
668           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
669         }
670       }
671     }
672   }
673
674   return "$isFound"
675 }
676
677 # Search OpenCL library placement
678 proc wokdep:SearchOpenCL {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
679   upvar $theErrInc   anErrInc
680   upvar $theErrLib32 anErrLib32
681   upvar $theErrLib64 anErrLib64
682   upvar $theErrBin32 anErrBin32
683   upvar $theErrBin64 anErrBin64
684
685   set isFound "true"
686   if { "$::tcl_platform(os)" == "Darwin" } {
687     # OpenCL framework available since Mac OS X 16
688     return "$isFound"
689   }
690
691   set aCLHPath [wokdep:SearchHeader "CL/cl_gl.h"]
692   if { "$aCLHPath"  == "" } {
693     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{OpenCL}*] "$::VCVER" "$::ARCH" ]
694     if { "$aPath" != "" && [file exists "$aPath/include/CL/cl_gl.h"] } {
695       lappend ::CSF_OPT_INC "$aPath/include"
696     } else {
697       lappend anErrInc "Error: 'CL/cl_gl.h' not found (OpenCL)"
698       set isFound "false"
699     }
700   }
701
702   foreach anArchIter {64 32} {
703     set aCLLibPath [wokdep:SearchLib "OpenCL" "$anArchIter"]
704     if { "$aCLLibPath" == "" } {
705       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{OpenCL}*] "$::VCVER" "$anArchIter" ]
706       set aCLLibPath [wokdep:SearchLib "OpenCL" "$anArchIter" "$aPath/lib"]
707       if { "$aCLLibPath" != "" } {
708         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
709       } else {
710         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}OpenCL.${::SYS_LIB_SUFFIX}' not found (OpenCL)"
711         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
712       }
713     }
714   }
715
716   return "$isFound"
717 }
718
719 # Search EGL library placement
720 proc wokdep:SearchEGL {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
721   upvar $theErrInc   anErrInc
722   upvar $theErrLib32 anErrLib32
723   upvar $theErrLib64 anErrLib64
724   upvar $theErrBin32 anErrBin32
725   upvar $theErrBin64 anErrBin64
726
727   set isFound "true"
728   set aHeaderPath [wokdep:SearchHeader "EGL/egl.h"]
729   if { "$aHeaderPath"  == "" } {
730     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{EGL}*] "$::VCVER" "$::ARCH" ]
731     if { "$aPath" == "" || ![file exists "$aPath/include/EGL/egl.h"] } {
732       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{angle}*] "$::VCVER" "$::ARCH" ]
733     }
734
735     if { "$aPath" != "" && [file exists "$aPath/include/EGL/egl.h"] } {
736       lappend ::CSF_OPT_INC "$aPath/include"
737     } else {
738       lappend anErrInc "Error: 'EGL/egl.h' not found (EGL)"
739       set isFound "false"
740     }
741   }
742
743   set aLibName "EGL"
744   if { "$::tcl_platform(platform)" == "windows" } {
745     # awkward exception
746     set aLibName "libEGL"
747   }
748
749   foreach anArchIter {64 32} {
750     set aLibPath [wokdep:SearchLib "$aLibName" "$anArchIter"]
751     if { "$aLibPath" == "" } {
752       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{EGL}*] "$::VCVER" "$anArchIter" ]
753       set aLibPath [wokdep:SearchLib "$aLibName" "$anArchIter" "$aPath/lib"]
754       if { "$aLibPath" == "" } {
755         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{angle}*] "$::VCVER" "$anArchIter" ]
756         set aLibPath [wokdep:SearchLib "$aLibName" "$anArchIter" "$aPath/lib"]
757       }
758
759       if { "$aLibPath" != "" } {
760         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
761       } else {
762         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}${aLibName}.${::SYS_LIB_SUFFIX}' not found (EGL)"
763         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
764       }
765     }
766
767     if { "$::tcl_platform(platform)" == "windows" } {
768       set aDllPath [wokdep:SearchBin "libEGL.dll" "$anArchIter"]
769       if { "$aDllPath" == "" } {
770         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{EGL}*] "$::VCVER" "$anArchIter" ]
771         set aDllPath [wokdep:SearchBin "libEGL.dll" "$anArchIter" "$aPath/bin"]
772         if { "$aDllPath" == "" } {
773           set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{angle}*] "$::VCVER" "$anArchIter" ]
774           set aDllPath [wokdep:SearchBin "libEGL.dll" "$anArchIter" "$aPath/bin"]
775         }
776
777         if { "$aDllPath" != "" } {
778           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
779         } else {
780           lappend anErrBin$anArchIter "Error: 'libEGL.dll' not found (EGL)"
781           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
782         }
783       }
784     }
785   }
786
787   return "$isFound"
788 }
789
790 # Search OpenGL ES 2.0 library placement
791 proc wokdep:SearchGLES {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
792   upvar $theErrInc   anErrInc
793   upvar $theErrLib32 anErrLib32
794   upvar $theErrLib64 anErrLib64
795   upvar $theErrBin32 anErrBin32
796   upvar $theErrBin64 anErrBin64
797
798   set isFound "true"
799   set aHeaderPath [wokdep:SearchHeader "GLES2/gl2.h"]
800   if { "$aHeaderPath"  == "" } {
801     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{GLES}*] "$::VCVER" "$::ARCH" ]
802     if { "$aPath" == "" || ![file exists "$aPath/include/GLES2/gl2.h"] } {
803       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{angle}*] "$::VCVER" "$::ARCH" ]
804     }
805
806     if { "$aPath" != "" && [file exists "$aPath/include/GLES2/gl2.h"] } {
807       lappend ::CSF_OPT_INC "$aPath/include"
808     } else {
809       lappend anErrInc "Error: 'GLES2/gl2.h' not found (OpenGL ES 2.0)"
810       set isFound "false"
811     }
812   }
813
814   set aLibName "GLESv2"
815   if { "$::tcl_platform(platform)" == "windows" } {
816     # awkward exception
817     set aLibName "libGLESv2"
818   }
819
820   foreach anArchIter {64 32} {
821     set aLibPath [wokdep:SearchLib "$aLibName" "$anArchIter"]
822     if { "$aLibPath" == "" } {
823       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{GLES}*] "$::VCVER" "$anArchIter" ]
824       set aLibPath [wokdep:SearchLib "$aLibName" "$anArchIter" "$aPath/lib"]
825       if { "$aLibPath" == "" } {
826         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{angle}*] "$::VCVER" "$anArchIter" ]
827         set aLibPath [wokdep:SearchLib "$aLibName" "$anArchIter" "$aPath/lib"]
828       }
829
830       if { "$aLibPath" != "" } {
831         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
832       } else {
833         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}${aLibName}.${::SYS_LIB_SUFFIX}' not found (OpenGL ES 2.0)"
834         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
835       }
836     }
837
838     if { "$::tcl_platform(platform)" == "windows" } {
839       set aDllPath [wokdep:SearchBin "libGLESv2.dll" "$anArchIter"]
840       if { "$aDllPath" == "" } {
841         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{EGL}*] "$::VCVER" "$anArchIter" ]
842         set aDllPath [wokdep:SearchBin "libGLESv2.dll" "$anArchIter" "$aPath/bin"]
843         if { "$aDllPath" == "" } {
844           set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{angle}*] "$::VCVER" "$anArchIter" ]
845           set aDllPath [wokdep:SearchBin "libGLESv2.dll" "$anArchIter" "$aPath/bin"]
846         }
847
848         if { "$aDllPath" != "" } {
849           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
850         } else {
851           lappend anErrBin$anArchIter "Error: 'libGLESv2.dll' not found (OpenGL ES 2.0)"
852           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
853         }
854       }
855     }
856   }
857
858   return "$isFound"
859 }
860
861 # Search RapidJSON headers
862 proc wokdep:SearchRapidJson {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
863   upvar $theErrInc anErrInc
864
865   set isFound "true"
866   set aRJHPath [wokdep:SearchHeader "rapidjson/rapidjson.h"]
867   if { "$aRJHPath"  == "" } {
868     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{rapidjson}*] "$::VCVER" "$::ARCH" ]
869     if { "$aPath" != "" && [file exists "$aPath/include/rapidjson/rapidjson.h"] } {
870       lappend ::CSF_OPT_INC "$aPath/include"
871     } else {
872       lappend anErrInc "Error: 'rapidjson/rapidjson.h' not found (RapidJSON)"
873       set isFound "false"
874     }
875   }
876
877   return "$isFound"
878 }
879
880 # Auxiliary function, gets VTK version to set default search directory
881 proc wokdep:VtkVersion { thePath } {
882   set aResult "6.1"
883
884   set aVtkRoot [lindex [regexp -all -inline {[0-9.]*} [file tail $thePath]] 0]
885   if { "$aVtkRoot" != "" } {
886     set aVtkRoot [regexp -inline {[0-9]*.[0-9]*} $aVtkRoot]
887     if { "$aVtkRoot" != "" } {
888     set aResult $aVtkRoot
889     }
890   }
891
892   return $aResult
893 }
894
895 # Search VTK library placement
896 proc wokdep:SearchVTK {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
897   upvar $theErrInc   anErrInc
898   upvar $theErrLib32 anErrLib32
899   upvar $theErrLib64 anErrLib64
900   upvar $theErrBin32 anErrBin32
901   upvar $theErrBin64 anErrBin64
902
903   set isFound "true"
904   
905   set aVtkPath ""
906   set aVtkIncPath [wokdep:SearchHeader "vtkConfigure.h"]
907   set aVtkVer [wokdep:VtkVersion $aVtkIncPath]
908   if { "$aVtkIncPath" == ""} {
909     set aPathList [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{VTK}*]
910     set aVtkPath [wokdep:Preferred "$aPathList" "$::VCVER" "$::ARCH" ]
911     if { "$aVtkPath" != "" && [file exists "$aVtkPath/include/vtk-[wokdep:VtkVersion $aVtkPath]/vtkConfigure.h"]} { 
912       set aVtkVer [wokdep:VtkVersion $aVtkPath]
913       lappend ::CSF_OPT_INC "$aVtkPath/include/vtk-[wokdep:VtkVersion $aVtkPath]"
914     } else { # try to search in all found paths
915       set isFound "false"
916       foreach anIt $aPathList {
917         if { [file exists "$anIt/include/vtk-[wokdep:VtkVersion $anIt]/vtkConfigure.h"] } {
918           set aVtkPath $anIt
919           set aVtkVer [wokdep:VtkVersion $aVtkPath]
920           lappend ::CSF_OPT_INC "$anIt/include/vtk-[wokdep:VtkVersion $anIt]"
921           set isFound "true"
922           break
923         }
924       }
925
926       # Bad case: we do not found vtkConfigure.h in all paths.
927       if { "$isFound" == "false"} {
928         lappend anErrInc "Error: 'vtkConfigure.h' not found (VTK)"
929         set isFound "false"
930       }
931     }
932   }
933
934   set aVtkLibPath ""
935   foreach anArchIter {64 32} {
936     set aVtkLibPath [wokdep:SearchLib "vtkCommonCore-$aVtkVer" "$anArchIter"]
937     if { "$aVtkLibPath" == "" } {
938       set aPathList [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{VTK}*]
939       set aPath [wokdep:Preferred $aPathList "$::VCVER" "$anArchIter" ]
940       set aVtkLibPath [wokdep:SearchLib "vtkCommonCore-$aVtkVer" "$anArchIter" "$aPath/lib"]
941       if { "$aVtkLibPath" != "" } {
942         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
943       } else {
944         set aPath [wokdep:SearchLib "vtkCommonCore-$aVtkVer" "$anArchIter" "$aVtkPath/lib"]
945         if { "$aPath" != "" } {
946           set aLibPath $aVtkIncPath
947           lappend ::CSF_OPT_LIB$anArchIter "$aLibPath/lib"
948         } else {
949           # The last chance: search /lib directory in all found paths
950           foreach anIt $aPathList {
951             set aVtkLibPath [wokdep:SearchLib "vtkCommonCore-$aVtkVer" "$anArchIter" "$anIt/lib"]
952             if { "$aVtkLibPath" != ""} {
953               lappend ::CSF_OPT_LIB$anArchIter "$anIt/lib"
954               break
955             }
956           }
957           if { "$aVtkLibPath" == "" } {
958             lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}vtkCommonCore-${aVtkVer}\.${::SYS_LIB_SUFFIX}' not found (VTK)"
959             if { "$::ARCH" == "$anArchIter" } {
960               set isFound "false"
961             }
962           }
963         }
964       }
965     }
966   }
967   
968     # Search binary path
969     if { "$::tcl_platform(platform)" == "windows" } {
970       foreach anArchIter {64 32} {
971         set aVtkBinPath [wokdep:SearchBin "vtkCommonCore-${aVtkVer}.dll" "$anArchIter"]
972         if { "$aVtkBinPath" == "" } {
973           set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{VTK}*] "$::VCVER" "$anArchIter" ]
974           set aVtkBinPath [wokdep:SearchBin "vtkCommonCore-${aVtkVer}.dll" "$anArchIter" "$aPath/bin"]
975           if { "$aVtkBinPath" != "" } { lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
976           } else {
977             set aVtkBinPath [wokdep:SearchBin "vtkCommonCore-${aVtkVer}.dll" "$anArchIter" "$aPath/lib"]
978             if { "$aVtkBinPath" != "" } { lappend ::CSF_OPT_BIN$anArchIter "$aPath/lib" } 
979           }
980         }
981       }
982       
983       # We didn't find preferred binary path => search through inc path or among all available VTK directories
984       if { "$aVtkBinPath" == "" } {
985         # Try to find in lib path
986         set aPath [wokdep:SearchBin "vtkCommonCore-${aVtkVer}.dll" "$anArchIter" "$aVtkLibPath/bin"]
987         if { "$aPath" != "" } { lappend ::CSF_OPT_BIN$anArchIter "$aVtkLibPath/bin"
988         } elseif { [wokdep:SearchBin "vtkCommonCore-${aVtkVer}.dll" "$anArchIter" "$aVtkLibPath/lib"] != "" } {
989           lappend ::CSF_OPT_BIN$anArchIter "$aVtkLibPath/lib"
990         } else {
991            lappend anErrBin$anArchIter "Error: 'vtkCommonCore-${aVtkVer}.dll' not found (VTK)"
992            set isFound "false"
993         }
994       }
995     }
996
997   return "$isFound"
998 }
999
1000 # Search Qt4 libraries placement
1001 proc wokdep:SearchQt4 {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
1002   upvar $theErrInc   anErrInc
1003   upvar $theErrLib32 anErrLib32
1004   upvar $theErrLib64 anErrLib64
1005   upvar $theErrBin32 anErrBin32
1006   upvar $theErrBin64 anErrBin64
1007
1008   set isFound "true"
1009   set aQMsgBoxHPath [wokdep:SearchHeader "QtGui/qmessagebox.h"]
1010   if { "$aQMsgBoxHPath" == "" } {
1011     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{qt4}*] "$::VCVER" "$::ARCH" ]
1012     if { "$aPath" != "" && [file exists "$aPath/include/QtGui/qmessagebox.h"] } {
1013       lappend ::CSF_OPT_INC "$aPath/include"
1014       lappend ::CSF_OPT_INC "$aPath/include/Qt"
1015       lappend ::CSF_OPT_INC "$aPath/include/QtGui"
1016       lappend ::CSF_OPT_INC "$aPath/include/QtCore"
1017     } else {
1018       if { [file exists "/usr/include/qt4/QtGui/qmessagebox.h"] } {
1019         lappend ::CSF_OPT_INC "/usr/include/qt4"
1020         lappend ::CSF_OPT_INC "/usr/include/qt4/Qt"
1021         lappend ::CSF_OPT_INC "/usr/include/qt4/QtGui"
1022         lappend ::CSF_OPT_INC "/usr/include/qt4/QtCore"
1023       } else {
1024         lappend anErrInc "Error: 'QtGui/qmessagebox.h' not found (Qt4)"
1025         set isFound "false"
1026       }
1027     }
1028   }
1029
1030   set aQtGuiLibName "QtGui"
1031   if { "$::tcl_platform(platform)" == "windows" } {
1032     set aQtGuiLibName "QtGui4"
1033   }
1034
1035   foreach anArchIter {64 32} {
1036     set aQMsgBoxLibPath [wokdep:SearchLib "${aQtGuiLibName}" "$anArchIter"]
1037     if { "$aQMsgBoxLibPath" == "" } {
1038       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{qt4}*] "$::VCVER" "$anArchIter" ]
1039       set aQMsgBoxLibPath [wokdep:SearchLib "${aQtGuiLibName}" "$anArchIter" "$aPath/lib"]
1040       if { "$aQMsgBoxLibPath" != "" } {
1041         lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
1042       } else {
1043         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}${aQtGuiLibName}.${::SYS_LIB_SUFFIX}' not found (Qt4)"
1044         if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
1045       }
1046     }
1047     if { "$::tcl_platform(platform)" == "windows" } {
1048       set aQMsgBoxDllPath [wokdep:SearchBin "QtGui4.dll" "$anArchIter"]
1049       if { "$aQMsgBoxDllPath" == "" } {
1050         set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{qt4}*] "$::VCVER" "$anArchIter" ]
1051         set aQMsgBoxDllPath [wokdep:SearchBin "QtGui4.dll" "$anArchIter" "$aPath/bin"]
1052         if { "$aQMsgBoxDllPath" != "" } {
1053           lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
1054         } else {
1055           lappend anErrBin$anArchIter "Error: 'QtGui4.dll' not found (Qt4)"
1056           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
1057         }
1058       }
1059     }
1060   }
1061
1062   return "$isFound"
1063 }
1064
1065 # Search JDK placement
1066 proc wokdep:SearchJDK {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
1067   upvar $theErrInc   anErrInc
1068   upvar $theErrLib32 anErrLib32
1069   upvar $theErrLib64 anErrLib64
1070   upvar $theErrBin32 anErrBin32
1071   upvar $theErrBin64 anErrBin64
1072
1073   set isFound "true"
1074   set aJniHPath   [wokdep:SearchHeader "jni.h"]
1075   set aJniMdHPath [wokdep:SearchHeader "jni_md.h"]
1076   if { "$aJniHPath" == "" || "$aJniMdHPath" == "" } {
1077     set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{jdk,java}*] "$::VCVER" "$::ARCH" ]
1078     if { "$aPath" != "" && [file exists "$aPath/include/jni.h"] } {
1079       lappend ::CSF_OPT_INC "$aPath/include"
1080       if { "$::tcl_platform(platform)" == "windows" } {
1081         lappend ::CSF_OPT_INC "$aPath/include/win32"
1082       } elseif { [file exists "$aPath/include/linux"] } {
1083         lappend ::CSF_OPT_INC "$aPath/include/linux"
1084       }
1085     } else {
1086       if { [file exists "/System/Library/Frameworks/JavaVM.framework/Home/include/jni.h"] } {
1087         lappend ::CSF_OPT_INC "/System/Library/Frameworks/JavaVM.framework/Home/include"
1088       } else {
1089         lappend anErrInc "Error: 'jni.h' or 'jni_md.h' not found (JDK)"
1090         set isFound "false"
1091       }
1092     }
1093   }
1094
1095   foreach anArchIter {64 32} {
1096     set aJavacPath [wokdep:SearchBin "javac${::SYS_EXE_SUFFIX}" "$anArchIter"]
1097     if { "$aJavacPath" == "" } {
1098       set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{jdk,java}*] "$::VCVER" "$anArchIter" ]
1099       set aJavacPath [wokdep:SearchBin "javac${::SYS_EXE_SUFFIX}" "$anArchIter" "$aPath/bin"]
1100       if { "$aJavacPath" != "" } {
1101         lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
1102       } else {
1103         if { "$::ARCH" == "$anArchIter" && [file exists "/System/Library/Frameworks/JavaVM.framework/Home/bin/javac${::SYS_EXE_SUFFIX}"] } {
1104           lappend ::CSF_OPT_BIN$anArchIter "/System/Library/Frameworks/JavaVM.framework/Home/bin"
1105         } else {
1106           lappend anErrBin$anArchIter "Error: 'javac${::SYS_EXE_SUFFIX}' not found (JDK)"
1107           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
1108         }
1109       }
1110     }
1111   }
1112
1113   return "$isFound"
1114 }
1115
1116 # Search X11 libraries placement
1117 proc wokdep:SearchX11 {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
1118   upvar $theErrInc   anErrInc
1119   upvar $theErrLib32 anErrLib32
1120   upvar $theErrLib64 anErrLib64
1121   upvar $theErrBin32 anErrBin32
1122   upvar $theErrBin64 anErrBin64
1123
1124   set isFound "true"
1125   if { "$::tcl_platform(platform)" == "windows" || ( "$::tcl_platform(os)" == "Darwin" && "$::MACOSX_USE_GLX" != "true" ) } {
1126     return "$isFound"
1127   }
1128
1129   set aXmuLibPath [wokdep:SearchLib "Xmu" "$::ARCH"]
1130   if { "$aXmuLibPath" == "" } {
1131     set aXmuLibPath [wokdep:SearchLib "Xmu" "$::ARCH" "/usr/X11/lib"]
1132     if { "$aXmuLibPath" != "" } {
1133       #lappend ::CSF_OPT_LIB$::ARCH "/usr/X11/lib"
1134     } else {
1135       lappend anErrLib$::ARCH "Error: '${::SYS_LIB_PREFIX}Xmu.${::SYS_LIB_SUFFIX}' not found (X11)"
1136       set isFound "false"
1137     }
1138   }
1139
1140   return "$isFound"
1141 }
1142
1143 # Returns OCCT version string from file Standard_Version.hxx (if available)
1144 proc wokdep:DetectCasVersion {} {
1145   set occt_ver 7.0.0
1146   set aCasRoot [file normalize [file dirname [info script]]]
1147   set filename "${aCasRoot}/src/Standard/Standard_Version.hxx"
1148   if { [file exists $filename] } {
1149     set fh [open $filename "r"]
1150     set fh_loaded [read $fh]
1151     close $fh
1152     regexp {[^/]\s*#\s*define\s+OCC_VERSION_COMPLETE\s+\"([^\s]*)\"} $fh_loaded dummy occt_ver
1153   } else {
1154     puts "Error: file '$filename' not found"
1155   }
1156   return $occt_ver
1157 }
1158
1159 # Generate (override) custom environment file
1160 proc wokdep:SaveCustom {} {
1161   set aGenInfo "This environment file was generated by genconf.tcl script at [clock format [clock seconds] -format "%Y.%m.%d %H:%M"]"
1162   if { "$::tcl_platform(platform)" == "windows" } {
1163     set aCustomFilePath "./custom.bat"
1164     set aFile [open $aCustomFilePath "w"]
1165     puts $aFile "@echo off"
1166     puts $aFile "rem $aGenInfo"
1167
1168     puts $aFile ""
1169     puts $aFile "set PRJFMT=$::PRJFMT"
1170     puts $aFile "set VCVER=$::VCVER"
1171     puts $aFile "set ARCH=$::ARCH"
1172     puts $aFile "set VCVARS=$::VCVARS"
1173     puts $aFile "set SHORTCUT_HEADERS=$::SHORTCUT_HEADERS"
1174
1175     puts $aFile ""
1176     puts $aFile "set \"PRODUCTS_PATH=$::PRODUCTS_PATH\""
1177
1178     puts $aFile ""
1179     puts $aFile "rem Optional 3rd-parties switches"
1180     foreach anEnvIter $::THE_ENV_VARIABLES {
1181       set aName ${anEnvIter}
1182       set aValue [set ::${anEnvIter}]
1183       if { "$aValue" != "" } {
1184         puts $aFile "set ${aName}=$aValue"
1185       }
1186     }
1187
1188     set aStringInc [join $::CSF_OPT_INC $::SYS_PATH_SPLITTER]
1189     if { "$::PRODUCTS_PATH" != "" } {
1190       set aStringInc [regsub -all "$::PRODUCTS_PATH" $aStringInc "%PRODUCTS_PATH%"]
1191     }
1192     puts $aFile ""
1193     puts $aFile "rem Additional headers search paths"
1194     puts $aFile "set \"CSF_OPT_INC=$aStringInc\""
1195
1196     set aStringLib32 [join $::CSF_OPT_LIB32 $::SYS_PATH_SPLITTER]
1197     if { "$::PRODUCTS_PATH" != "" } {
1198       set aStringLib32 [regsub -all "$::PRODUCTS_PATH" $aStringLib32 "%PRODUCTS_PATH%"]
1199     }
1200     puts $aFile ""
1201     puts $aFile "rem Additional libraries (32-bit) search paths"
1202     puts $aFile "set \"CSF_OPT_LIB32=$aStringLib32\""
1203
1204     set aStringLib64 [join $::CSF_OPT_LIB64 $::SYS_PATH_SPLITTER]
1205     if { "$::PRODUCTS_PATH" != "" } {
1206       set aStringLib64 [regsub -all "$::PRODUCTS_PATH" $aStringLib64 "%PRODUCTS_PATH%"]
1207     }
1208     puts $aFile ""
1209     puts $aFile "rem Additional libraries (64-bit) search paths"
1210     puts $aFile "set \"CSF_OPT_LIB64=$aStringLib64\""
1211
1212     set aStringBin32 [join $::CSF_OPT_BIN32 $::SYS_PATH_SPLITTER]
1213     if { "$::PRODUCTS_PATH" != "" } {
1214       set aStringBin32 [regsub -all "$::PRODUCTS_PATH" $aStringBin32 "%PRODUCTS_PATH%"]
1215     }
1216     puts $aFile ""
1217     puts $aFile "rem Additional (32-bit) search paths"
1218     puts $aFile "set \"CSF_OPT_BIN32=$aStringBin32\""
1219
1220     set aStringBin64 [join $::CSF_OPT_BIN64 $::SYS_PATH_SPLITTER]
1221     if { "$::PRODUCTS_PATH" != "" } {
1222       set aStringBin64 [regsub -all "$::PRODUCTS_PATH" $aStringBin64 "%PRODUCTS_PATH%"]
1223     }
1224     puts $aFile ""
1225     puts $aFile "rem Additional (64-bit) search paths"
1226     puts $aFile "set \"CSF_OPT_BIN64=$aStringBin64\""
1227
1228     close $aFile
1229   } else {
1230     set aCustomFilePath "./custom.sh"
1231     set aFile [open $aCustomFilePath "w"]
1232     puts $aFile "#!/bin/bash"
1233     puts $aFile "# $aGenInfo"
1234
1235     puts $aFile ""
1236     puts $aFile "export PRJFMT=$::PRJFMT"
1237     puts $aFile "export ARCH=$::ARCH"
1238     puts $aFile "export SHORTCUT_HEADERS=$::SHORTCUT_HEADERS"
1239
1240     puts $aFile ""
1241     puts $aFile "export PRODUCTS_PATH=\"$::PRODUCTS_PATH\""
1242
1243     puts $aFile ""
1244     puts $aFile "# Optional 3rd-parties switches"
1245     foreach anEnvIter $::THE_ENV_VARIABLES {
1246       set aName ${anEnvIter}
1247       set aValue [set ::${anEnvIter}]
1248       if { "$aValue" != "" } {
1249         puts $aFile "export ${aName}=${aValue}"
1250       }
1251     }
1252
1253     set aStringInc [join $::CSF_OPT_INC $::SYS_PATH_SPLITTER]
1254     if { "$::PRODUCTS_PATH" != "" } {
1255       set aStringInc [regsub -all "$::PRODUCTS_PATH" $aStringInc "\${PRODUCTS_PATH}"]
1256     }
1257     puts $aFile ""
1258     puts $aFile "# Additional headers search paths"
1259     puts $aFile "export CSF_OPT_INC=\"$aStringInc\""
1260
1261     set aStringLib [join [set ::CSF_OPT_LIB$::ARCH] $::SYS_PATH_SPLITTER]
1262     if { "$::PRODUCTS_PATH" != "" } {
1263       set aStringLib [regsub -all "$::PRODUCTS_PATH" $aStringLib "\${PRODUCTS_PATH}"]
1264     }
1265     puts $aFile ""
1266     puts $aFile "# Additional libraries ($::ARCH-bit) search paths"
1267     puts $aFile "export CSF_OPT_LIB$::ARCH=\"[set aStringLib]\""
1268
1269     set aStringBin [join [set ::CSF_OPT_BIN$::ARCH] $::SYS_PATH_SPLITTER]
1270     if { "$::PRODUCTS_PATH" != "" } {
1271       set aStringBin [regsub -all "$::PRODUCTS_PATH" $aStringBin "\${PRODUCTS_PATH}"]
1272     }
1273     puts $aFile ""
1274     puts $aFile "# Additional ($::ARCH-bit) search paths"
1275     puts $aFile "export CSF_OPT_BIN$::ARCH=\"[set aStringBin]\""
1276
1277     close $aFile
1278   }
1279   puts "Configuration saved to file '$aCustomFilePath'"
1280
1281   # generate custom.auto.pri
1282   set toExportCustomPri 1
1283   if { $toExportCustomPri == 1 } {
1284     set aCasVer [wokdep:DetectCasVersion]
1285     set aCustomFilePath "./adm/qmake/custom.auto.pri"
1286     set aFile [open $aCustomFilePath "w"]
1287     puts $aFile "# $aGenInfo"
1288
1289     puts $aFile ""
1290     puts $aFile "VERSION=$aCasVer"
1291     puts $aFile "PRODUCTS_PATH=\"$::PRODUCTS_PATH\""
1292
1293     puts $aFile ""
1294     puts $aFile "# Optional 3rd-parties switches"
1295     foreach anEnvIter $::THE_ENV_VARIABLES {
1296       set aName ${anEnvIter}
1297       set aValue [set ::${anEnvIter}]
1298       if { "$aValue" == "true" } {
1299         puts $aFile "CONFIG += ${aName}"
1300       } else {
1301         #puts $aFile "CONFIG -= ${aName}"
1302       }
1303     }
1304
1305     puts $aFile ""
1306     puts $aFile "# Additional headers search paths"
1307     foreach anIncPath $::CSF_OPT_INC {
1308       if { "$::PRODUCTS_PATH" != "" } {
1309         set anIncPath [regsub -all "$::PRODUCTS_PATH" $anIncPath "\$\$\{PRODUCTS_PATH\}"]
1310       }
1311       puts $aFile "INCLUDEPATH += \"${anIncPath}\""
1312     }
1313
1314     puts $aFile ""
1315     puts $aFile "# Additional libraries search paths"
1316     foreach aLibPath [set ::CSF_OPT_LIB$::ARCH] {
1317       if { "$::PRODUCTS_PATH" != "" } {
1318         set aLibPath [regsub -all "$::PRODUCTS_PATH" $aLibPath "\$\$\{PRODUCTS_PATH\}"]
1319       }
1320       puts $aFile "LIBS += -L\"${aLibPath}\""
1321     }
1322
1323     if { "$::tcl_platform(platform)" == "windows" } {
1324       puts $aFile ""
1325       puts $aFile "# Additional DLLs search paths"
1326       foreach aDllPath [set ::CSF_OPT_BIN$::ARCH] {
1327         if { "$::PRODUCTS_PATH" != "" } {
1328           set aDllPath [regsub -all "$::PRODUCTS_PATH" $aDllPath "\$\$\{PRODUCTS_PATH\}"]
1329         }
1330         puts $aFile "LIBS += -L\"${aDllPath}\""
1331       }
1332     }
1333
1334     puts $aFile ""
1335     close $aFile
1336     puts "Configuration saved to file '$aCustomFilePath'"
1337   }
1338 }