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