0025162: Visualization, TKOpenGl - drop GLU library dependency
[occt.git] / adm / genproj.tcl
1 # =======================================================================
2 # Created on: 2014-07-24
3 # Created by: SKI
4 # Copyright (c) 2014 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 # This script defines Tcl command genproj generating project files for 
19 # different IDEs: 
20 # "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "cbp" "xcd"
21 #
22 # Example:
23 #      genproj -path=D:/occt -target=vc10
24 #      genproj -target=xcd -ios -static
25 # =======================================================================
26
27 source [file join [file dirname [info script]] genconfdeps.tcl]
28
29 set path ""
30 set fBranch ""
31 switch -exact -- "$tcl_platform(platform)" {
32   "windows" {set targetStation "wnt"}
33   "unix"    {set targetStation "lin"}
34 }
35
36 switch -exact -- "$tcl_platform(os)" {
37   "Darwin"  {set targetStation "mac"}
38 }
39
40 proc _get_options { platform type branch } {
41   global path
42   set res ""
43   if {[file exists "$path/adm/CMPLRS"]} {
44     set fd [open "$path/adm/CMPLRS" rb]
45     set opts [split [read $fd] "\n"]
46     close $fd
47     foreach line $opts {
48       if {[regexp "^${platform} ${type} ${branch} (.+)$" $line dummy res]} {
49         while {[regexp {\(([^\(\)]+) ([^\(\)]+) ([^\(\)]+)\)(.+)} $res dummy p t b oldres]} {
50           set res "[_get_options $p $t $b] $oldres"
51         }
52       }
53     }
54   }
55   return $res
56 }
57
58 proc _get_type { name } {
59   global path
60   if {[file exists "$path/adm/UDLIST"]} {
61     set fd [open "$path/adm/UDLIST" rb]
62     set UDLIST [split [read $fd] "\n"]
63     close $fd
64     foreach uitem $UDLIST {
65       set line [split $uitem]
66       if {[lindex $line 1] == "$name"} {
67         return [lindex $line 0]
68       }
69     }
70   }
71   return ""
72 }
73
74 proc _get_used_files { pk {inc true} {src true} } {
75   global path
76   set type [_get_type $pk]
77   set lret {}
78   set pk_path  "$path/src/$pk"
79   set FILES_path "$path/src/$pk/FILES"
80   set FILES {}
81   if {[file exists $FILES_path]} {
82     set fd [open $FILES_path rb]
83     set FILES [split [read $fd] "\n"]
84     close $fd
85   }
86   set FILES [lsearch -inline -all -not -exact $FILES ""]
87
88   set index -1
89   foreach line $FILES {
90     incr index
91     if {$inc && ([regexp {([^:\s]*\.[hgl]xx)$} $line dummy name] || [regexp {([^:\s]*\.h)$} $line dummy name]) && [file exists $pk_path/$name]} {
92       lappend lret "pubinclude $name $pk_path/$name"
93       continue
94     }
95     if {[regexp {:} $line]} {
96       regexp {[^:]*:+([^\s]*)} $line dummy line
97     }
98     regexp {([^\s]*)} $line dummy line
99     if {$src && [file exists $pk_path/$line]} {
100       lappend lret "source $line $pk_path/$line"
101     }
102   }
103   return $lret
104 }
105
106 # Wrapper-function to generate VS project files
107 proc genproj { args } {
108   global path targetStation
109   set aSupportedTargets { "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "cbp" "xcd" }
110   set anArgs $args
111
112   # Setting default IDE.
113   set anTarget ""
114   switch -exact -- "$targetStation" {
115     "wnt"   {set anTarget "$::env(VCVER)"}
116     "lin"   {set anTarget "cbp"}
117     "mac"   {set anTarget "xcd"}
118   }
119
120   set isTargetDefault true
121   if { [set anIndex [lsearch -nocase $anArgs -target=*]] != -1 } {
122     regsub -nocase "\\-target=" [lindex $anArgs $anIndex] "" anTarget
123     set anArgs [removeAllOccurrencesOf -target=* $anArgs]
124     set isTargetDefault false
125   }
126
127   if { [set anIndex [lsearch -nocase $anArgs -path=*]] != -1} {
128     regsub -nocase "\\-path=" [lindex $anArgs $anIndex] "" path
129     set anArgs [removeAllOccurrencesOf -path=* $anArgs]
130     puts "Starting work with \"$path\""
131   }
132
133   if { [llength $anArgs] == 0 && $isTargetDefault == true } {
134     puts "the default \'$anTarget\' target has been applied"
135   }
136
137   set isHelpRequire false
138   if { [lsearch -nocase $anArgs -h] != -1} {
139     set anArgs [removeAllOccurrencesOf -h $anArgs]
140     set isHelpRequire true
141   }
142
143   if {$path == ""} {
144     set isHelpRequire true
145   }
146
147   set aLibType "dynamic"
148   if { [lsearch -nocase $anArgs "-static"] != -1} {
149     set anArgs [removeAllOccurrencesOf "-static" $anArgs]
150     set aLibType "static"
151     puts "static build has been selected"
152   } elseif { [lsearch -nocase $anArgs "-dynamic"] != -1} {
153     set anArgs [removeAllOccurrencesOf "-dynamic" $anArgs]
154     set aLibType "dynamic"
155     puts "dynamic build has been selected"
156   }
157
158   set aPlatform ""
159   if { [lsearch -nocase $anArgs "-ios"] != -1} {
160     set anArgs [removeAllOccurrencesOf "-ios" $anArgs]
161     set aPlatform "ios"
162   }
163
164   if { [lsearch -nocase $aSupportedTargets $anTarget] == -1} {
165     puts "the \'$anTarget\' is wrong TARGET"
166     set isHelpRequire true
167   }
168
169   if {[llength $anArgs] > 0} {
170     set isHelpRequire true
171
172     foreach anArg $anArgs {
173       puts "genproj: unrecognized option \'$anArg\'"
174     }
175   }
176
177   if {  $isHelpRequire == true } {
178     puts "usage: genproj \[ -target=<TARGET> \] \[ -path=<PATH> \]
179
180     PATH: 
181       path to the project
182
183     TARGET:
184       vc8   -  Visual Studio 2005
185       vc9   -  Visual Studio 2008
186       vc10  -  Visual Studio 2010
187       vc11  -  Visual Studio 2012
188       vc12  -  Visual Studio 2013
189       vc14  -  Visual Studio 2015
190       cbp   -  CodeBlocks
191       xcd   -  XCode"
192       return
193   }
194
195   if {!$isTargetDefault} {
196     puts "the \'$anTarget\' target has been applied"
197   }
198
199   set anAdmPath "$path/adm"
200
201   OS:MKPRC "$anAdmPath" "$anTarget" "$aLibType" "$aPlatform"
202
203   genprojbat "$anAdmPath" "$anTarget"
204 }
205
206 proc genprojbat {thePath theIDE} {
207   global path
208   
209   set anOsIncPath "$path/src/OS"
210   set anOsRootPath "$path"
211
212   set aTargetPlatform "lin"
213   if { "$::tcl_platform(platform)" == "windows" } {
214     set aTargetPlatform "wnt"
215   }
216   
217   if {[regexp {(vc)[0-9]*$} $theIDE] == 1} {
218     set aTargetPlatform wnt
219   } elseif {"$theIDE" == "xcd"} {
220     set aTargetPlatform mac
221   }
222
223   set aTargetPlatformExt sh
224   if { "$aTargetPlatform" == "wnt" } {
225     set aTargetPlatformExt bat
226   }
227
228   set aBox [file normalize "$thePath/.."]
229
230   if {"$theIDE" != "cmake"} {
231     set anEnvTmplFile [open "$path/adm/templates/env.${aTargetPlatformExt}" "r"]
232     set anEnvTmpl [read $anEnvTmplFile]
233     close $anEnvTmplFile
234
235     set aCasRoot ""
236     if { [file normalize "$anOsRootPath"] != "$aBox" } {
237       set aCasRoot [relativePath "$aBox" "$anOsRootPath"]
238     }
239     set anOsIncPath [relativePath "$aBox" "$anOsRootPath"]
240
241     regsub -all -- {__CASROOT__}   $anEnvTmpl "$aCasRoot" anEnvTmpl
242
243     set anEnvFile [open "$aBox/env.${aTargetPlatformExt}" "w"]
244     puts $anEnvFile $anEnvTmpl
245     close $anEnvFile
246
247     file copy -force -- "$path/adm/templates/draw.${aTargetPlatformExt}" "$aBox/draw.${aTargetPlatformExt}"
248   }
249
250   if {[regexp {(vc)[0-9]*$} $theIDE] == 1} {
251     file copy -force -- "$path/adm/templates/msvc.bat" "$aBox/msvc.bat"
252   } else {
253     switch -exact -- "$theIDE" {
254       "cbp"   { file copy -force -- "$path/adm/templates/codeblocks.sh" "$aBox/codeblocks.sh" }
255       "xcd"   { file copy -force -- "$path/adm/templates/xcode.sh"      "$aBox/xcode.sh" }
256     }
257   }
258 }
259
260 ###### MSVC #############################################################33
261 proc removeAllOccurrencesOf { theObject theList } {
262   set aSortIndices [lsort -decreasing [lsearch -all -nocase $theList $theObject]]
263   foreach anIndex $aSortIndices {
264     set theList [lreplace $theList $anIndex $anIndex]
265   }
266   return $theList
267 }
268
269 set aTKNullKey "TKNull"
270 set THE_GUIDS_LIST($aTKNullKey) "{00000000-0000-0000-0000-000000000000}"
271
272 # Entry function to generate project files and solutions for IDE
273 proc OS:MKPRC { {theOutDir {}} {theIDE ""} {theLibType "dynamic"} {thePlatform ""} } {
274   global path targetStation
275   set aSupportedIDE { "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "cbp" "xcd" }
276
277   if { [lsearch $aSupportedIDE $theIDE] < 0 } {
278     puts stderr "WOK does not support generation of project files for the selected IDE: $theIDE\nSupported IDEs: [join ${aSupportedIDE} " "]"
279     return
280   }
281   
282   set anOutRoot $theOutDir
283   if { $anOutRoot == "" } {
284     error "Error : \"theOutDir\" is not initialized"
285   }
286
287   # Create output directory
288   set aWokStation "$targetStation"
289
290   if { [lsearch -exact {vc7 vc8 vc9 vc10 vc11 vc12 vc14} $theIDE] != -1 } {
291     set aWokStation "msvc"
292   }
293
294   set anOutDir "${anOutRoot}/${aWokStation}/${theIDE}"
295
296   # read map of already generated GUIDs
297   set aGuidsFilePath [file join $anOutDir "wok_${theIDE}_guids.txt"]
298   if [file exists "$aGuidsFilePath"] {
299     set aFileIn [open "$aGuidsFilePath" r]
300     set aFileDataRaw [read $aFileIn]
301     close $aFileIn
302     set aFileData [split $aFileDataRaw "\n"]
303     foreach aLine $aFileData {
304       set aLineSplt [split $aLine "="]
305       if { [llength $aLineSplt] == 2 } {
306         set ::THE_GUIDS_LIST([lindex $aLineSplt 0]) [lindex $aLineSplt 1]
307       }
308     }
309   }
310
311   # make list of modules and platforms
312   set aModules [OS:init]
313   if { "$thePlatform" == "ios" } {
314     set goaway [list Draw]
315     set aModules [osutils:juststation $goaway $aModules]
316   }
317
318   # generate one solution for all projects if complete OS or VAS is processed
319   set anAllSolution "OCCT"
320
321   wokUtils:FILES:mkdir $anOutDir
322   if { ![file exists $anOutDir] } {
323     puts stderr "Error: Could not create output directory \"$anOutDir\""
324     return
325   }
326
327   # create the out dir if it does not exist
328   if (![file isdirectory $path/inc]) {
329     puts "$path/inc folder does not exists and will be created"
330     wokUtils:FILES:mkdir $path/inc
331   }
332
333   # collect all required header files
334   puts "Collecting required header files into $path/inc ..."
335   osutils:collectinc $aModules $path/inc $targetStation
336
337   # Generating project files for the selected IDE
338   switch -exact -- "$theIDE" {
339     "vc7"   -
340     "vc8"   -
341     "vc9"   -
342     "vc10"   -
343     "vc11"   -
344     "vc12"   -
345     "vc14"  { OS:MKVC  $anOutDir $aModules $anAllSolution $theIDE }
346     "cbp"   { OS:MKCBP $anOutDir $aModules $anAllSolution }
347     "xcd"   {
348       set ::THE_GUIDS_LIST($::aTKNullKey) "000000000000000000000000"
349       OS:MKXCD $anOutDir $aModules $anAllSolution $theLibType $thePlatform
350     }
351   }
352
353   # Store generated GUIDs map
354   set anOutFile [open "$aGuidsFilePath" "w"]
355   fconfigure $anOutFile -translation lf
356   foreach aKey [array names ::THE_GUIDS_LIST] {
357     set aValue $::THE_GUIDS_LIST($aKey)
358     puts $anOutFile "${aKey}=${aValue}"
359   }
360   close $anOutFile
361 }
362
363 # Function to generate Visual Studio solution and project files
364 proc OS:MKVC { theOutDir {theModules {}} {theAllSolution ""} {theVcVer "vc8"} } {
365
366   puts stderr "Generating VS project files for $theVcVer"
367
368   # generate projects for toolkits and separate solution for each module
369   foreach aModule $theModules {
370     OS:vcsolution $theVcVer $aModule $aModule $theOutDir ::THE_GUIDS_LIST
371     OS:vcproj     $theVcVer $aModule          $theOutDir ::THE_GUIDS_LIST
372   }
373
374   # generate single solution "OCCT" containing projects from all modules
375   if { "$theAllSolution" != "" } {
376     OS:vcsolution $theVcVer $theAllSolution $theModules $theOutDir ::THE_GUIDS_LIST
377   }
378
379   puts "The Visual Studio solution and project files are stored in the $theOutDir directory"
380 }
381
382 proc OS:init {{os {}}} {
383     global path
384     global env
385     global tcl_platform
386     
387     set askplat $os
388     if { "$os" == "" } {
389       set os $tcl_platform(os)
390     }
391
392     ;# Load list of OCCT modules and their definitions
393     source "$path/src/OS/Modules.tcl"
394     set Modules {}
395     foreach module [OS:Modules] {
396         set f "$path/src/OS/${module}.tcl"
397         if [file exists $f] {
398             source $f
399             lappend Modules $module
400         } else {
401             puts stderr "Definition file for module $module is not found in unit OS"
402         }
403     }
404
405     # Load list of products and their definitions
406 #    set Products [woklocate -p VAS:source:Products.tcl]
407     #if { "$Products" != "" } {
408         #source "$Products"
409         #foreach product [VAS:Products] {
410             #set f [woklocate -p VAS:source:${product}.tcl]
411             #if [file exists $f] {
412                 #source $f
413             #} else {
414                 #puts stderr "Definition file for product $product is not found in unit VAS"
415             #}
416         #}
417     #}
418
419     return $Modules
420 }
421
422 # topological sort. returns a list {  {a h} {b g} {c f} {c h} {d i}  } => { d a b c i g f h }
423 proc wokUtils:EASY:tsort { listofpairs } {
424     foreach x $listofpairs {
425         set e1 [lindex $x 0]
426         set e2 [lindex $x 1]
427         if ![info exists pcnt($e1)] {
428             set pcnt($e1) 0
429         }
430         if ![ info exists pcnt($e2)] {
431             set pcnt($e2) 1
432         } else {
433             incr pcnt($e2)
434         }
435         if ![info exists scnt($e1)] {
436             set scnt($e1) 1
437         } else {
438             incr scnt($e1)
439         }
440         set l {}
441         if [info exists slist($e1)] {
442             set l $slist($e1)
443         }
444         lappend l $e2
445         set slist($e1) $l
446     }
447     set nodecnt 0
448     set back 0
449     foreach node [array names pcnt] {
450         incr nodecnt
451         if { $pcnt($node) == 0 } {
452             incr back
453             set q($back) $node
454         }
455         if ![info exists scnt($node)] {
456             set scnt($node) 0
457         }
458     }
459     set res {}
460     for {set front 1} { $front <= $back } { incr front } {
461         lappend res [set node $q($front)]
462         for {set i 1} {$i <= $scnt($node) } { incr i } {
463             set ll $slist($node)
464             set j [expr {$i - 1}]
465             set u [expr { $pcnt([lindex $ll $j]) - 1 }]
466             if { [set pcnt([lindex $ll $j]) $u] == 0 } {
467                 incr back
468                 set q($back) [lindex $ll $j]
469             }
470         }
471     }
472     if { $back != $nodecnt } {
473         puts stderr "input contains a cycle"
474         return {}
475     } else {
476         return $res
477     }
478 }
479
480 proc wokUtils:LIST:Purge { l } {
481     set r {}
482      foreach e $l {
483          if ![info exist tab($e)] {
484              lappend r $e
485              set tab($e) {}
486          } 
487      }
488      return $r
489 }
490
491 # Read file pointed to by path
492 # 1. sort = 1 tri 
493 # 2. trim = 1 plusieurs blancs => 1 seul blanc
494 # 3. purge= not yet implemented.
495 # 4. emptl= dont process blank lines
496 proc wokUtils:FILES:FileToList { path {sort 0} {trim 0} {purge 0} {emptl 1} } {
497     if ![ catch { set id [ open $path r ] } ] {
498         set l  {}
499         while {[gets $id line] >= 0 } {
500             if { $trim } {
501                 regsub -all {[ ]+} $line " " line
502             }
503             if { $emptl } {
504                 if { [string length ${line}] != 0 } {
505                     lappend l $line
506                 }
507             } else {
508                 lappend l $line
509             }
510         }
511         close $id
512         if { $sort } {
513             return [lsort $l]
514         } else {
515             return $l
516         }
517     } else {
518         return {}
519     }
520 }
521
522 # retorn the list of executables in module.
523 proc OS:executable { module } {
524     set lret {}
525     foreach XXX  [${module}:ressources] {
526         if { "[lindex $XXX 1]" == "x" } {
527             lappend lret [lindex $XXX 2]
528         }
529     }
530     return $lret
531 }
532
533 # Topological sort of toolkits in tklm
534 proc osutils:tk:sort { tklm } {
535   set tkby2 {}
536   foreach tkloc $tklm {
537     set lprg [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
538     foreach tkx  $lprg {
539       if { [lsearch $tklm $tkx] != -1 } {
540         lappend tkby2 [list $tkx $tkloc]
541       } else {
542         lappend tkby2 [list $tkloc {}]
543       }
544     }
545   }
546   set lret {}
547   foreach e [wokUtils:EASY:tsort $tkby2] {
548     if { $e != {} } {
549       lappend lret $e
550     }
551   }
552   return $lret
553 }
554
555 #  close dependencies of ltk. (full wok pathes of toolkits)
556 # The CURRENT WOK LOCATION MUST contains ALL TOOLKITS required.
557 # (locate not performed.)
558 proc osutils:tk:close { ltk } {
559   set result {}
560   set recurse {}
561   foreach dir $ltk {
562     set ids [LibToLink $dir]
563     set eated [osutils:tk:eatpk $ids]
564     set result [concat $result $eated]
565     set ids [LibToLink $dir]
566     set result [concat $result $ids]
567
568     foreach file $eated {
569       set kds "$path/src/$file/EXTERNLIB"
570       if { [osutils:tk:eatpk $kds] !=  {} } {
571         lappend recurse $file
572       }
573     }
574   }
575   if { $recurse != {} } {
576     set result [concat $result [osutils:tk:close $recurse]]
577   }
578   return $result
579 }
580
581 proc osutils:tk:eatpk { EXTERNLIB  } {
582   set l [wokUtils:FILES:FileToList $EXTERNLIB]
583   set lret  {}
584   foreach str $l {
585     if ![regexp -- {(CSF_[^ ]*)} $str csf] {
586       lappend lret $str
587     }
588   }
589   return $lret
590 }
591 # Define libraries to link using only EXTERNLIB file
592
593 proc LibToLink {theTKit} {
594   global path
595   regexp {^.*:([^:]+)$} $theTKit dummy theTKit
596   set type [_get_type $theTKit]
597   if {$type != "t" && $type != "x"} {
598     return
599   }
600   set aToolkits {}
601   set anExtLibList [osutils:tk:eatpk "$path/src/$theTKit/EXTERNLIB"]
602   foreach anExtLib $anExtLibList {
603     set aFullPath [LocateRecur $anExtLib]
604     if { "$aFullPath" != "" && [_get_type $anExtLib] == "t" } {
605       lappend aToolkits $anExtLib
606     }
607   }
608   return $aToolkits
609 }
610 # Search unit recursively
611
612 proc LocateRecur {theName} {
613   global path
614   set theNamePath "$path/src/$theName"
615   if {[file isdirectory $theNamePath]} {
616     return $theNamePath
617   }
618   return ""
619 }
620
621 proc OS:genGUID { {theIDE "vc"} } {
622   if { "$theIDE" == "vc" } {
623     set p1 "[format %07X [expr { int(rand() * 268435456) }]][format %X [expr { int(rand() * 16) }]]"
624     set p2 "[format %04X [expr { int(rand() * 6536) }]]"
625     set p3 "[format %04X [expr { int(rand() * 6536) }]]"
626     set p4 "[format %04X [expr { int(rand() * 6536) }]]"
627     set p5 "[format %06X [expr { int(rand() * 16777216) }]][format %06X [expr { int(rand() * 16777216) }]]"
628     return "{$p1-$p2-$p3-$p4-$p5}"
629   } else {
630     set p1 "[format %04X [expr { int(rand() * 6536) }]]"
631     set p2 "[format %04X [expr { int(rand() * 6536) }]]"
632     set p3 "[format %04X [expr { int(rand() * 6536) }]]"
633     set p4 "[format %04X [expr { int(rand() * 6536) }]]"
634     set p5 "[format %04X [expr { int(rand() * 6536) }]]"
635     set p6 "[format %04X [expr { int(rand() * 6536) }]]"
636     return "$p1$p2$p3$p4$p5$p6"
637   }
638 }
639
640 # collect all include file that required for theModules in theOutDir
641 proc osutils:collectinc {theModules theIncPath theTargetStation} {
642   global path
643
644   set aCasRoot [file normalize $path]
645   set anIncPath [file normalize $theIncPath]
646
647   if {![file isdirectory $aCasRoot]} {
648     puts "OCCT directory is not defined correctly: $aCasRoot"
649     return
650   }
651
652   set anUsedToolKits {}
653   foreach aModule $theModules {
654     foreach aToolKit [${aModule}:toolkits] {
655       lappend anUsedToolKits $aToolKit
656
657       foreach aDependency [LibToLink $aToolKit] {
658         lappend anUsedToolKits $aDependency
659       }
660     }
661     foreach anExecutable [OS:executable ${aModule}] {
662       lappend anUsedToolKits $anExecutable
663
664       foreach aDependency [LibToLink $anExecutable] {
665         lappend anUsedToolKits $aDependency
666       }
667     }
668   }
669   lsort -unique $anUsedToolKits
670
671   set anUnits {}
672   foreach anUsedToolKit $anUsedToolKits {
673     set anUnits [concat $anUnits [osutils:tk:units $anUsedToolKit]]
674   }
675   lsort -unique $anUnits
676
677   if { [info exists ::env(SHORTCUT_HEADERS)] && 
678        $::env(SHORTCUT_HEADERS) == "true" } {
679     # template preparation
680     if { ![file exists $aCasRoot/adm/templates/header.in] } {
681       puts "template file does not exist: $aCasRoot/adm/templates/header.in"
682       return
683     }
684     set aHeaderTmpl [wokUtils:FILES:FileToString $aCasRoot/adm/templates/header.in]
685
686     # relative anIncPath in connection with aCasRoot/src
687     set aFromBuildIncToSrcPath [relativePath "$anIncPath" "$aCasRoot/src"]
688
689     # create and copy short-cut header files
690     foreach anUnit $anUnits {
691       set aHFiles [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.h"]
692       foreach aHeaderFile [concat [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.\[hgl\]xx"] $aHFiles] {
693         set aHeaderFileName [file tail $aHeaderFile]
694
695         regsub -all -- {@OCCT_HEADER_FILE@} $aHeaderTmpl "$aFromBuildIncToSrcPath/$anUnit/$aHeaderFileName" aShortCutHeaderFileContent
696
697         if {[file exists "$theIncPath/$aHeaderFileName"] && [file readable "$theIncPath/$aHeaderFileName"]} {
698           set fp [open "$theIncPath/$aHeaderFileName" r]
699           set aHeaderContent [read $fp]
700           close $fp
701
702           # minus eof
703           set aHeaderLenght  [expr [string length $aHeaderContent] - 1]
704
705           if {$aHeaderLenght == [string length $aShortCutHeaderFileContent]} {
706             # remove eof from string
707             set aHeaderContent [string range $aHeaderContent 0 [expr $aHeaderLenght - 1]]
708
709             if {[string compare $aShortCutHeaderFileContent $aHeaderContent] == 0} {
710               continue
711             }
712           }
713         }
714
715         set aShortCutHeaderFile [open "$theIncPath/$aHeaderFileName" "w"]
716         fconfigure $aShortCutHeaderFile -translation lf
717         puts $aShortCutHeaderFile $aShortCutHeaderFileContent
718         close $aShortCutHeaderFile
719       }
720     }  
721   } else {
722     set nbcopied 0
723     foreach anUnit $anUnits {
724       set aHFiles [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.h"]
725       foreach aHeaderFile [concat [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.\[hgl\]xx"] $aHFiles] {
726         set aHeaderFileName [file tail $aHeaderFile]
727
728         # copy file only if target does not exist or is older than original
729         set torig [file mtime $aHeaderFile]
730         if { ! [file isfile $anIncPath/$aHeaderFileName] } {
731           set tcopy 0
732         } else {
733           set tcopy [file mtime $anIncPath/$aHeaderFileName]
734         }
735         if { $tcopy < $torig } {
736           incr nbcopied
737           file copy -force $aHeaderFile $anIncPath/$aHeaderFileName
738         } elseif { $tcopy != $torig } {
739           puts "Warning: file $anIncPath/$aHeaderFileName is newer than $aHeaderFile, not changed!"
740         }
741       }
742     }
743     puts "Info: $nbcopied files updated"
744   }
745 }
746
747 # Generate header for VS solution file
748 proc osutils:vcsolution:header { vcversion } {
749   if { "$vcversion" == "vc7" } {
750     append var \
751       "Microsoft Visual Studio Solution File, Format Version 8.00\n"
752   } elseif { "$vcversion" == "vc8" } {
753     append var \
754       "Microsoft Visual Studio Solution File, Format Version 9.00\n" \
755       "# Visual Studio 2005\n"
756   } elseif { "$vcversion" == "vc9" } {
757     append var \
758       "Microsoft Visual Studio Solution File, Format Version 10.00\n" \
759       "# Visual Studio 2008\n"
760   } elseif { "$vcversion" == "vc10" } {
761     append var \
762       "Microsoft Visual Studio Solution File, Format Version 11.00\n" \
763       "# Visual Studio 2010\n"
764   } elseif { "$vcversion" == "vc11" } {
765     append var \
766       "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
767       "# Visual Studio 2012\n"
768   } elseif { "$vcversion" == "vc12" } {
769     append var \
770       "Microsoft Visual Studio Solution File, Format Version 13.00\n" \
771       "# Visual Studio 2013\n"
772   } elseif { "$vcversion" == "vc14" } {
773     append var \
774       "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
775       "# Visual Studio 14\n"
776   } else {
777     puts stderr "Error: Visual Studio version $vcversion is not supported by this function!"
778   }
779   return $var
780 }
781 # Returns extension (without dot) for project files of given version of VC
782
783 proc osutils:vcproj:ext { vcversion } {
784   if { "$vcversion" == "vc7" || "$vcversion" == "vc8" || "$vcversion" == "vc9" } {
785     return "vcproj"
786   } else {
787     return "vcxproj"
788   }
789 }
790 # Generate start of configuration section of VS solution file
791
792 proc osutils:vcsolution:config:begin { vcversion } {
793   if { "$vcversion" == "vc7" } {
794     append var \
795       "Global\n" \
796       "\tGlobalSection(SolutionConfiguration) = preSolution\n" \
797       "\t\tDebug = Debug\n" \
798       "\t\tRelease = Release\n" \
799       "\tEndGlobalSection\n" \
800       "\tGlobalSection(ProjectConfiguration) = postSolution\n"
801   } else {
802     append var \
803       "Global\n" \
804       "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" \
805       "\t\tDebug|Win32 = Debug|Win32\n" \
806       "\t\tRelease|Win32 = Release|Win32\n" \
807       "\t\tDebug|x64 = Debug|x64\n" \
808       "\t\tRelease|x64 = Release|x64\n" \
809       "\tEndGlobalSection\n" \
810       "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"
811   }
812   return $var
813 }
814 # Generate part of configuration section of VS solution file describing one project
815
816 proc osutils:vcsolution:config:project { vcversion guid } {
817   if { "$vcversion" == "vc7" } {
818     append var \
819       "\t\t$guid.Debug.ActiveCfg = Debug|Win32\n" \
820       "\t\t$guid.Debug.Build.0 = Debug|Win32\n" \
821       "\t\t$guid.Release.ActiveCfg = Release|Win32\n" \
822       "\t\t$guid.Release.Build.0 = Release|Win32\n"
823   } else {
824     append var \
825       "\t\t$guid.Debug|Win32.ActiveCfg = Debug|Win32\n" \
826       "\t\t$guid.Debug|Win32.Build.0 = Debug|Win32\n" \
827       "\t\t$guid.Release|Win32.ActiveCfg = Release|Win32\n" \
828       "\t\t$guid.Release|Win32.Build.0 = Release|Win32\n" \
829       "\t\t$guid.Debug|x64.ActiveCfg = Debug|x64\n" \
830       "\t\t$guid.Debug|x64.Build.0 = Debug|x64\n" \
831       "\t\t$guid.Release|x64.ActiveCfg = Release|x64\n" \
832       "\t\t$guid.Release|x64.Build.0 = Release|x64\n"
833   }
834   return $var
835 }
836 # Generate start of configuration section of VS solution file
837
838 proc osutils:vcsolution:config:end { vcversion } {
839   if { "$vcversion" == "vc7" } {
840     append var \
841       "\tEndGlobalSection\n" \
842       "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" \
843       "\tEndGlobalSection\n" \
844       "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" \
845       "\tEndGlobalSection\n"
846   } else {
847     append var \
848       "\tEndGlobalSection\n" \
849       "\tGlobalSection(SolutionProperties) = preSolution\n" \
850       "\t\tHideSolutionNode = FALSE\n" \
851       "\tEndGlobalSection\n"
852   }
853   return $var
854 }
855 # generate Visual Studio solution file
856 # if module is empty, generates one solution for all known modules
857
858 proc OS:vcsolution { theVcVer theSolName theModules theOutDir theGuidsMap } {
859   global path
860   upvar $theGuidsMap aGuidsMap
861
862   # collect list of projects to be created
863   set aProjects {}
864   set aDependencies {}
865   foreach aModule $theModules {
866     # toolkits
867     foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
868       lappend aProjects $aToolKit
869       lappend aProjectsInModule($aModule) $aToolKit
870       lappend aDependencies [LibToLink $aToolKit]
871     }
872     # executables, assume one project per cxx file...
873     foreach aUnit [OS:executable ${aModule}] {
874       set aUnitLoc $aUnit
875       set src_files [_get_used_files $aUnit false]
876       set aSrcFiles {}
877       foreach s $src_files {
878         regexp {source ([^\s]+)} $s dummy name
879         lappend aSrcFiles $name
880       }
881       foreach aSrcFile $aSrcFiles {
882         set aFileExtension [file extension $aSrcFile]
883         if { $aFileExtension == ".cxx" } {
884           set aPrjName [file rootname $aSrcFile]
885           lappend aProjects $aPrjName
886           lappend aProjectsInModule($aModule) $aPrjName
887           if {[file isdirectory $path/src/$aUnitLoc]} {
888             lappend aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
889           } else {
890             lappend aDependencies {}
891           }
892         }
893       }
894     }
895   }
896
897 # generate GUIDs for projects (unless already known)
898   foreach aProject $aProjects {
899     if { ! [info exists aGuidsMap($aProject)] } {
900       set aGuidsMap($aProject) [OS:genGUID]
901     }
902   }
903
904   # generate solution file
905 #  puts "Generating Visual Studio ($theVcVer) solution file for $theSolName ($aProjects)"
906   append aFileBuff [osutils:vcsolution:header $theVcVer]
907
908   # GUID identifying group projects in Visual Studio
909   set VC_GROUP_GUID "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"
910
911   # generate group projects -- one per module
912   if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
913     foreach aModule $theModules {
914       if { ! [info exists aGuidsMap(_$aModule)] } {
915         set aGuidsMap(_$aModule) [OS:genGUID]
916       }
917       set aGuid $aGuidsMap(_$aModule)
918       append aFileBuff "Project(\"${VC_GROUP_GUID}\") = \"$aModule\", \"$aModule\", \"$aGuid\"\nEndProject\n"
919     }
920   }
921
922   # extension of project files
923   set aProjExt [osutils:vcproj:ext $theVcVer]
924
925   # GUID identifying C++ projects in Visual Studio
926   set VC_CPP_GUID "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
927
928   # generate normal projects
929   set aProjsNb [llength $aProjects]
930   for {set aProjId 0} {$aProjId < $aProjsNb} {incr aProjId} {
931     set aProj [lindex $aProjects $aProjId]
932     set aGuid $aGuidsMap($aProj)
933     append aFileBuff "Project(\"${VC_CPP_GUID}\") = \"$aProj\", \"$aProj.${aProjExt}\", \"$aGuid\"\n"
934     # write projects dependencies information (vc7 to vc9)
935     set aDepGuids ""
936     foreach aDepLib [lindex $aDependencies $aProjId] {
937       if { $aDepLib != $aProj && [lsearch $aProjects $aDepLib] != "-1" } {
938         set depGUID $aGuidsMap($aDepLib)
939         append aDepGuids "\t\t$depGUID = $depGUID\n"
940       }
941     }
942     if { "$aDepGuids" != "" } {
943       append aFileBuff "\tProjectSection(ProjectDependencies) = postProject\n"
944       append aFileBuff "$aDepGuids"
945       append aFileBuff "\tEndProjectSection\n"
946     }
947     append aFileBuff "EndProject\n"
948   }
949
950   # generate configuration section
951   append aFileBuff [osutils:vcsolution:config:begin $theVcVer]
952   foreach aProj $aProjects {
953     append aFileBuff [osutils:vcsolution:config:project $theVcVer $aGuidsMap($aProj)]
954   }
955   append aFileBuff [osutils:vcsolution:config:end $theVcVer]
956
957   # write information of grouping of projects by module
958   if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
959     append aFileBuff "  GlobalSection(NestedProjects) = preSolution\n"
960     foreach aModule $theModules {
961       if { ! [info exists aProjectsInModule($aModule)] } { continue }
962       foreach aProject $aProjectsInModule($aModule) {
963         append aFileBuff "              $aGuidsMap($aProject) = $aGuidsMap(_$aModule)\n"
964       }
965     }
966     append aFileBuff "  EndGlobalSection\n"
967   }
968
969   # final word (footer)
970   append aFileBuff "EndGlobal"
971
972   # write solution
973   set aFile [open [set fdsw [file join $theOutDir ${theSolName}.sln]] w]
974   fconfigure $aFile -translation crlf
975   puts $aFile $aFileBuff
976   close $aFile
977   return [file join $theOutDir ${theSolName}.sln]
978 }
979 # Generate Visual Studio projects for specified version
980
981 proc OS:vcproj { theVcVer theModules theOutDir theGuidsMap } {
982   upvar $theGuidsMap aGuidsMap
983
984   set aProjectFiles {}
985
986   foreach aModule $theModules {
987     foreach aToolKit [${aModule}:toolkits] {
988       lappend aProjectFiles [osutils:vcproj  $theVcVer $theOutDir $aToolKit     aGuidsMap]
989     }
990     foreach anExecutable [OS:executable ${aModule}] {
991       lappend aProjectFiles [osutils:vcprojx $theVcVer $theOutDir $anExecutable aGuidsMap]
992     }
993   }
994   return $aProjectFiles
995 }
996 # generate template name and load it for given version of Visual Studio and platform
997
998 proc osutils:vcproj:readtemplate {theVcVer isexec} {
999   set anExt $theVcVer
1000   if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1001     set anExt vc10
1002   }
1003
1004   set what "$theVcVer"
1005   set aVerExt [string range $theVcVer 2 end]
1006   set aVerExt "v${aVerExt}0"
1007   set aCmpl32 ""
1008   set aCmpl64 ""
1009   if { $isexec } {
1010     set anExt "${anExt}x"
1011     set what "$what executable"
1012   }
1013   if { "$theVcVer" == "vc10" } {
1014     # SSE2 is enabled by default in vc11+, but not in vc10 for 32-bit target
1015     set aCmpl32 "\n      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>"
1016   }
1017   set aTmpl [osutils:readtemplate $anExt "MS VC++ project ($what)"]
1018   regsub -all -- {__VCVER__}    $aTmpl $theVcVer aTmpl
1019   regsub -all -- {__VCVEREXT__} $aTmpl $aVerExt  aTmpl
1020   regsub -all -- {__VCMPL32__}  $aTmpl $aCmpl32  aTmpl
1021   regsub -all -- {__VCMPL64__}  $aTmpl $aCmpl64  aTmpl
1022   return $aTmpl
1023 }
1024
1025 proc osutils:readtemplate {ext what} {
1026   global env
1027   global path
1028   set loc "$path/adm/templates/template.$ext"
1029   return [wokUtils:FILES:FileToString $loc]
1030 }
1031 # Read a file in a string as is.
1032
1033 proc wokUtils:FILES:FileToString { fin } {
1034     if { [catch { set in [ open $fin r ] } errin] == 0 } {
1035         set strin [read $in [file size $fin]]
1036         close $in
1037         return $strin
1038     } else {
1039         return {}
1040     }
1041 }
1042 # List extensions of compilable files in OCCT
1043
1044 proc osutils:compilable { } {
1045   global targetStation
1046   set aWokStation "$targetStation"
1047   if { "$aWokStation" == "mac" } {
1048     return [list .c .cxx .cpp .mm]
1049   }
1050   return [list .c .cxx .cpp]
1051 }
1052
1053 proc osutils:commonUsedTK { theToolKit } {
1054   global path
1055   set anUsedToolKits [list]
1056   set aDepToolkits [LibToLink $theToolKit]
1057   foreach tkx $aDepToolkits {
1058     if {[_get_type $tkx] == "t"} {
1059       lappend anUsedToolKits "${tkx}"
1060     }
1061   }
1062   return $anUsedToolKits
1063 }
1064
1065 # Return the list of name *CSF_ in a EXTERNLIB description of a toolkit
1066 proc osutils:tk:csfInExternlib { EXTERNLIB } {
1067   set l [wokUtils:FILES:FileToList $EXTERNLIB]
1068   set lret  {STLPort}
1069   foreach str $l {
1070     if [regexp -- {(CSF_[^ ]*)} $str csf] {
1071       lappend lret $csf
1072     }
1073   }
1074   return $lret
1075 }
1076
1077 # @param theCsfLibsMap - libraries  map
1078 # @param theCsfFrmsMap - frameworks map, OS X specific
1079 proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
1080   upvar $theCsfLibsMap aLibsMap
1081   upvar $theCsfFrmsMap aFrmsMap
1082
1083   unset theCsfLibsMap
1084   unset theCsfFrmsMap
1085
1086   if { "$theOS" == "wnt" } {
1087     #  WinAPI libraries
1088     set aLibsMap(CSF_kernel32)     "kernel32.lib"
1089     set aLibsMap(CSF_advapi32)     "advapi32.lib"
1090     set aLibsMap(CSF_gdi32)        "gdi32.lib"
1091     set aLibsMap(CSF_user32)       "user32.lib"
1092     set aLibsMap(CSF_opengl32)     "opengl32.lib"
1093     set aLibsMap(CSF_wsock32)      "wsock32.lib"
1094     set aLibsMap(CSF_netapi32)     "netapi32.lib"
1095     set aLibsMap(CSF_AviLibs)      "ws2_32.lib vfw32.lib"
1096     set aLibsMap(CSF_OpenGlLibs)   "opengl32.lib"
1097
1098     set aLibsMap(CSF_QT)           "QtCore4.lib QtGui4.lib"
1099
1100     # VTK
1101     set aLibsMap(CSF_VTK)         [osutils:vtkCsf "wnt"]
1102   } else {
1103     set aLibsMap(CSF_FREETYPE)     "freetype"
1104     if { "$theOS" == "mac" } {
1105       set aLibsMap(CSF_objc)       "objc"
1106       set aFrmsMap(CSF_Appkit)     "Appkit"
1107       set aFrmsMap(CSF_IOKit)      "IOKit"
1108       set aFrmsMap(CSF_OpenGlLibs) "OpenGL"
1109       set aFrmsMap(CSF_TclLibs)    "Tcl"
1110       set aFrmsMap(CSF_TclTkLibs)  "Tk"
1111     } else {
1112       set aLibsMap(CSF_ThreadLibs) "pthread rt"
1113       set aLibsMap(CSF_OpenGlLibs) "GL"
1114       set aLibsMap(CSF_TclLibs)    "tcl8.6"
1115       set aLibsMap(CSF_TclTkLibs)  "X11 tk8.6"
1116       set aLibsMap(CSF_XwLibs)     "X11 Xext Xmu Xi"
1117       set aLibsMap(CSF_MotifLibs)  "X11"
1118     }
1119
1120     # optional 3rd-parties
1121     if { "$::HAVE_TBB" == "true" } {
1122       set aLibsMap(CSF_TBB)        "tbb tbbmalloc"
1123     }
1124     if { "$::HAVE_FREEIMAGE" == "true" } {
1125       set aLibsMap(CSF_FreeImagePlus)  "freeimage"
1126     }
1127     if { "$::HAVE_GL2PS" == "true" } {
1128       set aLibsMap(CSF_GL2PS)      "gl2ps"
1129     }
1130     if { "$::HAVE_VTK" == "true" } {
1131       set aLibsMap(CSF_VTK)         [osutils:vtkCsf "unix"]
1132     }
1133   }
1134 }
1135
1136 # Returns string of library dependencies for generation of Visual Studio project or make lists.
1137 proc osutils:vtkCsf {{theOS ""}} {
1138   set aVtkVer "6.1"
1139
1140   set aLibSuffix ""
1141   set aPathSplitter ":"
1142   
1143   if {"$theOS" == "wnt"} {
1144     set aPathSplitter ";"
1145     set aLibSuffix ".lib"
1146   }
1147
1148   set anOptIncs [split $::env(CSF_OPT_INC) "$aPathSplitter"]
1149   foreach anIncItem $anOptIncs {
1150     if {[regexp -- "vtk-(.*)$" [file tail $anIncItem] dummy aFoundVtkVer]} {
1151       set aVtkVer $aFoundVtkVer
1152     }
1153   }
1154
1155   set aLibArray [list vtkCommonCore vtkCommonDataModel vtkCommonExecutionModel vtkCommonMath vtkCommonTransforms vtkRenderingCore \
1156                       vtkRenderingOpenGL  vtkFiltersGeneral vtkIOCore vtkIOImage vtkImagingCore vtkInteractionStyle]
1157
1158   # Additional suffices for the libraries
1159   set anIdx 0
1160   foreach anItem $aLibArray {
1161     lset aLibArray $anIdx $anItem-$aVtkVer$aLibSuffix
1162     incr anIdx
1163   }
1164
1165   return [join $aLibArray " "]
1166 }
1167
1168 # @param theLibsList   - dependencies (libraries  list)
1169 # @param theFrameworks - dependencies (frameworks list, OS X specific)
1170 proc osutils:usedOsLibs { theToolKit theOS theLibsList theFrameworks } {
1171   global path
1172   upvar $theLibsList   aLibsList
1173   upvar $theFrameworks aFrameworks
1174   set aLibsList   [list]
1175   set aFrameworks [list]
1176
1177   osutils:csfList $theOS aLibsMap aFrmsMap
1178
1179   foreach aCsfElem [osutils:tk:csfInExternlib "$path/src/${theToolKit}/EXTERNLIB"] {
1180     if [info exists aLibsMap($aCsfElem)] {
1181       foreach aLib [split "$aLibsMap($aCsfElem)"] {
1182         if { [lsearch $aLibsList $aLib] == "-1" } {
1183           lappend aLibsList $aLib
1184         }
1185       }
1186     }
1187     if [info exists aFrmsMap($aCsfElem)] {
1188       foreach aFrm [split "$aFrmsMap($aCsfElem)"] {
1189         if { [lsearch $aFrameworks $aFrm] == "-1" } {
1190           lappend aFrameworks $aFrm
1191         }
1192       }
1193     }
1194   }
1195 }
1196
1197 # Returns liste of UD in a toolkit. tkloc is a full path wok.
1198 proc osutils:tk:units { tkloc } {
1199   global path
1200   set l {}
1201   set PACKAGES "$path/src/$tkloc/PACKAGES"
1202   foreach u [wokUtils:FILES:FileToList $PACKAGES] {
1203     if {[file isdirectory "$path/src/$u"]} {
1204       lappend l $u
1205     }
1206   }
1207   if { $l == {} } {
1208     ;#puts stderr "Warning. No devunit included in $tkloc"
1209   }
1210   return $l
1211 }
1212
1213 proc osutils:justwnt { listloc } {
1214   # ImageUtility is required for support for old (<6.5.4) versions of OCCT
1215   set goaway [list Xdps Xw  ImageUtility WOKUnix]
1216   return [osutils:juststation $goaway $listloc]
1217 }
1218
1219 # remove from listloc OpenCascade units indesirables on NT
1220 proc osutils:juststation {goaway listloc} {
1221   global path
1222   set lret {}
1223   foreach u $listloc {
1224     if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1225      || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1226       lappend lret $u
1227     }
1228   }
1229   return $lret
1230 }
1231
1232 # intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1233 # The first list is everything in the first list that wasn't in the second,
1234 # the second list contains the intersection of the two lists, the third list contains everything
1235 # in the second list that wasn't in the first.
1236 proc osutils:intersect3 {list1 list2} {
1237   set la1(0) {} ; unset la1(0)
1238   set lai(0) {} ; unset lai(0)
1239   set la2(0) {} ; unset la2(0)
1240   foreach v $list1 {
1241     set la1($v) {}
1242   }
1243   foreach v $list2 {
1244     set la2($v) {}
1245   }
1246   foreach elem [concat $list1 $list2] {
1247     if {[info exists la1($elem)] && [info exists la2($elem)]} {
1248       unset la1($elem)
1249       unset la2($elem)
1250       set lai($elem) {}
1251     }
1252   }
1253   list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1254 }
1255
1256 # Prepare relative path
1257 proc relativePath {thePathFrom thePathTo} {
1258   if { [file isdirectory "$thePathFrom"] == 0 } {
1259     return ""
1260   }
1261
1262   set aPathFrom [file normalize "$thePathFrom"]
1263   set aPathTo   [file normalize "$thePathTo"]
1264
1265   set aCutedPathFrom "${aPathFrom}/dummy"
1266   set aRelatedDeepPath ""
1267
1268   while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1269     set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1270     # does aPathTo contain aCutedPathFrom?
1271     regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1272     if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1273       if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1274         set aPathTo ".${aPathTo}"
1275       } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1276         set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1277       }
1278       regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1279       regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1280       return $aPathToAfterCut
1281     }
1282     set aRelatedDeepPath "$aRelatedDeepPath../"
1283
1284   }
1285
1286   return $thePathTo
1287 }
1288
1289 proc wokUtils:EASY:bs1 { s } {
1290     regsub -all {/} $s {\\} r
1291     return $r
1292 }
1293
1294 # Returs for a full path the liste of n last directory part
1295 # n = 1 => tail
1296 # n = 2 => dir/file.c
1297 # n = 3 => sdir/dir/file.c
1298 # etc..
1299 proc wokUtils:FILES:wtail { f n } {
1300     set ll [expr [llength [set lif [file split $f]]] -$n]
1301     return [join [lrange $lif $ll end] /]
1302 }
1303
1304 # Generate entry for one source file in Visual Studio 10 project file
1305 proc osutils:vcxproj:file { vcversion file params } {
1306   append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1307   if { $params != "" } {
1308     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1309   }
1310
1311   if { $params != "" } {
1312     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1313   }
1314
1315   if { $params != "" } {
1316     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1317   }
1318
1319   if { $params != "" } {
1320     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1321   }
1322
1323   append text "    </ClCompile>\n"
1324   return $text
1325 }
1326
1327 # Generate Visual Studio 2010 project filters file
1328 proc osutils:vcxproj:filters { dir proj theFilesMap } {
1329   upvar $theFilesMap aFilesMap
1330
1331   # header
1332   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1333   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1334
1335   # list of "filters" (units)
1336   append text "  <ItemGroup>\n"
1337   append text "    <Filter Include=\"Source files\">\n"
1338   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1339   append text "    </Filter>\n"
1340   foreach unit $aFilesMap(units) {
1341     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1342     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1343     append text "    </Filter>\n"
1344   }
1345   append text "  </ItemGroup>\n"
1346
1347   # list of files
1348   append text "  <ItemGroup>\n"
1349   foreach unit $aFilesMap(units) {
1350     foreach file $aFilesMap($unit) {
1351       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1352       append text "      <Filter>Source files\\${unit}</Filter>\n"
1353       append text "    </ClCompile>\n"
1354     }
1355   }
1356   append text "  </ItemGroup>\n"
1357
1358   # end
1359   append text "</Project>"
1360
1361   # write file
1362   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1363   fconfigure $fp -translation crlf
1364   puts $fp $text
1365   close $fp
1366
1367   return ${proj}.vcxproj.filters
1368 }
1369
1370 # Generate Visual Studio 2011 project filters file
1371 proc osutils:vcx1proj:filters { dir proj theFilesMap } {
1372   upvar $theFilesMap aFilesMap
1373
1374   # header
1375   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1376   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1377
1378   # list of "filters" (units)
1379   append text "  <ItemGroup>\n"
1380   append text "    <Filter Include=\"Source files\">\n"
1381   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1382   append text "    </Filter>\n"
1383   foreach unit $aFilesMap(units) {
1384     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1385     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1386     append text "    </Filter>\n"
1387   }
1388   append text "  </ItemGroup>\n"
1389
1390   # list of files
1391   append text "  <ItemGroup>\n"
1392   foreach unit $aFilesMap(units) {
1393     foreach file $aFilesMap($unit) {
1394       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1395       append text "      <Filter>Source files\\${unit}</Filter>\n"
1396       append text "    </ClCompile>\n"
1397     }
1398   }
1399   append text "  </ItemGroup>\n"
1400
1401   append text "  <ItemGroup>\n"
1402   append text "    <ResourceCompile Include=\"${proj}.rc\" />"
1403   append text "  </ItemGroup>\n"
1404
1405   # end
1406   append text "</Project>"
1407
1408   # write file
1409   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1410   fconfigure $fp -translation crlf
1411   puts $fp $text
1412   close $fp
1413
1414   return ${proj}.vcxproj.filters
1415 }
1416
1417 # Generate RC file content for ToolKit from template
1418 proc osutils:readtemplate:rc {theOutDir theToolKit} {
1419   global path
1420   set aLoc "$path/adm/templates/template_dll.rc"
1421   set aBody [wokUtils:FILES:FileToString $aLoc]
1422   regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1423
1424   set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1425   fconfigure $aFile -translation lf
1426   puts $aFile $aBody
1427   close $aFile
1428   return "${theOutDir}/${theToolKit}.rc"
1429 }
1430
1431 # Generate Visual Studio project file for ToolKit
1432 proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1433   if { $theProjTmpl == {} } {set theProjTmpl [osutils:vcproj:readtemplate $theVcVer 0]}
1434
1435   set l_compilable [osutils:compilable]
1436   regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1437
1438   upvar $theGuidsMap aGuidsMap
1439   if { ! [info exists aGuidsMap($theToolKit)] } {
1440     set aGuidsMap($theToolKit) [OS:genGUID]
1441   }
1442   regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1443
1444   set aCommonUsedTK [list]
1445   foreach tkx [osutils:commonUsedTK  $theToolKit] {
1446     lappend aCommonUsedTK "${tkx}.lib"
1447   }
1448
1449   osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
1450   set aUsedToolKits [concat $aCommonUsedTK $aLibs]
1451
1452   # correct names of referred third-party libraries that are named with suffix
1453   # depending on VC version
1454   regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1455
1456   # and put this list to project file
1457   #puts "$theToolKit requires  $aUsedToolKits"
1458   if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1459     set aUsedToolKits [join $aUsedToolKits {;}]
1460   }
1461   regsub -all -- {__TKDEP__} $theProjTmpl $aUsedToolKits theProjTmpl
1462
1463   set anIncPaths "..\\..\\..\\inc"
1464   set aTKDefines ""
1465   set aFilesSection ""
1466   set aVcFilesX(units) ""
1467   set listloc [osutils:tk:units $theToolKit]
1468   set resultloc [osutils:justwnt $listloc]
1469   if [array exists written] { unset written }
1470   #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1471   #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1472   #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1473   #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1474   set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1475   set fxloparamfc   [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1476   set fxloparam ""
1477   foreach fxlo $resultloc {
1478     set xlo $fxlo
1479     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
1480         set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
1481     if {$fxlo_cmplrs_options_cxx == ""} {
1482       set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1483     }
1484         set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1485     if {$fxlo_cmplrs_options_c == ""} {
1486       set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1487     }
1488     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1489     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1490         #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1491         #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo  CXX"
1492         #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1493         #puts "\t6 [wokparam -v %CMPLRS_C_Options   $fxlo] $fxlo  C"
1494     set needparam ""
1495     foreach partopt $fxloparam {
1496       if {[string first "-I" $partopt] == "0"} {
1497         # this is an additional includes search path
1498         continue
1499       }
1500       set needparam "$needparam $partopt"
1501     }
1502
1503     # Format of projects in vc10+ is different from vc7-9
1504     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1505       foreach aSrcFile [lsort $aSrcFiles] {
1506         if { ![info exists written([file tail $aSrcFile])] } {
1507           set written([file tail $aSrcFile]) 1
1508           append aFilesSection [osutils:vcxproj:file $theVcVer $aSrcFile $needparam]
1509         } else {
1510           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1511         }
1512         if { ! [info exists aVcFilesX($xlo)] } { lappend aVcFilesX(units) $xlo }
1513         lappend aVcFilesX($xlo) $aSrcFile
1514       }
1515     } else {
1516       append aFilesSection "\t\t\t<Filter\n"
1517       append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1518       append aFilesSection "\t\t\t\t>\n"
1519       foreach aSrcFile [lsort $aSrcFiles] {
1520         if { ![info exists written([file tail $aSrcFile])] } {
1521           set written([file tail $aSrcFile]) 1
1522           append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1523         } else {
1524           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1525         }
1526       }
1527       append aFilesSection "\t\t\t</Filter>\n"
1528     }
1529
1530     # macros
1531     append aTKDefines ";__${xlo}_DLL"
1532     # common includes
1533 #    append anIncPaths ";..\\..\\..\\src\\${xlo}"
1534   }
1535
1536   regsub -all -- {__TKINC__}  $theProjTmpl $anIncPaths theProjTmpl
1537   regsub -all -- {__TKDEFS__} $theProjTmpl $aTKDefines theProjTmpl
1538   regsub -all -- {__FILES__}  $theProjTmpl $aFilesSection theProjTmpl
1539
1540   # write file
1541   set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1542   fconfigure $aFile -translation crlf
1543   puts $aFile $theProjTmpl
1544   close $aFile
1545
1546   # write filters file for vc10+
1547   if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" || "$theVcVer" == "vc9" } {
1548     # nothing
1549   } elseif { "$theVcVer" == "vc10" } {
1550     lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesX]
1551   } else {
1552     lappend aVcFiles [osutils:vcx1proj:filters $theOutDir $theToolKit aVcFilesX]
1553   }
1554
1555   # write resource file
1556   lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1557
1558   return $aVcFiles
1559 }
1560
1561 # for a unit returns a map containing all its file in the current
1562 # workbench
1563 # local = 1 only local files
1564 proc osutils:tk:loadunit { loc map } {
1565   #puts $loc
1566   upvar $map TLOC
1567   catch { unset TLOC }
1568   set lfiles [_get_used_files $loc]
1569   foreach f $lfiles {
1570     #puts "\t$f"
1571     set t [lindex $f 0]
1572     set p [lindex $f 2]
1573     if [info exists TLOC($t)] {
1574       set l $TLOC($t)
1575       lappend l $p
1576       set TLOC($t) $l
1577     } else {
1578       set TLOC($t) $p
1579     }
1580   }
1581   return
1582 }
1583
1584 # Returns the list of all compilable files name in a toolkit, or devunit of any type
1585 # Call unit filter on units name to accept or reject a unit
1586 # Tfiles lists for each unit the type of file that can be compiled.
1587 proc osutils:tk:files { tkloc  {l_compilable {} } {justail 1} {unitfilter {}} } {
1588   global path
1589   set Tfiles(source,nocdlpack)     {source pubinclude}
1590   set Tfiles(source,toolkit)       {}
1591   set Tfiles(source,executable)    {source pubinclude}
1592   set listloc [concat [osutils:tk:units $tkloc] $tkloc]
1593   #puts " listloc = $listloc"
1594   if { $l_compilable == {} } {
1595     set l_comp [list .c .cxx .cpp]
1596   } else {
1597     set l_comp [$l_compilable]
1598   }
1599   if { $unitfilter == {} } {
1600     set resultloc $listloc
1601   } else {
1602     set resultloc [$unitfilter $listloc]
1603   }
1604   set lret {}
1605   foreach loc $resultloc {
1606     set utyp [_get_type $loc]
1607     #puts "\"$utyp\" \"$loc\""
1608     switch $utyp {
1609          "t" { set utyp "toolkit" }
1610          "n" { set utyp "nocdlpack" }
1611          "x" { set utyp "executable" }
1612     }
1613     if [array exists map] { unset map }
1614     osutils:tk:loadunit $loc map
1615     #puts " loc = $loc === > [array names map]"
1616     set LType $Tfiles(source,${utyp})
1617     foreach typ [array names map] {
1618       if { [lsearch $LType $typ] == -1 } {
1619         unset map($typ)
1620       }
1621     }
1622     foreach type [array names map] {
1623       #puts $type
1624       foreach f $map($type) {
1625         #puts $f
1626         if { [lsearch $l_comp [file extension $f]] != -1 } {
1627           if { $justail == 1 } {
1628             if {$type == "source"} {
1629               if {[lsearch $lret "@top_srcdir@/src/$loc/[file tail $f]"] == -1} {
1630                 lappend lret @top_srcdir@/src/$loc/[file tail $f]
1631               }
1632             }
1633           } else {
1634             lappend lret $f
1635           }
1636         }
1637       }
1638     }
1639   }
1640   return $lret
1641 }
1642
1643 # Generate Visual Studio project file for executable
1644 proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1645   global path
1646   set aVcFiles {}
1647   foreach f [osutils:tk:files $theToolKit osutils:compilable 0] {
1648     if { $theProjTmpl == {} } {
1649       set aProjTmpl [osutils:vcproj:readtemplate $theVcVer 1]
1650     } else {
1651       set aProjTmpl $theProjTmpl
1652     }
1653     set aProjName [file rootname [file tail $f]]
1654     set l_compilable [osutils:compilable]
1655     regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
1656
1657     upvar $theGuidsMap aGuidsMap
1658     if { ! [info exists aGuidsMap($aProjName)] } {
1659       set aGuidsMap($aProjName) [OS:genGUID]
1660     }
1661     regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
1662
1663     set aCommonUsedTK [list]
1664     foreach tkx [osutils:commonUsedTK  $theToolKit] {
1665       lappend aCommonUsedTK "${tkx}.lib"
1666     }
1667
1668     osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
1669     set aUsedToolKits [concat $aCommonUsedTK $aLibs]
1670
1671     # correct names of referred third-party libraries that are named with suffix
1672     # depending on VC version
1673     regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1674
1675 #    puts "$aProjName requires  $aUsedToolKits"
1676     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1677       set aUsedToolKits [join $aUsedToolKits {;}]
1678     }
1679     regsub -all -- {__TKDEP__} $aProjTmpl $aUsedToolKits aProjTmpl
1680
1681     set aFilesSection ""
1682     set aVcFilesX(units) ""
1683
1684     if { ![info exists written([file tail $f])] } {
1685       set written([file tail $f]) 1
1686
1687       if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1688         append aFilesSection [osutils:vcxproj:file $theVcVer $f ""]
1689         if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
1690         lappend aVcFilesX($theToolKit) $f
1691       } else {
1692         append aFilesSection "\t\t\t<Filter\n"
1693         append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
1694         append aFilesSection "\t\t\t\t>\n"
1695         append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
1696         append aFilesSection "\t\t\t</Filter>"
1697       }
1698     } else {
1699       puts "Warning : in vcproj there are than one occurences for [file tail $f]"
1700     }
1701     #puts "$aProjTmpl $aFilesSection"
1702     set aTKDefines ";__${theToolKit}_DLL"
1703     set anIncPaths "..\\..\\..\\inc"
1704     regsub -all -- {__TKINC__}  $aProjTmpl $anIncPaths    aProjTmpl
1705     regsub -all -- {__TKDEFS__} $aProjTmpl $aTKDefines    aProjTmpl
1706     regsub -all -- {__FILES__}  $aProjTmpl $aFilesSection aProjTmpl
1707     regsub -all -- {__CONF__}   $aProjTmpl Application    aProjTmpl
1708
1709     regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
1710
1711     set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
1712     fconfigure $aFile -translation crlf
1713     puts $aFile $aProjTmpl
1714     close $aFile
1715
1716     set aCommonSettingsFile "$aVcFilePath.user"
1717     lappend aVcFiles $aVcFilePath
1718
1719     # write filters file for vc10
1720     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1721       lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesX]
1722     }
1723
1724     set aCommonSettingsFileTmpl ""
1725     if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
1726       # nothing
1727     } elseif { "$theVcVer" == "vc9" } {
1728       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$path/adm/templates/vcproj.user.vc9x"]
1729     } else {
1730       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$path/adm/templates/vcxproj.user.vc10x"]
1731     }
1732     if { "$aCommonSettingsFileTmpl" != "" } {
1733       regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $theVcVer aCommonSettingsFileTmpl
1734
1735       set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
1736       fconfigure $aFile -translation crlf
1737       puts $aFile $aCommonSettingsFileTmpl
1738       close $aFile
1739
1740       lappend aVcFiles "$aCommonSettingsFile"
1741     }
1742   }
1743   return $aVcFiles
1744 }
1745
1746 # Generate entry for one source file in Visual Studio 7 - 9 project file
1747 proc osutils:vcproj:file { theVcVer theFile theOptions } {
1748   append aText "\t\t\t\t<File\n"
1749   append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1750   if { $theOptions == "" } {
1751     append aText "\t\t\t\t</File>\n"
1752     return $aText
1753   }
1754
1755   append aText "\t\t\t\t\t<FileConfiguration\n"
1756   append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
1757   append aText "\t\t\t\t\t\t<Tool\n"
1758   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1759   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1760   foreach aParam $theOptions {
1761     append aText "$aParam "
1762   }
1763   append aText "\"\n"
1764   append aText "\t\t\t\t\t\t/>\n"
1765   append aText "\t\t\t\t\t</FileConfiguration>\n"
1766
1767   append aText "\t\t\t\t\t<FileConfiguration\n"
1768   append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
1769   append aText "\t\t\t\t\t\t<Tool\n"
1770   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1771   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1772   foreach aParam $theOptions {
1773     append aText "$aParam "
1774   }
1775   append aText "\"\n"
1776   append aText "\t\t\t\t\t\t/>\n"
1777   append aText "\t\t\t\t\t</FileConfiguration>\n"
1778   if { "$theVcVer" == "vc7" } {
1779     append aText "\t\t\t\t</File>\n"
1780     return $aText
1781   }
1782
1783   append aText "\t\t\t\t\t<FileConfiguration\n"
1784   append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
1785   append aText "\t\t\t\t\t\t<Tool\n"
1786   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1787   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1788   foreach aParam $theOptions {
1789     append aText "$aParam "
1790   }
1791   append aText "\"\n"
1792   append aText "\t\t\t\t\t\t/>\n"
1793   append aText "\t\t\t\t\t</FileConfiguration>\n"
1794
1795   append aText "\t\t\t\t\t<FileConfiguration\n"
1796   append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
1797   append aText "\t\t\t\t\t\t<Tool\n"
1798   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1799   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1800   foreach aParam $theOptions {
1801     append aText "$aParam "
1802   }
1803   append aText "\"\n"
1804   append aText "\t\t\t\t\t\t/>\n"
1805   append aText "\t\t\t\t\t</FileConfiguration>\n"
1806
1807   append aText "\t\t\t\t</File>\n"
1808   return $aText
1809 }
1810
1811 proc wokUtils:FILES:mkdir { d } {
1812     global tcl_version
1813     regsub -all {\.[^.]*} $tcl_version "" major
1814     if { $major == 8 } {
1815         file mkdir $d
1816     } else {
1817         if ![file exists $d] {
1818             if { "[info command mkdir]" == "mkdir" } {
1819                 mkdir -path $d
1820             } else {
1821                 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
1822             }
1823         }
1824     }
1825     if [file exists $d] {
1826         return $d
1827     } else {
1828         return {}
1829     }
1830 }
1831
1832 # remove from listloc OpenCascade units indesirables on Unix
1833 proc osutils:justunix { listloc } {
1834   if { "$::tcl_platform(os)" == "Darwin" } {
1835     set goaway [list Xw WNT]
1836   } else {
1837     set goaway [list WNT]
1838   }
1839   return [osutils:juststation $goaway $listloc]
1840 }
1841
1842
1843 ####### CODEBLOCK ###################################################################
1844 # Function to generate Code Blocks workspace and project files
1845 proc OS:MKCBP { theOutDir {theModules {}} {theAllSolution ""} } {
1846   puts stderr "Generating project files for Code Blocks"
1847
1848   # Generate projects for toolkits and separate workspace for each module
1849   foreach aModule $theModules {
1850     OS:cworkspace $aModule $aModule $theOutDir
1851     OS:cbp        $aModule          $theOutDir
1852   }
1853
1854   # Generate single workspace "OCCT" containing projects from all modules
1855   if { "$theAllSolution" != "" } {
1856     OS:cworkspace $theAllSolution $theModules $theOutDir
1857   }
1858
1859   puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
1860 }
1861
1862 # Generate Code Blocks projects
1863 proc OS:cbp { theModules theOutDir } {
1864   set aProjectFiles {}
1865   foreach aModule $theModules {
1866     foreach aToolKit [${aModule}:toolkits] {
1867       lappend aProjectFiles [osutils:cbptk $theOutDir $aToolKit ]
1868     }
1869     foreach anExecutable [OS:executable ${aModule}] {
1870       lappend aProjectFiles [osutils:cbpx  $theOutDir $anExecutable]
1871     }
1872   }
1873   return $aProjectFiles
1874 }
1875
1876 # Generate Code::Blocks project file for ToolKit
1877 proc osutils:cbptk { theOutDir theToolKit } {
1878   set aUsedToolKits [list]
1879   set aFrameworks   [list]
1880   set anIncPaths    [list]
1881   set aTKDefines    [list]
1882   set aTKSrcFiles   [list]
1883
1884   osutils:tkinfo "../../.." $theToolKit aUsedToolKits aFrameworks anIncPaths aTKDefines aTKSrcFiles
1885
1886   return [osutils:cbp $theOutDir $theToolKit $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines]
1887 }
1888
1889 # Generates Code Blocks workspace.
1890 proc OS:cworkspace { theSolName theModules theOutDir } {
1891   global path
1892   set aWsFilePath "${theOutDir}/${theSolName}.workspace"
1893   set aFile [open $aWsFilePath "w"]
1894   set isActiveSet 0
1895   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
1896   puts $aFile "<CodeBlocks_workspace_file>"
1897   puts $aFile "\t<Workspace title=\"${theSolName}\">"
1898
1899   # collect list of projects to be created
1900   foreach aModule $theModules {
1901     # toolkits
1902     foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
1903       set aDependencies [LibToLink $aToolKit]
1904       if { [llength $aDependencies] == 0 } {
1905         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
1906       } else {
1907         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
1908         foreach aDepTk $aDependencies {
1909           puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
1910         }
1911         puts $aFile "\t\t</Project>"
1912       }
1913     }
1914
1915     # executables, assume one project per cxx file...
1916     foreach aUnit [OS:executable ${aModule}] {
1917       set aUnitLoc $aUnit
1918       set src_files [_get_used_files $aUnit false]
1919       set aSrcFiles {}
1920       foreach s $src_files { 
1921         regexp {source ([^\s]+)} $s dummy name
1922         lappend aSrcFiles $name
1923       }
1924       foreach aSrcFile $aSrcFiles {
1925         set aFileExtension [file extension $aSrcFile]
1926         if { $aFileExtension == ".cxx" } {
1927           set aPrjName [file rootname $aSrcFile]
1928           set aDependencies [list]
1929           if {[file isdirectory $path/src/$aUnitLoc]} {
1930             set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
1931           }
1932           set anActiveState ""
1933           if { $isActiveSet == 0 } {
1934             set anActiveState " active=\"1\""
1935             set isActiveSet 1
1936           }
1937           if { [llength $aDependencies] == 0 } {
1938             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
1939           } else {
1940             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
1941             foreach aDepTk $aDependencies {
1942               puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
1943             }
1944             puts $aFile "\t\t</Project>"
1945           }
1946         }
1947       }
1948     }
1949   }
1950
1951   puts $aFile "\t</Workspace>"
1952   puts $aFile "</CodeBlocks_workspace_file>"
1953   close $aFile
1954
1955   return $aWsFilePath
1956 }
1957
1958 # Generate Code::Blocks project file for Executable
1959 proc osutils:cbpx { theOutDir theToolKit } {
1960   global path targetStation
1961   set aWokStation "$targetStation"
1962   set aWokArch    "$::env(ARCH)"
1963
1964   set aCbpFiles {}
1965   foreach aSrcFile [osutils:tk:files $theToolKit osutils:compilable 0] {
1966     # collect list of referred libraries to link with
1967     set aUsedToolKits [list]
1968     set aFrameworks   [list]
1969     set anIncPaths    [list]
1970     set aTKDefines    [list]
1971     set aTKSrcFiles   [list]
1972     set aProjName [file rootname [file tail $aSrcFile]]
1973
1974     osutils:usedOsLibs $theToolKit "$aWokStation" aUsedToolKits aFrameworks
1975     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
1976     foreach tkx $aDepToolkits {
1977       if {[_get_type $tkx] == "t"} {
1978         lappend aUsedToolKits "${tkx}"
1979       }
1980       if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
1981         lappend aUsedToolKits "${tkx}"
1982       }
1983     }
1984
1985     set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
1986     if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
1987       set isExecutable "false"
1988     } else {
1989       set isExecutable "true"
1990     }
1991
1992     if { ![info exists written([file tail $aSrcFile])] } {
1993       set written([file tail $aSrcFile]) 1
1994       lappend aTKSrcFiles $aSrcFile
1995     } else {
1996       puts "Warning : in cbp there are more than one occurences for [file tail $aSrcFile]"
1997     }
1998
1999     # macros for correct DLL exports
2000     if { "$aWokStation" == "wnt" } {
2001       lappend aTKDefines "__${theToolKit}_DLL"
2002     }
2003
2004     # common include paths
2005     lappend anIncPaths "../../../inc"
2006
2007     # extra macros
2008     lappend aTKDefines "CSFDB"
2009     if { "$aWokStation" == "wnt" } {
2010       lappend aTKDefines "WNT"
2011       lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2012     } else {
2013       if { "$aWokStation" == "lin" } {
2014         lappend aTKDefines "LIN"
2015       }
2016       lappend aTKDefines "OCC_CONVERT_SIGNALS"
2017       #lappend aTKDefines "_GNU_SOURCE=1"
2018     }
2019
2020     lappend aCbpFiles [osutils:cbp $theOutDir $aProjName $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines $isExecutable]
2021   }
2022
2023   return $aCbpFiles
2024 }
2025
2026 proc osutils:optinal_libs { } {
2027   return [list tbb.lib tbbmalloc.lib FreeImage.lib FreeImagePlus.lib gl2ps.lib]
2028 }
2029
2030 # This function intended to generate Code::Blocks project file
2031 # @param theOutDir     - output directory to place project file
2032 # @param theProjName   - project name
2033 # @param theSrcFiles   - list of source files
2034 # @param theLibsList   - dependencies (libraries  list)
2035 # @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2036 # @param theIncPaths   - header search paths
2037 # @param theDefines    - compiler macro definitions
2038 # @param theIsExe      - flag to indicate executable / library target
2039 proc osutils:cbp { theOutDir theProjName theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2040   global targetStation
2041   set aWokStation "$targetStation"
2042   set aWokArch    "$::env(ARCH)"
2043
2044   set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2045   set aFile [open $aCbpFilePath "w"]
2046   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2047   puts $aFile "<CodeBlocks_project_file>"
2048   puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2049   puts $aFile "\t<Project>"
2050   puts $aFile "\t\t<Option title=\"$theProjName\" />"
2051   puts $aFile "\t\t<Option pch_mode=\"2\" />"
2052   if { "$aWokStation" == "wnt" } {
2053     puts $aFile "\t\t<Option compiler=\"msvc8\" />"
2054   } else {
2055     puts $aFile "\t\t<Option compiler=\"gcc\" />"
2056   }
2057   puts $aFile "\t\t<Build>"
2058
2059   # Release target configuration
2060   puts $aFile "\t\t\t<Target title=\"Release\">"
2061   if { "$theIsExe" == "true" } {
2062     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2063     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2064   } else {
2065     if { "$aWokStation" == "wnt" } {
2066       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2067     } else {
2068       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2069     }
2070     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2071   }
2072   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
2073   if { "$aWokStation" == "wnt" } {
2074     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2075   } else {
2076     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2077   }
2078   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2079   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2080
2081   # compiler options per TARGET (including defines)
2082   puts $aFile "\t\t\t\t<Compiler>"
2083   if { "$aWokStation" == "wnt" } {
2084     puts $aFile "\t\t\t\t\t<Add option=\"-MD\" />"
2085     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2086     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2087     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2088     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2089     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2090   } else {
2091     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2092     puts $aFile "\t\t\t\t\t<Add option=\"-std=c++0x\" />"
2093     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2094     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2095     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2096     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2097   }
2098   foreach aMacro $theDefines {
2099     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2100   }
2101   puts $aFile "\t\t\t\t\t<Add option=\"-DNDEBUG\" />"
2102   puts $aFile "\t\t\t\t\t<Add option=\"-DNo_Exception\" />"
2103
2104   puts $aFile "\t\t\t\t</Compiler>"
2105
2106   puts $aFile "\t\t\t\t<Linker>"
2107   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
2108   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2109     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2110   }
2111   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
2112   puts $aFile "\t\t\t\t</Linker>"
2113
2114   puts $aFile "\t\t\t</Target>"
2115
2116   # Debug target configuration
2117   puts $aFile "\t\t\t<Target title=\"Debug\">"
2118   if { "$theIsExe" == "true" } {
2119     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2120     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2121   } else {
2122     if { "$aWokStation" == "wnt" } {
2123       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2124     } else {
2125       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2126     }
2127     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2128   }
2129   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
2130   if { "$aWokStation" == "wnt" } {
2131     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2132   } else {
2133     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2134   }
2135   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2136   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2137
2138   # compiler options per TARGET (including defines)
2139   puts $aFile "\t\t\t\t<Compiler>"
2140   if { "$aWokStation" == "wnt" } {
2141     puts $aFile "\t\t\t\t\t<Add option=\"-MDd\" />"
2142     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2143     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2144     puts $aFile "\t\t\t\t\t<Add option=\"-Od\" />"
2145     puts $aFile "\t\t\t\t\t<Add option=\"-Zi\" />"
2146     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2147     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2148   } else {
2149     puts $aFile "\t\t\t\t\t<Add option=\"-O0\" />"
2150     puts $aFile "\t\t\t\t\t<Add option=\"-std=c++0x\" />"
2151     puts $aFile "\t\t\t\t\t<Add option=\"-g\" />"
2152     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2153     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2154     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2155     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2156   }
2157   foreach aMacro $theDefines {
2158     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2159   }
2160   puts $aFile "\t\t\t\t\t<Add option=\"-D_DEBUG\" />"
2161   puts $aFile "\t\t\t\t\t<Add option=\"-DDEB\" />"
2162   puts $aFile "\t\t\t\t</Compiler>"
2163
2164   puts $aFile "\t\t\t\t<Linker>"
2165   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
2166   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2167     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2168   }
2169   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
2170   puts $aFile "\t\t\t\t</Linker>"
2171
2172   puts $aFile "\t\t\t</Target>"
2173
2174   puts $aFile "\t\t</Build>"
2175
2176   # COMMON compiler options
2177   puts $aFile "\t\t<Compiler>"
2178   puts $aFile "\t\t\t<Add option=\"-Wall\" />"
2179   puts $aFile "\t\t\t<Add option=\"-fexceptions\" />"
2180   puts $aFile "\t\t\t<Add option=\"-fPIC\" />"
2181   puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2182   foreach anIncPath $theIncPaths {
2183     puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2184   }
2185   puts $aFile "\t\t</Compiler>"
2186
2187   # COMMON linker options
2188   puts $aFile "\t\t<Linker>"
2189   foreach aFrameworkName $theFrameworks {
2190     if { "$aFrameworkName" != "" } {
2191       puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2192     }
2193   }
2194   foreach aLibName $theLibsList {
2195     if { "$aLibName" != "" } {
2196       puts $aFile "\t\t\t<Add library=\"$aLibName\" />"
2197     }
2198   }
2199   puts $aFile "\t\t</Linker>"
2200
2201   # list of sources
2202   foreach aSrcFile $theSrcFiles {
2203     if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2204       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2205       puts $aFile "\t\t\t<Option compile=\"1\" />"
2206       puts $aFile "\t\t\t<Option link=\"1\" />"
2207       puts $aFile "\t\t</Unit>"
2208     } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2209       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2210       puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2211       puts $aFile "\t\t</Unit>"
2212     } else {
2213       puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
2214     }
2215   }
2216
2217   puts $aFile "\t</Project>"
2218   puts $aFile "</CodeBlocks_project_file>"
2219   close $aFile
2220
2221   return $aCbpFilePath
2222 }
2223
2224 # Auxiliary function to achieve complete information to build Toolkit
2225 # @param theRelativePath - relative path to CASROOT
2226 # @param theToolKit      - Toolkit name
2227 # @param theUsedLib      - dependencies (libraries  list)
2228 # @param theFrameworks   - dependencies (frameworks list, Mac OS X specific)
2229 # @param theIncPaths     - header search paths
2230 # @param theTKDefines    - compiler macro definitions
2231 # @param theTKSrcFiles   - list of source files
2232 proc osutils:tkinfo { theRelativePath theToolKit theUsedLib theFrameworks theIncPaths theTKDefines theTKSrcFiles } {
2233   global path targetStation
2234   set aWokStation "$targetStation"
2235
2236   # collect list of referred libraries to link with
2237   upvar $theUsedLib    aUsedLibs
2238   upvar $theFrameworks aFrameworks
2239   upvar $theIncPaths   anIncPaths
2240   upvar $theTKDefines  aTKDefines
2241   upvar $theTKSrcFiles aTKSrcFiles
2242
2243   osutils:usedOsLibs $theToolKit "$aWokStation" aUsedLibs aFrameworks
2244   set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2245   foreach tkx $aDepToolkits {
2246     lappend aUsedLibs "${tkx}"
2247   }
2248
2249   lappend anIncPaths "$theRelativePath/inc"
2250   set listloc [osutils:tk:units $theToolKit]
2251
2252   if { [llength $listloc] == 0 } {
2253     set listloc $theToolKit
2254   }
2255
2256   if { "$aWokStation" == "wnt" } {
2257     set resultloc [osutils:justwnt  $listloc]
2258   } else {
2259     set resultloc [osutils:justunix $listloc]
2260   }
2261   if [array exists written] { unset written }
2262   foreach fxlo $resultloc {
2263     set xlo       $fxlo
2264     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2265     foreach aSrcFile [lsort $aSrcFiles] {
2266       if { ![info exists written([file tail $aSrcFile])] } {
2267         set written([file tail $aSrcFile]) 1
2268         lappend aTKSrcFiles "${theRelativePath}/[wokUtils:FILES:wtail $aSrcFile 3]"
2269       } else {
2270         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2271       }
2272     }
2273
2274     # macros for correct DLL exports
2275     if { "$aWokStation" == "wnt" } {
2276       lappend aTKDefines "__${xlo}_DLL"
2277     }
2278
2279     # common include paths
2280 #    lappend anIncPaths "${theRelativePath}/src/${xlo}"
2281   }
2282
2283   # extra macros
2284   lappend aTKDefines "CSFDB"
2285   if { "$aWokStation" == "wnt" } {
2286     lappend aTKDefines "WNT"
2287     lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2288   } else {
2289     if { "$aWokStation" == "lin" } {
2290       lappend aTKDefines "LIN"
2291     }
2292     lappend aTKDefines "OCC_CONVERT_SIGNALS"
2293     #lappend aTKDefines "_GNU_SOURCE=1"
2294   }
2295 }
2296
2297 # Define libraries to link using only EXTERNLIB file
2298 proc LibToLinkX {thePackage theDummyName} {
2299   set aToolKits [LibToLink $thePackage]
2300   return $aToolKits
2301 }
2302
2303 # Function to generate Xcode workspace and project files
2304 proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
2305
2306   puts stderr "Generating project files for Xcode"
2307
2308   # Generate projects for toolkits and separate workspace for each module
2309   foreach aModule $theModules {
2310     OS:xcworkspace $aModule $aModule $theOutDir
2311     OS:xcodeproj   $aModule          $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
2312   }
2313
2314   # Generate single workspace "OCCT" containing projects from all modules
2315   if { "$theAllSolution" != "" } {
2316     OS:xcworkspace $theAllSolution $theModules $theOutDir
2317   }
2318 }
2319
2320 # Generates toolkits sections for Xcode workspace file.
2321 proc OS:xcworkspace:toolkits { theModule } {
2322   set aBuff ""
2323
2324   # Adding toolkits for module in workspace.
2325   foreach aToolKit [osutils:tk:sort [${theModule}:toolkits]] {
2326     append aBuff "         <FileRef\n"
2327     append aBuff "            location = \"group:${aToolKit}.xcodeproj\">\n"
2328     append aBuff "         </FileRef>\n"
2329   }
2330
2331   # Adding executables for module, assume one project per cxx file...
2332   foreach aUnit [OS:executable ${theModule}] {
2333     set aUnitLoc $aUnit
2334     set src_files [_get_used_files $aUnit false]
2335     set aSrcFiles {}
2336     foreach s $src_files {
2337       regexp {source ([^\s]+)} $s dummy name
2338       lappend aSrcFiles $name
2339     }
2340     foreach aSrcFile $aSrcFiles {
2341       set aFileExtension [file extension $aSrcFile]
2342       if { $aFileExtension == ".cxx" } {
2343         set aPrjName [file rootname $aSrcFile]
2344         append aBuff "         <FileRef\n"
2345         append aBuff "            location = \"group:${aPrjName}.xcodeproj\">\n"
2346         append aBuff "         </FileRef>\n"
2347       }
2348     }
2349   }
2350
2351   # Removing unnecessary newline character from the end.
2352   set aBuff [string replace $aBuff end end]
2353   return $aBuff
2354 }
2355
2356 # Generates workspace files for Xcode.
2357 proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
2358   # Creating workspace directory for Xcode.
2359   set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
2360   wokUtils:FILES:mkdir $aWorkspaceDir
2361   if { ! [file exists $aWorkspaceDir] } {
2362     puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
2363     return
2364   }
2365
2366   # Creating workspace file.
2367   set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
2368   set aFile [open $aWsFilePath "w"]
2369
2370   # Adding header and section for main Group.
2371   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2372   puts $aFile "<Workspace"
2373   puts $aFile "   version = \"1.0\">"
2374   puts $aFile "   <Group"
2375   puts $aFile "      location = \"container:\""
2376   puts $aFile "      name = \"${theWorkspaceName}\">"
2377
2378   # Adding modules.
2379   if { [llength "$theModules"] > 1 } {
2380     foreach aModule $theModules {
2381       puts $aFile "      <Group"
2382       puts $aFile "         location = \"container:\""
2383       puts $aFile "         name = \"${aModule}\">"
2384       puts $aFile [OS:xcworkspace:toolkits $aModule]
2385       puts $aFile "      </Group>"
2386     }
2387   } else {
2388     puts $aFile [OS:xcworkspace:toolkits $theModules]
2389   }
2390
2391   # Adding footer.
2392   puts $aFile "   </Group>"
2393   puts $aFile "</Workspace>"
2394   close $aFile
2395 }
2396
2397 # Generates Xcode project files.
2398 proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
2399   upvar $theGuidsMap aGuidsMap
2400
2401   set isStatic 0
2402   if { "$theLibType" == "static" } {
2403     set isStatic 1
2404   } elseif { "$thePlatform" == "ios" } {
2405     set isStatic 1
2406   }
2407
2408   set aProjectFiles {}
2409   foreach aModule $theModules {
2410     foreach aToolKit [${aModule}:toolkits] {
2411       lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit     aGuidsMap $isStatic $thePlatform "dylib"]
2412     }
2413     foreach anExecutable [OS:executable ${aModule}] {
2414       lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
2415     }
2416   }
2417   return $aProjectFiles
2418 }
2419
2420 # Generates dependencies section for Xcode project files.
2421 proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids theIsStatic} {
2422   global path
2423   upvar $theGuidsMap         aGuidsMap
2424   upvar $theFileRefSection   aFileRefSection
2425   upvar $theDepsGuids        aDepsGuids
2426   upvar $theDepsRefGuids     aDepsRefGuids
2427
2428   set aBuildFileSection ""
2429   set aUsedToolKits     [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2430   set aDepToolkits      [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]] $theToolKit]
2431
2432   if { "$theTargetType" == "executable" } {
2433     set aFile [osutils:tk:files $theToolKit osutils:compilable 0]
2434     set aProjName [file rootname [file tail $aFile]]
2435     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2436   }
2437
2438   set aLibExt "dylib"
2439   if { $theIsStatic == 1 } {
2440     set aLibExt "a"
2441     if { "$theTargetType" != "executable" } {
2442       return $aBuildFileSection
2443     }
2444   }
2445
2446   osutils:usedOsLibs $theToolKit "mac" aLibs aFrameworks
2447   set aUsedToolKits [concat $aUsedToolKits $aLibs]
2448   set aUsedToolKits [concat $aUsedToolKits $aFrameworks]
2449   foreach tkx $aUsedToolKits {
2450     set aDepLib    "${tkx}_Dep"
2451     set aDepLibRef "${tkx}_DepRef"
2452
2453     if { ! [info exists aGuidsMap($aDepLib)] } {
2454       set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
2455     }
2456     if { ! [info exists aGuidsMap($aDepLibRef)] } {
2457       set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
2458     }
2459
2460     append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
2461     if {[lsearch -nocase $aFrameworks $tkx] == -1} {
2462       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
2463     } else {
2464       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
2465     }
2466     append aDepsGuids        "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
2467     append aDepsRefGuids     "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
2468   }
2469
2470   return $aBuildFileSection
2471 }
2472
2473 # Generates PBXBuildFile and PBXGroup sections for project file.
2474 proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
2475   upvar $theSrcFileRefSection aSrcFileRefSection
2476   upvar $theGroupSection      aGroupSection
2477   upvar $thePackageGuids      aPackagesGuids
2478   upvar $theSrcFileGuids      aSrcFileGuids
2479   upvar $theGuidsMap          aGuidsMap
2480   upvar $theIncPaths          anIncPaths
2481
2482   set listloc [osutils:tk:units $theToolKit]
2483   set resultloc [osutils:justunix $listloc]
2484   set aBuildFileSection ""
2485   set aPackages [lsort -nocase $resultloc]
2486   if { "$theTargetType" == "executable" } {
2487     set aPackages [list "$theToolKit"]
2488   }
2489
2490   # Generating PBXBuildFile, PBXGroup sections and groups for each package.
2491   foreach fxlo $aPackages {
2492     set xlo       $fxlo
2493     set aPackage "${xlo}_Package"
2494     set aSrcFileRefGuids ""
2495     if { ! [info exists aGuidsMap($aPackage)] } {
2496       set aGuidsMap($aPackage) [OS:genGUID "xcd"]
2497     }
2498
2499     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2500     foreach aSrcFile [lsort $aSrcFiles] {
2501       set aFileExt "sourcecode.cpp.cpp"
2502
2503       if { [file extension $aSrcFile] == ".c" } {
2504         set aFileExt "sourcecode.c.c"
2505       } elseif { [file extension $aSrcFile] == ".mm" } {
2506         set aFileExt "sourcecode.cpp.objcpp"
2507       }
2508
2509       if { ! [info exists aGuidsMap($aSrcFile)] } {
2510         set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
2511       }
2512       set aSrcFileRef "${aSrcFile}_Ref"
2513       if { ! [info exists aGuidsMap($aSrcFileRef)] } {
2514         set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
2515       }
2516       if { ! [info exists written([file tail $aSrcFile])] } {
2517         set written([file tail $aSrcFile]) 1
2518         append aBuildFileSection  "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
2519         append aSrcFileRefSection "\t\t$aGuidsMap($aSrcFileRef) = \{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = ${aFileExt}; name = [wokUtils:FILES:wtail $aSrcFile 1]; path = ../../../[wokUtils:FILES:wtail $aSrcFile 3]; sourceTree = \"<group>\"; \};\n"
2520         append aSrcFileGuids      "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
2521         append aSrcFileRefGuids   "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
2522       } else {
2523         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2524       }
2525     }
2526
2527     append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
2528     append aGroupSection "\t\t\tisa = PBXGroup;\n"
2529     append aGroupSection "\t\t\tchildren = (\n"
2530     append aGroupSection $aSrcFileRefGuids
2531     append aGroupSection "\t\t\t);\n"
2532     append aGroupSection "\t\t\tname = $xlo;\n"
2533     append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
2534     append aGroupSection "\t\t\};\n"
2535
2536     # Storing packages IDs for adding them later as a child of toolkit
2537     append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
2538   }
2539
2540   # Removing unnecessary newline character from the end.
2541   set aPackagesGuids [string replace $aPackagesGuids end end]
2542
2543   return $aBuildFileSection
2544 }
2545
2546 # Creates folders structure and all necessary files for Xcode project.
2547 proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
2548   set aPBXBuildPhase "Headers"
2549   set aRunOnlyForDeployment "0"
2550   set aProductType "library.dynamic"
2551   set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
2552   set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
2553   set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
2554   set aTKDefines [list "CSFDB" "OCC_CONVERT_SIGNALS"]
2555
2556   if { "$theTargetType" == "executable" } {
2557     set aPBXBuildPhase "CopyFiles"
2558     set aRunOnlyForDeployment "1"
2559     set aProductType "tool"
2560     set anExecExtension ""
2561     set anExecPrefix ""
2562     set aWrapperExtension ""
2563   } elseif { $theIsStatic == 1 } {
2564     set aProductType "library.static"
2565     set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
2566     set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
2567   }
2568
2569   set aUsername [exec whoami]
2570
2571   # Creation of folders for Xcode projectP.
2572   set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
2573   wokUtils:FILES:mkdir $aToolkitDir
2574   if { ! [file exists $aToolkitDir] } {
2575     puts stderr "Error: Could not create project directory \"$aToolkitDir\""
2576     return
2577   }
2578
2579   set aUserDataDir "${aToolkitDir}/xcuserdata"
2580   wokUtils:FILES:mkdir $aUserDataDir
2581   if { ! [file exists $aUserDataDir] } {
2582     puts stderr "Error: Could not create xcuserdata directorty in \"$aToolkitDir\""
2583     return
2584   }
2585
2586   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
2587   wokUtils:FILES:mkdir $aUserDataDir
2588   if { ! [file exists $aUserDataDir] } {
2589     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$aToolkitDir\"/xcuserdata"
2590     return
2591   }
2592
2593   set aSchemesDir "${aUserDataDir}/xcschemes"
2594   wokUtils:FILES:mkdir $aSchemesDir
2595   if { ! [file exists $aSchemesDir] } {
2596     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
2597     return
2598   }
2599   # End of folders creation.
2600
2601   # Generating GUID for tookit.
2602   upvar $theGuidsMap aGuidsMap
2603   if { ! [info exists aGuidsMap($theToolKit)] } {
2604     set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
2605   }
2606
2607   # Creating xcscheme file for toolkit from template.
2608   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
2609   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
2610   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
2611   set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme"  "w"]
2612   puts $aXcschemeFile $aXcschemeTmpl
2613   close $aXcschemeFile
2614
2615   # Creating xcschememanagement.plist file for toolkit from template.
2616   set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
2617   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
2618   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
2619   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
2620   puts $aPlistFile $aPlistTmpl
2621   close $aPlistFile
2622
2623   # Creating project.pbxproj file for toolkit.
2624   set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
2625   puts $aPbxprojFile "// !\$*UTF8*\$!"
2626   puts $aPbxprojFile "\{"
2627   puts $aPbxprojFile "\tarchiveVersion = 1;"
2628   puts $aPbxprojFile "\tclasses = \{"
2629   puts $aPbxprojFile "\t\};"
2630   puts $aPbxprojFile "\tobjectVersion = 46;"
2631   puts $aPbxprojFile "\tobjects = \{\n"
2632
2633   # Begin PBXBuildFile section
2634   set aPackagesGuids ""
2635   set aGroupSection ""
2636   set aSrcFileRefSection ""
2637   set aSrcFileGuids ""
2638   set aDepsFileRefSection ""
2639   set aDepsGuids ""
2640   set aDepsRefGuids ""
2641   set anIncPaths [list "../../../inc"]
2642   set anLibPaths ""
2643
2644   if { [info exists ::env(CSF_OPT_INC)] } {
2645     set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
2646     foreach anIncCfgPath $anIncCfg {
2647       lappend anIncPaths $anIncCfgPath
2648     }
2649   }
2650   if { [info exists ::env(CSF_OPT_LIB64)] } {
2651     set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
2652     foreach anLibCfgPath $anLibCfg {
2653       lappend anLibPaths $anLibCfgPath
2654     }
2655   }
2656
2657   puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
2658   puts $aPbxprojFile [osutils:xcdtk:deps    $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $theIsStatic]
2659   # End PBXBuildFile section
2660
2661   # Begin PBXFileReference section
2662   set aToolkitLib "lib${theToolKit}.dylib"
2663   set aPath "$aToolkitLib"
2664   if { "$theTargetType" == "executable" } {
2665     set aPath "$theToolKit"
2666   } elseif { $theIsStatic == 1 } {
2667     set aToolkitLib "lib${theToolKit}.a"
2668   }
2669
2670   if { ! [info exists aGuidsMap($aToolkitLib)] } {
2671     set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
2672   }
2673
2674   puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
2675   puts $aPbxprojFile $aSrcFileRefSection
2676   puts $aPbxprojFile $aDepsFileRefSection
2677   # End PBXFileReference section
2678
2679
2680   # Begin PBXFrameworksBuildPhase section
2681   set aTkFrameworks "${theToolKit}_Frameworks"
2682   if { ! [info exists aGuidsMap($aTkFrameworks)] } {
2683     set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
2684   }
2685
2686   puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
2687   puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
2688   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2689   puts $aPbxprojFile "\t\t\tfiles = ("
2690   puts $aPbxprojFile $aDepsGuids
2691   puts $aPbxprojFile "\t\t\t);"
2692   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2693   puts $aPbxprojFile "\t\t\};\n"
2694   # End PBXFrameworksBuildPhase section
2695
2696   # Begin PBXGroup section
2697   set aTkPBXGroup "${theToolKit}_PBXGroup"
2698   if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
2699     set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
2700   }
2701
2702   set aTkSrcGroup "${theToolKit}_SrcGroup"
2703   if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
2704     set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
2705   }
2706
2707   puts $aPbxprojFile $aGroupSection
2708   puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
2709   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2710   puts $aPbxprojFile "\t\t\tchildren = ("
2711   puts $aPbxprojFile $aDepsRefGuids
2712   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
2713   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
2714   puts $aPbxprojFile "\t\t\t);"
2715   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2716   puts $aPbxprojFile "\t\t\};"
2717   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
2718   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2719   puts $aPbxprojFile "\t\t\tchildren = ("
2720   puts $aPbxprojFile $aPackagesGuids
2721   puts $aPbxprojFile "\t\t\t);"
2722   puts $aPbxprojFile "\t\t\tname = \"Source files\";"
2723   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2724   puts $aPbxprojFile "\t\t\};\n"
2725   # End PBXGroup section
2726
2727   # Begin PBXHeadersBuildPhase section
2728   set aTkHeaders "${theToolKit}_Headers"
2729   if { ! [info exists aGuidsMap($aTkHeaders)] } {
2730     set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
2731   }
2732
2733   puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
2734   puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
2735   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2736   puts $aPbxprojFile "\t\t\tfiles = ("
2737   puts $aPbxprojFile "\t\t\t);"
2738   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
2739   puts $aPbxprojFile "\t\t\};\n"
2740   # End PBXHeadersBuildPhase section
2741
2742   # Begin PBXNativeTarget section
2743   set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
2744   if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
2745     set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
2746   }
2747
2748   set aTkSources "${theToolKit}_Sources"
2749   if { ! [info exists aGuidsMap($aTkSources)] } {
2750     set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
2751   }
2752
2753   puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
2754   puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
2755   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
2756   puts $aPbxprojFile "\t\t\tbuildPhases = ("
2757   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
2758   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
2759   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
2760   puts $aPbxprojFile "\t\t\t);"
2761   puts $aPbxprojFile "\t\t\tbuildRules = ("
2762   puts $aPbxprojFile "\t\t\t);"
2763   puts $aPbxprojFile "\t\t\tdependencies = ("
2764   puts $aPbxprojFile "\t\t\t);"
2765   puts $aPbxprojFile "\t\t\tname = $theToolKit;"
2766   puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
2767   puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
2768   puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
2769   puts $aPbxprojFile "\t\t\};\n"
2770   # End PBXNativeTarget section
2771
2772   # Begin PBXProject section
2773   set aTkProjectObj "${theToolKit}_ProjectObj"
2774   if { ! [info exists aGuidsMap($aTkProjectObj)] } {
2775     set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
2776   }
2777
2778   set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
2779   if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
2780     set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
2781   }
2782
2783   puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
2784   puts $aPbxprojFile "\t\t\tisa = PBXProject;"
2785   puts $aPbxprojFile "\t\t\tattributes = \{"
2786   puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
2787   puts $aPbxprojFile "\t\t\t\};"
2788   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
2789   puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
2790   puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
2791   puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
2792   puts $aPbxprojFile "\t\t\tknownRegions = ("
2793   puts $aPbxprojFile "\t\t\t\ten,"
2794   puts $aPbxprojFile "\t\t\t);"
2795   puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
2796   puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
2797   puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
2798   puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
2799   puts $aPbxprojFile "\t\t\ttargets = ("
2800   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
2801   puts $aPbxprojFile "\t\t\t);"
2802   puts $aPbxprojFile "\t\t\};\n"
2803   # End PBXProject section
2804
2805   # Begin PBXSourcesBuildPhase section
2806   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
2807   puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
2808   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2809   puts $aPbxprojFile "\t\t\tfiles = ("
2810   puts $aPbxprojFile $aSrcFileGuids
2811   puts $aPbxprojFile "\t\t\t);"
2812   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2813   puts $aPbxprojFile "\t\t\};\n"
2814   # End PBXSourcesBuildPhase section
2815
2816   # Begin XCBuildConfiguration section
2817   set aTkDebugProject "${theToolKit}_DebugProject"
2818   if { ! [info exists aGuidsMap($aTkDebugProject)] } {
2819     set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
2820   }
2821
2822   set aTkReleaseProject "${theToolKit}_ReleaseProject"
2823   if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
2824     set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
2825   }
2826
2827   set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
2828   if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
2829     set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
2830   }
2831
2832   set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
2833   if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
2834     set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
2835   }
2836
2837   # Debug target
2838   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
2839   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2840   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2841
2842   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
2843   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
2844   if { "$thePlatform" == "ios" } {
2845     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
2846     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
2847     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
2848     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
2849     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
2850   }
2851   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
2852   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
2853   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
2854   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
2855   puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
2856   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
2857   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
2858   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2859   puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
2860   puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
2861   puts $aPbxprojFile "\t\t\t\t);"
2862   puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
2863   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
2864   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
2865   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
2866   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
2867   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
2868   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
2869   if { "$thePlatform" == "ios" } {
2870     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
2871     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
2872   } else {
2873     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
2874   }
2875   puts $aPbxprojFile "\t\t\t\};"
2876
2877   puts $aPbxprojFile "\t\t\tname = Debug;"
2878   puts $aPbxprojFile "\t\t\};"
2879
2880   # Release target
2881   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
2882   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2883   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2884
2885   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
2886   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
2887   if { "$thePlatform" == "ios" } {
2888     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
2889     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
2890     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
2891     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
2892     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
2893   }
2894   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
2895   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
2896   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
2897   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
2898   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
2899   puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
2900   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
2901   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
2902   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
2903   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
2904   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
2905   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
2906   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
2907   if { "$thePlatform" == "ios" } {
2908     puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
2909     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
2910   }
2911   puts $aPbxprojFile "\t\t\t\};"
2912   puts $aPbxprojFile "\t\t\tname = Release;"
2913   puts $aPbxprojFile "\t\t\};"
2914   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
2915   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2916   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2917   puts $aPbxprojFile "${anExecExtension}"
2918   puts $aPbxprojFile "${anExecPrefix}"
2919   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2920   foreach aMacro $aTKDefines {
2921     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
2922   }
2923   puts $aPbxprojFile "\t\t\t\t);"
2924
2925   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
2926   foreach anIncPath $anIncPaths {
2927     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
2928   }
2929   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
2930   puts $aPbxprojFile "\t\t\t\t);"
2931
2932   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
2933   foreach anLibPath $anLibPaths {
2934     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
2935   }
2936   puts $aPbxprojFile "\t\t\t\t);"
2937
2938   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
2939   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
2940   puts $aPbxprojFile "\t\t\t\t);"
2941   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
2942   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
2943   puts $aPbxprojFile "\t\t\t\t);"
2944   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
2945   set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
2946   foreach anIncPath $anIncPaths {
2947     append anUserHeaderSearchPath " ${anIncPath}"
2948   }
2949   append anUserHeaderSearchPath "\";"
2950   puts $aPbxprojFile $anUserHeaderSearchPath
2951   puts $aPbxprojFile "${aWrapperExtension}"
2952   puts $aPbxprojFile "\t\t\t\};"
2953   puts $aPbxprojFile "\t\t\tname = Debug;"
2954   puts $aPbxprojFile "\t\t\};"
2955   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
2956   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2957   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2958   puts $aPbxprojFile "${anExecExtension}"
2959   puts $aPbxprojFile "${anExecPrefix}"
2960   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2961   foreach aMacro $aTKDefines {
2962     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
2963   }
2964   puts $aPbxprojFile "\t\t\t\t);"
2965   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
2966   foreach anIncPath $anIncPaths {
2967     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
2968   }
2969   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
2970   puts $aPbxprojFile "\t\t\t\t);"
2971
2972   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
2973   foreach anLibPath $anLibPaths {
2974     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
2975   }
2976   puts $aPbxprojFile "\t\t\t\t);"
2977
2978   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
2979   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
2980   puts $aPbxprojFile "\t\t\t\t);"
2981   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
2982   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
2983   puts $aPbxprojFile "\t\t\t\t);"
2984   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
2985   puts $aPbxprojFile $anUserHeaderSearchPath
2986   puts $aPbxprojFile "${aWrapperExtension}"
2987   puts $aPbxprojFile "\t\t\t\};"
2988   puts $aPbxprojFile "\t\t\tname = Release;"
2989   puts $aPbxprojFile "\t\t\};\n"
2990   # End XCBuildConfiguration section
2991
2992   # Begin XCConfigurationList section
2993   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
2994   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
2995   puts $aPbxprojFile "\t\tbuildConfigurations = ("
2996   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
2997   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
2998   puts $aPbxprojFile "\t\t\t);"
2999   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3000   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3001   puts $aPbxprojFile "\t\t\};"
3002   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
3003   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3004   puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
3005   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
3006   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
3007   puts $aPbxprojFile "\t\t\t);"
3008   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3009   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3010   puts $aPbxprojFile "\t\t\};\n"
3011   # End XCConfigurationList section
3012
3013   puts $aPbxprojFile "\t\};"
3014   puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3015   puts $aPbxprojFile "\}"
3016
3017   close $aPbxprojFile
3018 }
3019
3020 proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3021   set aUsername [exec whoami]
3022
3023   # Creating folders for Xcode project file.
3024   set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3025   wokUtils:FILES:mkdir $anExecutableDir
3026   if { ! [file exists $anExecutableDir] } {
3027     puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3028     return
3029   }
3030
3031   set aUserDataDir "${anExecutableDir}/xcuserdata"
3032   wokUtils:FILES:mkdir $aUserDataDir
3033   if { ! [file exists $aUserDataDir] } {
3034     puts stderr "Error: Could not create xcuserdata directorty in \"$anExecutableDir\""
3035     return
3036   }
3037
3038   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3039   wokUtils:FILES:mkdir $aUserDataDir
3040   if { ! [file exists $aUserDataDir] } {
3041     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$anExecutableDir\"/xcuserdata"
3042     return
3043   }
3044
3045   set aSchemesDir "${aUserDataDir}/xcschemes"
3046   wokUtils:FILES:mkdir $aSchemesDir
3047   if { ! [file exists $aSchemesDir] } {
3048     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3049     return
3050   }
3051   # End folders creation.
3052
3053   # Generating GUID for tookit.
3054   upvar $theGuidsMap aGuidsMap
3055   if { ! [info exists aGuidsMap($theExecutable)] } {
3056     set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3057   }
3058
3059   # Creating xcscheme file for toolkit from template.
3060   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3061   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3062   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3063   set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme"  "w"]
3064   puts $aXcschemeFile $aXcschemeTmpl
3065   close $aXcschemeFile
3066
3067   # Creating xcschememanagement.plist file for toolkit from template.
3068   set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3069   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3070   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3071   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
3072   puts $aPlistFile $aPlistTmpl
3073   close $aPlistFile
3074 }