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