0027055: Configuration, genconf.tcl - reduce window height to fit into smaller screens
[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       if { "$theOS" == "qnx" } {
1113         # CSF_ThreadLibs - pthread API is part og libc on QNX
1114         set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
1115         set aLibsMap(CSF_TclLibs)    "tcl8.6"
1116         set aLibsMap(CSF_TclTkLibs)  "tk8.6"
1117       } else {
1118         set aLibsMap(CSF_ThreadLibs) "pthread rt"
1119         set aLibsMap(CSF_OpenGlLibs) "GL"
1120         set aLibsMap(CSF_TclLibs)    "tcl8.6"
1121         set aLibsMap(CSF_TclTkLibs)  "X11 tk8.6"
1122         set aLibsMap(CSF_XwLibs)     "X11 Xext Xmu Xi"
1123         set aLibsMap(CSF_MotifLibs)  "X11"
1124       }
1125     }
1126
1127     # optional 3rd-parties
1128     if { "$::HAVE_TBB" == "true" } {
1129       set aLibsMap(CSF_TBB)        "tbb tbbmalloc"
1130     }
1131     if { "$::HAVE_FREEIMAGE" == "true" } {
1132       set aLibsMap(CSF_FreeImagePlus)  "freeimage"
1133     }
1134     if { "$::HAVE_GL2PS" == "true" } {
1135       set aLibsMap(CSF_GL2PS)      "gl2ps"
1136     }
1137     if { "$::HAVE_VTK" == "true" } {
1138       set aLibsMap(CSF_VTK)         [osutils:vtkCsf "unix"]
1139     }
1140   }
1141 }
1142
1143 # Returns string of library dependencies for generation of Visual Studio project or make lists.
1144 proc osutils:vtkCsf {{theOS ""}} {
1145   set aVtkVer "6.1"
1146
1147   set aLibSuffix ""
1148   set aPathSplitter ":"
1149   
1150   if {"$theOS" == "wnt"} {
1151     set aPathSplitter ";"
1152     set aLibSuffix ".lib"
1153   }
1154
1155   set anOptIncs [split $::env(CSF_OPT_INC) "$aPathSplitter"]
1156   foreach anIncItem $anOptIncs {
1157     if {[regexp -- "vtk-(.*)$" [file tail $anIncItem] dummy aFoundVtkVer]} {
1158       set aVtkVer $aFoundVtkVer
1159     }
1160   }
1161
1162   set aLibArray [list vtkCommonCore vtkCommonDataModel vtkCommonExecutionModel vtkCommonMath vtkCommonTransforms vtkRenderingCore \
1163                       vtkRenderingOpenGL  vtkFiltersGeneral vtkIOCore vtkIOImage vtkImagingCore vtkInteractionStyle]
1164
1165   # Additional suffices for the libraries
1166   set anIdx 0
1167   foreach anItem $aLibArray {
1168     lset aLibArray $anIdx $anItem-$aVtkVer$aLibSuffix
1169     incr anIdx
1170   }
1171
1172   return [join $aLibArray " "]
1173 }
1174
1175 # @param theLibsList   - dependencies (libraries  list)
1176 # @param theFrameworks - dependencies (frameworks list, OS X specific)
1177 proc osutils:usedOsLibs { theToolKit theOS theLibsList theFrameworks } {
1178   global path
1179   upvar $theLibsList   aLibsList
1180   upvar $theFrameworks aFrameworks
1181   set aLibsList   [list]
1182   set aFrameworks [list]
1183
1184   osutils:csfList $theOS aLibsMap aFrmsMap
1185
1186   foreach aCsfElem [osutils:tk:csfInExternlib "$path/src/${theToolKit}/EXTERNLIB"] {
1187     if [info exists aLibsMap($aCsfElem)] {
1188       foreach aLib [split "$aLibsMap($aCsfElem)"] {
1189         if { [lsearch $aLibsList $aLib] == "-1" } {
1190           lappend aLibsList $aLib
1191         }
1192       }
1193     }
1194     if [info exists aFrmsMap($aCsfElem)] {
1195       foreach aFrm [split "$aFrmsMap($aCsfElem)"] {
1196         if { [lsearch $aFrameworks $aFrm] == "-1" } {
1197           lappend aFrameworks $aFrm
1198         }
1199       }
1200     }
1201   }
1202 }
1203
1204 # Returns liste of UD in a toolkit. tkloc is a full path wok.
1205 proc osutils:tk:units { tkloc } {
1206   global path
1207   set l {}
1208   set PACKAGES "$path/src/$tkloc/PACKAGES"
1209   foreach u [wokUtils:FILES:FileToList $PACKAGES] {
1210     if {[file isdirectory "$path/src/$u"]} {
1211       lappend l $u
1212     }
1213   }
1214   if { $l == {} } {
1215     ;#puts stderr "Warning. No devunit included in $tkloc"
1216   }
1217   return $l
1218 }
1219
1220 proc osutils:justwnt { listloc } {
1221   # ImageUtility is required for support for old (<6.5.4) versions of OCCT
1222   set goaway [list Xdps Xw  ImageUtility WOKUnix]
1223   return [osutils:juststation $goaway $listloc]
1224 }
1225
1226 # remove from listloc OpenCascade units indesirables on NT
1227 proc osutils:juststation {goaway listloc} {
1228   global path
1229   set lret {}
1230   foreach u $listloc {
1231     if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1232      || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1233       lappend lret $u
1234     }
1235   }
1236   return $lret
1237 }
1238
1239 # intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1240 # The first list is everything in the first list that wasn't in the second,
1241 # the second list contains the intersection of the two lists, the third list contains everything
1242 # in the second list that wasn't in the first.
1243 proc osutils:intersect3 {list1 list2} {
1244   set la1(0) {} ; unset la1(0)
1245   set lai(0) {} ; unset lai(0)
1246   set la2(0) {} ; unset la2(0)
1247   foreach v $list1 {
1248     set la1($v) {}
1249   }
1250   foreach v $list2 {
1251     set la2($v) {}
1252   }
1253   foreach elem [concat $list1 $list2] {
1254     if {[info exists la1($elem)] && [info exists la2($elem)]} {
1255       unset la1($elem)
1256       unset la2($elem)
1257       set lai($elem) {}
1258     }
1259   }
1260   list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1261 }
1262
1263 # Prepare relative path
1264 proc relativePath {thePathFrom thePathTo} {
1265   if { [file isdirectory "$thePathFrom"] == 0 } {
1266     return ""
1267   }
1268
1269   set aPathFrom [file normalize "$thePathFrom"]
1270   set aPathTo   [file normalize "$thePathTo"]
1271
1272   set aCutedPathFrom "${aPathFrom}/dummy"
1273   set aRelatedDeepPath ""
1274
1275   while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1276     set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1277     # does aPathTo contain aCutedPathFrom?
1278     regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1279     if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1280       if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1281         set aPathTo ".${aPathTo}"
1282       } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1283         set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1284       }
1285       regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1286       regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1287       return $aPathToAfterCut
1288     }
1289     set aRelatedDeepPath "$aRelatedDeepPath../"
1290
1291   }
1292
1293   return $thePathTo
1294 }
1295
1296 proc wokUtils:EASY:bs1 { s } {
1297     regsub -all {/} $s {\\} r
1298     return $r
1299 }
1300
1301 # Returs for a full path the liste of n last directory part
1302 # n = 1 => tail
1303 # n = 2 => dir/file.c
1304 # n = 3 => sdir/dir/file.c
1305 # etc..
1306 proc wokUtils:FILES:wtail { f n } {
1307     set ll [expr [llength [set lif [file split $f]]] -$n]
1308     return [join [lrange $lif $ll end] /]
1309 }
1310
1311 # Generate entry for one source file in Visual Studio 10 project file
1312 proc osutils:vcxproj:file { vcversion file params } {
1313   append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1314   if { $params != "" } {
1315     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1316   }
1317
1318   if { $params != "" } {
1319     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1320   }
1321
1322   if { $params != "" } {
1323     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1324   }
1325
1326   if { $params != "" } {
1327     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1328   }
1329
1330   append text "    </ClCompile>\n"
1331   return $text
1332 }
1333
1334 # Generate Visual Studio 2010 project filters file
1335 proc osutils:vcxproj:filters { dir proj theFilesMap } {
1336   upvar $theFilesMap aFilesMap
1337
1338   # header
1339   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1340   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1341
1342   # list of "filters" (units)
1343   append text "  <ItemGroup>\n"
1344   append text "    <Filter Include=\"Source files\">\n"
1345   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1346   append text "    </Filter>\n"
1347   foreach unit $aFilesMap(units) {
1348     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1349     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1350     append text "    </Filter>\n"
1351   }
1352   append text "  </ItemGroup>\n"
1353
1354   # list of files
1355   append text "  <ItemGroup>\n"
1356   foreach unit $aFilesMap(units) {
1357     foreach file $aFilesMap($unit) {
1358       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1359       append text "      <Filter>Source files\\${unit}</Filter>\n"
1360       append text "    </ClCompile>\n"
1361     }
1362   }
1363   append text "  </ItemGroup>\n"
1364
1365   # end
1366   append text "</Project>"
1367
1368   # write file
1369   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1370   fconfigure $fp -translation crlf
1371   puts $fp $text
1372   close $fp
1373
1374   return ${proj}.vcxproj.filters
1375 }
1376
1377 # Generate Visual Studio 2011 project filters file
1378 proc osutils:vcx1proj:filters { dir proj theFilesMap } {
1379   upvar $theFilesMap aFilesMap
1380
1381   # header
1382   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1383   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1384
1385   # list of "filters" (units)
1386   append text "  <ItemGroup>\n"
1387   append text "    <Filter Include=\"Source files\">\n"
1388   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1389   append text "    </Filter>\n"
1390   foreach unit $aFilesMap(units) {
1391     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1392     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1393     append text "    </Filter>\n"
1394   }
1395   append text "  </ItemGroup>\n"
1396
1397   # list of files
1398   append text "  <ItemGroup>\n"
1399   foreach unit $aFilesMap(units) {
1400     foreach file $aFilesMap($unit) {
1401       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1402       append text "      <Filter>Source files\\${unit}</Filter>\n"
1403       append text "    </ClCompile>\n"
1404     }
1405   }
1406   append text "  </ItemGroup>\n"
1407
1408   append text "  <ItemGroup>\n"
1409   append text "    <ResourceCompile Include=\"${proj}.rc\" />"
1410   append text "  </ItemGroup>\n"
1411
1412   # end
1413   append text "</Project>"
1414
1415   # write file
1416   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1417   fconfigure $fp -translation crlf
1418   puts $fp $text
1419   close $fp
1420
1421   return ${proj}.vcxproj.filters
1422 }
1423
1424 # Generate RC file content for ToolKit from template
1425 proc osutils:readtemplate:rc {theOutDir theToolKit} {
1426   global path
1427   set aLoc "$path/adm/templates/template_dll.rc"
1428   set aBody [wokUtils:FILES:FileToString $aLoc]
1429   regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1430
1431   set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1432   fconfigure $aFile -translation lf
1433   puts $aFile $aBody
1434   close $aFile
1435   return "${theOutDir}/${theToolKit}.rc"
1436 }
1437
1438 # Generate Visual Studio project file for ToolKit
1439 proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1440   if { $theProjTmpl == {} } {set theProjTmpl [osutils:vcproj:readtemplate $theVcVer 0]}
1441
1442   set l_compilable [osutils:compilable]
1443   regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1444
1445   upvar $theGuidsMap aGuidsMap
1446   if { ! [info exists aGuidsMap($theToolKit)] } {
1447     set aGuidsMap($theToolKit) [OS:genGUID]
1448   }
1449   regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1450
1451   set aCommonUsedTK [list]
1452   foreach tkx [osutils:commonUsedTK  $theToolKit] {
1453     lappend aCommonUsedTK "${tkx}.lib"
1454   }
1455
1456   osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
1457   set aUsedToolKits [concat $aCommonUsedTK $aLibs]
1458
1459   # correct names of referred third-party libraries that are named with suffix
1460   # depending on VC version
1461   regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1462
1463   # and put this list to project file
1464   #puts "$theToolKit requires  $aUsedToolKits"
1465   if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1466     set aUsedToolKits [join $aUsedToolKits {;}]
1467   }
1468   regsub -all -- {__TKDEP__} $theProjTmpl $aUsedToolKits theProjTmpl
1469
1470   set anIncPaths "..\\..\\..\\inc"
1471   set aTKDefines ""
1472   set aFilesSection ""
1473   set aVcFilesX(units) ""
1474   set listloc [osutils:tk:units $theToolKit]
1475   set resultloc [osutils:justwnt $listloc]
1476   if [array exists written] { unset written }
1477   #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1478   #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1479   #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1480   #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1481   set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1482   set fxloparamfc   [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1483   set fxloparam ""
1484   foreach fxlo $resultloc {
1485     set xlo $fxlo
1486     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
1487         set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
1488     if {$fxlo_cmplrs_options_cxx == ""} {
1489       set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1490     }
1491         set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1492     if {$fxlo_cmplrs_options_c == ""} {
1493       set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1494     }
1495     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1496     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1497         #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1498         #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo  CXX"
1499         #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1500         #puts "\t6 [wokparam -v %CMPLRS_C_Options   $fxlo] $fxlo  C"
1501     set needparam ""
1502     foreach partopt $fxloparam {
1503       if {[string first "-I" $partopt] == "0"} {
1504         # this is an additional includes search path
1505         continue
1506       }
1507       set needparam "$needparam $partopt"
1508     }
1509
1510     # Format of projects in vc10+ is different from vc7-9
1511     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1512       foreach aSrcFile [lsort $aSrcFiles] {
1513         if { ![info exists written([file tail $aSrcFile])] } {
1514           set written([file tail $aSrcFile]) 1
1515           append aFilesSection [osutils:vcxproj:file $theVcVer $aSrcFile $needparam]
1516         } else {
1517           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1518         }
1519         if { ! [info exists aVcFilesX($xlo)] } { lappend aVcFilesX(units) $xlo }
1520         lappend aVcFilesX($xlo) $aSrcFile
1521       }
1522     } else {
1523       append aFilesSection "\t\t\t<Filter\n"
1524       append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1525       append aFilesSection "\t\t\t\t>\n"
1526       foreach aSrcFile [lsort $aSrcFiles] {
1527         if { ![info exists written([file tail $aSrcFile])] } {
1528           set written([file tail $aSrcFile]) 1
1529           append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1530         } else {
1531           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1532         }
1533       }
1534       append aFilesSection "\t\t\t</Filter>\n"
1535     }
1536
1537     # macros
1538     append aTKDefines ";__${xlo}_DLL"
1539     # common includes
1540 #    append anIncPaths ";..\\..\\..\\src\\${xlo}"
1541   }
1542
1543   regsub -all -- {__TKINC__}  $theProjTmpl $anIncPaths theProjTmpl
1544   regsub -all -- {__TKDEFS__} $theProjTmpl $aTKDefines theProjTmpl
1545   regsub -all -- {__FILES__}  $theProjTmpl $aFilesSection theProjTmpl
1546
1547   # write file
1548   set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1549   fconfigure $aFile -translation crlf
1550   puts $aFile $theProjTmpl
1551   close $aFile
1552
1553   # write filters file for vc10+
1554   if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" || "$theVcVer" == "vc9" } {
1555     # nothing
1556   } elseif { "$theVcVer" == "vc10" } {
1557     lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesX]
1558   } else {
1559     lappend aVcFiles [osutils:vcx1proj:filters $theOutDir $theToolKit aVcFilesX]
1560   }
1561
1562   # write resource file
1563   lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1564
1565   return $aVcFiles
1566 }
1567
1568 # for a unit returns a map containing all its file in the current
1569 # workbench
1570 # local = 1 only local files
1571 proc osutils:tk:loadunit { loc map } {
1572   #puts $loc
1573   upvar $map TLOC
1574   catch { unset TLOC }
1575   set lfiles [_get_used_files $loc]
1576   foreach f $lfiles {
1577     #puts "\t$f"
1578     set t [lindex $f 0]
1579     set p [lindex $f 2]
1580     if [info exists TLOC($t)] {
1581       set l $TLOC($t)
1582       lappend l $p
1583       set TLOC($t) $l
1584     } else {
1585       set TLOC($t) $p
1586     }
1587   }
1588   return
1589 }
1590
1591 # Returns the list of all compilable files name in a toolkit, or devunit of any type
1592 # Call unit filter on units name to accept or reject a unit
1593 # Tfiles lists for each unit the type of file that can be compiled.
1594 proc osutils:tk:files { tkloc  {l_compilable {} } {justail 1} {unitfilter {}} } {
1595   global path
1596   set Tfiles(source,nocdlpack)     {source pubinclude}
1597   set Tfiles(source,toolkit)       {}
1598   set Tfiles(source,executable)    {source pubinclude}
1599   set listloc [concat [osutils:tk:units $tkloc] $tkloc]
1600   #puts " listloc = $listloc"
1601   if { $l_compilable == {} } {
1602     set l_comp [list .c .cxx .cpp]
1603   } else {
1604     set l_comp [$l_compilable]
1605   }
1606   if { $unitfilter == {} } {
1607     set resultloc $listloc
1608   } else {
1609     set resultloc [$unitfilter $listloc]
1610   }
1611   set lret {}
1612   foreach loc $resultloc {
1613     set utyp [_get_type $loc]
1614     #puts "\"$utyp\" \"$loc\""
1615     switch $utyp {
1616          "t" { set utyp "toolkit" }
1617          "n" { set utyp "nocdlpack" }
1618          "x" { set utyp "executable" }
1619     }
1620     if [array exists map] { unset map }
1621     osutils:tk:loadunit $loc map
1622     #puts " loc = $loc === > [array names map]"
1623     set LType $Tfiles(source,${utyp})
1624     foreach typ [array names map] {
1625       if { [lsearch $LType $typ] == -1 } {
1626         unset map($typ)
1627       }
1628     }
1629     foreach type [array names map] {
1630       #puts $type
1631       foreach f $map($type) {
1632         #puts $f
1633         if { [lsearch $l_comp [file extension $f]] != -1 } {
1634           if { $justail == 1 } {
1635             if {$type == "source"} {
1636               if {[lsearch $lret "@top_srcdir@/src/$loc/[file tail $f]"] == -1} {
1637                 lappend lret @top_srcdir@/src/$loc/[file tail $f]
1638               }
1639             }
1640           } else {
1641             lappend lret $f
1642           }
1643         }
1644       }
1645     }
1646   }
1647   return $lret
1648 }
1649
1650 # Generate Visual Studio project file for executable
1651 proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1652   global path
1653   set aVcFiles {}
1654   foreach f [osutils:tk:files $theToolKit osutils:compilable 0] {
1655     if { $theProjTmpl == {} } {
1656       set aProjTmpl [osutils:vcproj:readtemplate $theVcVer 1]
1657     } else {
1658       set aProjTmpl $theProjTmpl
1659     }
1660     set aProjName [file rootname [file tail $f]]
1661     set l_compilable [osutils:compilable]
1662     regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
1663
1664     upvar $theGuidsMap aGuidsMap
1665     if { ! [info exists aGuidsMap($aProjName)] } {
1666       set aGuidsMap($aProjName) [OS:genGUID]
1667     }
1668     regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
1669
1670     set aCommonUsedTK [list]
1671     foreach tkx [osutils:commonUsedTK  $theToolKit] {
1672       lappend aCommonUsedTK "${tkx}.lib"
1673     }
1674
1675     osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
1676     set aUsedToolKits [concat $aCommonUsedTK $aLibs]
1677
1678     # correct names of referred third-party libraries that are named with suffix
1679     # depending on VC version
1680     regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1681
1682 #    puts "$aProjName requires  $aUsedToolKits"
1683     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1684       set aUsedToolKits [join $aUsedToolKits {;}]
1685     }
1686     regsub -all -- {__TKDEP__} $aProjTmpl $aUsedToolKits aProjTmpl
1687
1688     set aFilesSection ""
1689     set aVcFilesX(units) ""
1690
1691     if { ![info exists written([file tail $f])] } {
1692       set written([file tail $f]) 1
1693
1694       if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1695         append aFilesSection [osutils:vcxproj:file $theVcVer $f ""]
1696         if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
1697         lappend aVcFilesX($theToolKit) $f
1698       } else {
1699         append aFilesSection "\t\t\t<Filter\n"
1700         append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
1701         append aFilesSection "\t\t\t\t>\n"
1702         append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
1703         append aFilesSection "\t\t\t</Filter>"
1704       }
1705     } else {
1706       puts "Warning : in vcproj there are than one occurences for [file tail $f]"
1707     }
1708     #puts "$aProjTmpl $aFilesSection"
1709     set aTKDefines ";__${theToolKit}_DLL"
1710     set anIncPaths "..\\..\\..\\inc"
1711     regsub -all -- {__TKINC__}  $aProjTmpl $anIncPaths    aProjTmpl
1712     regsub -all -- {__TKDEFS__} $aProjTmpl $aTKDefines    aProjTmpl
1713     regsub -all -- {__FILES__}  $aProjTmpl $aFilesSection aProjTmpl
1714     regsub -all -- {__CONF__}   $aProjTmpl Application    aProjTmpl
1715
1716     regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
1717
1718     set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
1719     fconfigure $aFile -translation crlf
1720     puts $aFile $aProjTmpl
1721     close $aFile
1722
1723     set aCommonSettingsFile "$aVcFilePath.user"
1724     lappend aVcFiles $aVcFilePath
1725
1726     # write filters file for vc10
1727     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1728       lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesX]
1729     }
1730
1731     set aCommonSettingsFileTmpl ""
1732     if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
1733       # nothing
1734     } elseif { "$theVcVer" == "vc9" } {
1735       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$path/adm/templates/vcproj.user.vc9x"]
1736     } else {
1737       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$path/adm/templates/vcxproj.user.vc10x"]
1738     }
1739     if { "$aCommonSettingsFileTmpl" != "" } {
1740       regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $theVcVer aCommonSettingsFileTmpl
1741
1742       set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
1743       fconfigure $aFile -translation crlf
1744       puts $aFile $aCommonSettingsFileTmpl
1745       close $aFile
1746
1747       lappend aVcFiles "$aCommonSettingsFile"
1748     }
1749   }
1750   return $aVcFiles
1751 }
1752
1753 # Generate entry for one source file in Visual Studio 7 - 9 project file
1754 proc osutils:vcproj:file { theVcVer theFile theOptions } {
1755   append aText "\t\t\t\t<File\n"
1756   append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1757   if { $theOptions == "" } {
1758     append aText "\t\t\t\t</File>\n"
1759     return $aText
1760   }
1761
1762   append aText "\t\t\t\t\t<FileConfiguration\n"
1763   append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
1764   append aText "\t\t\t\t\t\t<Tool\n"
1765   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1766   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1767   foreach aParam $theOptions {
1768     append aText "$aParam "
1769   }
1770   append aText "\"\n"
1771   append aText "\t\t\t\t\t\t/>\n"
1772   append aText "\t\t\t\t\t</FileConfiguration>\n"
1773
1774   append aText "\t\t\t\t\t<FileConfiguration\n"
1775   append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
1776   append aText "\t\t\t\t\t\t<Tool\n"
1777   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1778   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1779   foreach aParam $theOptions {
1780     append aText "$aParam "
1781   }
1782   append aText "\"\n"
1783   append aText "\t\t\t\t\t\t/>\n"
1784   append aText "\t\t\t\t\t</FileConfiguration>\n"
1785   if { "$theVcVer" == "vc7" } {
1786     append aText "\t\t\t\t</File>\n"
1787     return $aText
1788   }
1789
1790   append aText "\t\t\t\t\t<FileConfiguration\n"
1791   append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
1792   append aText "\t\t\t\t\t\t<Tool\n"
1793   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1794   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1795   foreach aParam $theOptions {
1796     append aText "$aParam "
1797   }
1798   append aText "\"\n"
1799   append aText "\t\t\t\t\t\t/>\n"
1800   append aText "\t\t\t\t\t</FileConfiguration>\n"
1801
1802   append aText "\t\t\t\t\t<FileConfiguration\n"
1803   append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
1804   append aText "\t\t\t\t\t\t<Tool\n"
1805   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1806   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1807   foreach aParam $theOptions {
1808     append aText "$aParam "
1809   }
1810   append aText "\"\n"
1811   append aText "\t\t\t\t\t\t/>\n"
1812   append aText "\t\t\t\t\t</FileConfiguration>\n"
1813
1814   append aText "\t\t\t\t</File>\n"
1815   return $aText
1816 }
1817
1818 proc wokUtils:FILES:mkdir { d } {
1819     global tcl_version
1820     regsub -all {\.[^.]*} $tcl_version "" major
1821     if { $major == 8 } {
1822         file mkdir $d
1823     } else {
1824         if ![file exists $d] {
1825             if { "[info command mkdir]" == "mkdir" } {
1826                 mkdir -path $d
1827             } else {
1828                 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
1829             }
1830         }
1831     }
1832     if [file exists $d] {
1833         return $d
1834     } else {
1835         return {}
1836     }
1837 }
1838
1839 # remove from listloc OpenCascade units indesirables on Unix
1840 proc osutils:justunix { listloc } {
1841   if { "$::tcl_platform(os)" == "Darwin" } {
1842     set goaway [list Xw WNT]
1843   } else {
1844     set goaway [list WNT]
1845   }
1846   return [osutils:juststation $goaway $listloc]
1847 }
1848
1849
1850 ####### CODEBLOCK ###################################################################
1851 # Function to generate Code Blocks workspace and project files
1852 proc OS:MKCBP { theOutDir {theModules {}} {theAllSolution ""} } {
1853   puts stderr "Generating project files for Code Blocks"
1854
1855   # Generate projects for toolkits and separate workspace for each module
1856   foreach aModule $theModules {
1857     OS:cworkspace $aModule $aModule $theOutDir
1858     OS:cbp        $aModule          $theOutDir
1859   }
1860
1861   # Generate single workspace "OCCT" containing projects from all modules
1862   if { "$theAllSolution" != "" } {
1863     OS:cworkspace $theAllSolution $theModules $theOutDir
1864   }
1865
1866   puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
1867 }
1868
1869 # Generate Code Blocks projects
1870 proc OS:cbp { theModules theOutDir } {
1871   set aProjectFiles {}
1872   foreach aModule $theModules {
1873     foreach aToolKit [${aModule}:toolkits] {
1874       lappend aProjectFiles [osutils:cbptk $theOutDir $aToolKit ]
1875     }
1876     foreach anExecutable [OS:executable ${aModule}] {
1877       lappend aProjectFiles [osutils:cbpx  $theOutDir $anExecutable]
1878     }
1879   }
1880   return $aProjectFiles
1881 }
1882
1883 # Generate Code::Blocks project file for ToolKit
1884 proc osutils:cbptk { theOutDir theToolKit } {
1885   set aUsedToolKits [list]
1886   set aFrameworks   [list]
1887   set anIncPaths    [list]
1888   set aTKDefines    [list]
1889   set aTKSrcFiles   [list]
1890
1891   osutils:tkinfo "../../.." $theToolKit aUsedToolKits aFrameworks anIncPaths aTKDefines aTKSrcFiles
1892
1893   return [osutils:cbp $theOutDir $theToolKit $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines]
1894 }
1895
1896 # Generates Code Blocks workspace.
1897 proc OS:cworkspace { theSolName theModules theOutDir } {
1898   global path
1899   set aWsFilePath "${theOutDir}/${theSolName}.workspace"
1900   set aFile [open $aWsFilePath "w"]
1901   set isActiveSet 0
1902   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
1903   puts $aFile "<CodeBlocks_workspace_file>"
1904   puts $aFile "\t<Workspace title=\"${theSolName}\">"
1905
1906   # collect list of projects to be created
1907   foreach aModule $theModules {
1908     # toolkits
1909     foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
1910       set aDependencies [LibToLink $aToolKit]
1911       if { [llength $aDependencies] == 0 } {
1912         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
1913       } else {
1914         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
1915         foreach aDepTk $aDependencies {
1916           puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
1917         }
1918         puts $aFile "\t\t</Project>"
1919       }
1920     }
1921
1922     # executables, assume one project per cxx file...
1923     foreach aUnit [OS:executable ${aModule}] {
1924       set aUnitLoc $aUnit
1925       set src_files [_get_used_files $aUnit false]
1926       set aSrcFiles {}
1927       foreach s $src_files { 
1928         regexp {source ([^\s]+)} $s dummy name
1929         lappend aSrcFiles $name
1930       }
1931       foreach aSrcFile $aSrcFiles {
1932         set aFileExtension [file extension $aSrcFile]
1933         if { $aFileExtension == ".cxx" } {
1934           set aPrjName [file rootname $aSrcFile]
1935           set aDependencies [list]
1936           if {[file isdirectory $path/src/$aUnitLoc]} {
1937             set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
1938           }
1939           set anActiveState ""
1940           if { $isActiveSet == 0 } {
1941             set anActiveState " active=\"1\""
1942             set isActiveSet 1
1943           }
1944           if { [llength $aDependencies] == 0 } {
1945             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
1946           } else {
1947             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
1948             foreach aDepTk $aDependencies {
1949               puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
1950             }
1951             puts $aFile "\t\t</Project>"
1952           }
1953         }
1954       }
1955     }
1956   }
1957
1958   puts $aFile "\t</Workspace>"
1959   puts $aFile "</CodeBlocks_workspace_file>"
1960   close $aFile
1961
1962   return $aWsFilePath
1963 }
1964
1965 # Generate Code::Blocks project file for Executable
1966 proc osutils:cbpx { theOutDir theToolKit } {
1967   global path targetStation
1968   set aWokStation "$targetStation"
1969   set aWokArch    "$::env(ARCH)"
1970
1971   set aCbpFiles {}
1972   foreach aSrcFile [osutils:tk:files $theToolKit osutils:compilable 0] {
1973     # collect list of referred libraries to link with
1974     set aUsedToolKits [list]
1975     set aFrameworks   [list]
1976     set anIncPaths    [list]
1977     set aTKDefines    [list]
1978     set aTKSrcFiles   [list]
1979     set aProjName [file rootname [file tail $aSrcFile]]
1980
1981     osutils:usedOsLibs $theToolKit "$aWokStation" aUsedToolKits aFrameworks
1982     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
1983     foreach tkx $aDepToolkits {
1984       if {[_get_type $tkx] == "t"} {
1985         lappend aUsedToolKits "${tkx}"
1986       }
1987       if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
1988         lappend aUsedToolKits "${tkx}"
1989       }
1990     }
1991
1992     set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
1993     if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
1994       set isExecutable "false"
1995     } else {
1996       set isExecutable "true"
1997     }
1998
1999     if { ![info exists written([file tail $aSrcFile])] } {
2000       set written([file tail $aSrcFile]) 1
2001       lappend aTKSrcFiles $aSrcFile
2002     } else {
2003       puts "Warning : in cbp there are more than one occurences for [file tail $aSrcFile]"
2004     }
2005
2006     # macros for correct DLL exports
2007     if { "$aWokStation" == "wnt" } {
2008       lappend aTKDefines "__${theToolKit}_DLL"
2009     }
2010
2011     # common include paths
2012     lappend anIncPaths "../../../inc"
2013
2014     # extra macros
2015     if { "$aWokStation" == "wnt" } {
2016       lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2017     } else {
2018       lappend aTKDefines "OCC_CONVERT_SIGNALS"
2019       #lappend aTKDefines "_GNU_SOURCE=1"
2020     }
2021
2022     lappend aCbpFiles [osutils:cbp $theOutDir $aProjName $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines $isExecutable]
2023   }
2024
2025   return $aCbpFiles
2026 }
2027
2028 proc osutils:optinal_libs { } {
2029   return [list tbb.lib tbbmalloc.lib FreeImage.lib FreeImagePlus.lib gl2ps.lib]
2030 }
2031
2032 # This function intended to generate Code::Blocks project file
2033 # @param theOutDir     - output directory to place project file
2034 # @param theProjName   - project name
2035 # @param theSrcFiles   - list of source files
2036 # @param theLibsList   - dependencies (libraries  list)
2037 # @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2038 # @param theIncPaths   - header search paths
2039 # @param theDefines    - compiler macro definitions
2040 # @param theIsExe      - flag to indicate executable / library target
2041 proc osutils:cbp { theOutDir theProjName theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2042   global targetStation
2043   set aWokStation "$targetStation"
2044   set aWokArch    "$::env(ARCH)"
2045
2046   set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2047   set aFile [open $aCbpFilePath "w"]
2048   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2049   puts $aFile "<CodeBlocks_project_file>"
2050   puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2051   puts $aFile "\t<Project>"
2052   puts $aFile "\t\t<Option title=\"$theProjName\" />"
2053   puts $aFile "\t\t<Option pch_mode=\"2\" />"
2054   if { "$aWokStation" == "wnt" } {
2055     puts $aFile "\t\t<Option compiler=\"msvc8\" />"
2056   } else {
2057     puts $aFile "\t\t<Option compiler=\"gcc\" />"
2058   }
2059   puts $aFile "\t\t<Build>"
2060
2061   # Release target configuration
2062   puts $aFile "\t\t\t<Target title=\"Release\">"
2063   if { "$theIsExe" == "true" } {
2064     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
2065     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2066   } else {
2067     if { "$aWokStation" == "wnt" } {
2068       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2069     } else {
2070       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
2071     }
2072     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2073   }
2074   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
2075   if { "$aWokStation" == "wnt" } {
2076     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2077   } else {
2078     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2079   }
2080   puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
2081   puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
2082
2083   # compiler options per TARGET (including defines)
2084   puts $aFile "\t\t\t\t<Compiler>"
2085   if { "$aWokStation" == "wnt" } {
2086     puts $aFile "\t\t\t\t\t<Add option=\"-MD\" />"
2087     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2088     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2089     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2090     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2091     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2092   } else {
2093     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2094     puts $aFile "\t\t\t\t\t<Add option=\"-std=c++0x\" />"
2095     if { "$aWokStation" != "qnx" } {
2096       puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2097       puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2098       puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2099       puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2100     }
2101   }
2102   foreach aMacro $theDefines {
2103     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2104   }
2105   puts $aFile "\t\t\t\t\t<Add option=\"-DNDEBUG\" />"
2106   if { "$aWokStation" == "qnx" } {
2107     puts $aFile "\t\t\t\t\t<Add option=\"-D_QNX_SOURCE\" />"
2108   }
2109   puts $aFile "\t\t\t\t\t<Add option=\"-DNo_Exception\" />"
2110
2111   puts $aFile "\t\t\t\t</Compiler>"
2112
2113   puts $aFile "\t\t\t\t<Linker>"
2114   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
2115   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2116     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2117   }
2118   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
2119   puts $aFile "\t\t\t\t</Linker>"
2120
2121   puts $aFile "\t\t\t</Target>"
2122
2123   # Debug target configuration
2124   puts $aFile "\t\t\t<Target title=\"Debug\">"
2125   if { "$theIsExe" == "true" } {
2126     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
2127     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2128   } else {
2129     if { "$aWokStation" == "wnt" } {
2130       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2131     } else {
2132       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
2133     }
2134     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2135   }
2136   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
2137   if { "$aWokStation" == "wnt" } {
2138     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2139   } else {
2140     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2141   }
2142   puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
2143   puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
2144
2145   # compiler options per TARGET (including defines)
2146   puts $aFile "\t\t\t\t<Compiler>"
2147   if { "$aWokStation" == "wnt" } {
2148     puts $aFile "\t\t\t\t\t<Add option=\"-MDd\" />"
2149     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2150     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2151     puts $aFile "\t\t\t\t\t<Add option=\"-Od\" />"
2152     puts $aFile "\t\t\t\t\t<Add option=\"-Zi\" />"
2153     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2154     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2155   } else {
2156     puts $aFile "\t\t\t\t\t<Add option=\"-O0\" />"
2157     puts $aFile "\t\t\t\t\t<Add option=\"-std=c++0x\" />"
2158     puts $aFile "\t\t\t\t\t<Add option=\"-g\" />"
2159     if { "$aWokStation" != "qnx" } {
2160       puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2161       puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2162       puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2163       puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2164     }
2165   }
2166   foreach aMacro $theDefines {
2167     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2168   }
2169   puts $aFile "\t\t\t\t\t<Add option=\"-D_DEBUG\" />"
2170   if { "$aWokStation" == "qnx" } {
2171     puts $aFile "\t\t\t\t\t<Add option=\"-D_QNX_SOURCE\" />"
2172   }
2173   puts $aFile "\t\t\t\t\t<Add option=\"-DDEB\" />"
2174   puts $aFile "\t\t\t\t</Compiler>"
2175
2176   puts $aFile "\t\t\t\t<Linker>"
2177   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
2178   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2179     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2180   }
2181   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
2182   puts $aFile "\t\t\t\t</Linker>"
2183
2184   puts $aFile "\t\t\t</Target>"
2185
2186   puts $aFile "\t\t</Build>"
2187
2188   # COMMON compiler options
2189   puts $aFile "\t\t<Compiler>"
2190   puts $aFile "\t\t\t<Add option=\"-Wall\" />"
2191   puts $aFile "\t\t\t<Add option=\"-fexceptions\" />"
2192   puts $aFile "\t\t\t<Add option=\"-fPIC\" />"
2193   puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2194   foreach anIncPath $theIncPaths {
2195     puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2196   }
2197   puts $aFile "\t\t</Compiler>"
2198
2199   # COMMON linker options
2200   puts $aFile "\t\t<Linker>"
2201   foreach aFrameworkName $theFrameworks {
2202     if { "$aFrameworkName" != "" } {
2203       puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2204     }
2205   }
2206   foreach aLibName $theLibsList {
2207     if { "$aLibName" != "" } {
2208       puts $aFile "\t\t\t<Add library=\"$aLibName\" />"
2209     }
2210   }
2211   puts $aFile "\t\t</Linker>"
2212
2213   # list of sources
2214   foreach aSrcFile $theSrcFiles {
2215     if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2216       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2217       puts $aFile "\t\t\t<Option compile=\"1\" />"
2218       puts $aFile "\t\t\t<Option link=\"1\" />"
2219       puts $aFile "\t\t</Unit>"
2220     } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2221       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2222       puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2223       puts $aFile "\t\t</Unit>"
2224     } else {
2225       puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
2226     }
2227   }
2228
2229   puts $aFile "\t</Project>"
2230   puts $aFile "</CodeBlocks_project_file>"
2231   close $aFile
2232
2233   return $aCbpFilePath
2234 }
2235
2236 # Auxiliary function to achieve complete information to build Toolkit
2237 # @param theRelativePath - relative path to CASROOT
2238 # @param theToolKit      - Toolkit name
2239 # @param theUsedLib      - dependencies (libraries  list)
2240 # @param theFrameworks   - dependencies (frameworks list, Mac OS X specific)
2241 # @param theIncPaths     - header search paths
2242 # @param theTKDefines    - compiler macro definitions
2243 # @param theTKSrcFiles   - list of source files
2244 proc osutils:tkinfo { theRelativePath theToolKit theUsedLib theFrameworks theIncPaths theTKDefines theTKSrcFiles } {
2245   global path targetStation
2246   set aWokStation "$targetStation"
2247
2248   # collect list of referred libraries to link with
2249   upvar $theUsedLib    aUsedLibs
2250   upvar $theFrameworks aFrameworks
2251   upvar $theIncPaths   anIncPaths
2252   upvar $theTKDefines  aTKDefines
2253   upvar $theTKSrcFiles aTKSrcFiles
2254
2255   osutils:usedOsLibs $theToolKit "$aWokStation" aUsedLibs aFrameworks
2256   set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2257   foreach tkx $aDepToolkits {
2258     lappend aUsedLibs "${tkx}"
2259   }
2260
2261   lappend anIncPaths "$theRelativePath/inc"
2262   set listloc [osutils:tk:units $theToolKit]
2263
2264   if { [llength $listloc] == 0 } {
2265     set listloc $theToolKit
2266   }
2267
2268   if { "$aWokStation" == "wnt" } {
2269     set resultloc [osutils:justwnt  $listloc]
2270   } else {
2271     set resultloc [osutils:justunix $listloc]
2272   }
2273   if [array exists written] { unset written }
2274   foreach fxlo $resultloc {
2275     set xlo       $fxlo
2276     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2277     foreach aSrcFile [lsort $aSrcFiles] {
2278       if { ![info exists written([file tail $aSrcFile])] } {
2279         set written([file tail $aSrcFile]) 1
2280         lappend aTKSrcFiles "${theRelativePath}/[wokUtils:FILES:wtail $aSrcFile 3]"
2281       } else {
2282         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2283       }
2284     }
2285
2286     # macros for correct DLL exports
2287     if { "$aWokStation" == "wnt" } {
2288       lappend aTKDefines "__${xlo}_DLL"
2289     }
2290
2291     # common include paths
2292 #    lappend anIncPaths "${theRelativePath}/src/${xlo}"
2293   }
2294
2295   # extra macros
2296   if { "$aWokStation" == "wnt" } {
2297     lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2298   } else {
2299     lappend aTKDefines "OCC_CONVERT_SIGNALS"
2300     #lappend aTKDefines "_GNU_SOURCE=1"
2301   }
2302 }
2303
2304 # Define libraries to link using only EXTERNLIB file
2305 proc LibToLinkX {thePackage theDummyName} {
2306   set aToolKits [LibToLink $thePackage]
2307   return $aToolKits
2308 }
2309
2310 # Function to generate Xcode workspace and project files
2311 proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
2312
2313   puts stderr "Generating project files for Xcode"
2314
2315   # Generate projects for toolkits and separate workspace for each module
2316   foreach aModule $theModules {
2317     OS:xcworkspace $aModule $aModule $theOutDir
2318     OS:xcodeproj   $aModule          $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
2319   }
2320
2321   # Generate single workspace "OCCT" containing projects from all modules
2322   if { "$theAllSolution" != "" } {
2323     OS:xcworkspace $theAllSolution $theModules $theOutDir
2324   }
2325 }
2326
2327 # Generates toolkits sections for Xcode workspace file.
2328 proc OS:xcworkspace:toolkits { theModule } {
2329   set aBuff ""
2330
2331   # Adding toolkits for module in workspace.
2332   foreach aToolKit [osutils:tk:sort [${theModule}:toolkits]] {
2333     append aBuff "         <FileRef\n"
2334     append aBuff "            location = \"group:${aToolKit}.xcodeproj\">\n"
2335     append aBuff "         </FileRef>\n"
2336   }
2337
2338   # Adding executables for module, assume one project per cxx file...
2339   foreach aUnit [OS:executable ${theModule}] {
2340     set aUnitLoc $aUnit
2341     set src_files [_get_used_files $aUnit false]
2342     set aSrcFiles {}
2343     foreach s $src_files {
2344       regexp {source ([^\s]+)} $s dummy name
2345       lappend aSrcFiles $name
2346     }
2347     foreach aSrcFile $aSrcFiles {
2348       set aFileExtension [file extension $aSrcFile]
2349       if { $aFileExtension == ".cxx" } {
2350         set aPrjName [file rootname $aSrcFile]
2351         append aBuff "         <FileRef\n"
2352         append aBuff "            location = \"group:${aPrjName}.xcodeproj\">\n"
2353         append aBuff "         </FileRef>\n"
2354       }
2355     }
2356   }
2357
2358   # Removing unnecessary newline character from the end.
2359   set aBuff [string replace $aBuff end end]
2360   return $aBuff
2361 }
2362
2363 # Generates workspace files for Xcode.
2364 proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
2365   # Creating workspace directory for Xcode.
2366   set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
2367   wokUtils:FILES:mkdir $aWorkspaceDir
2368   if { ! [file exists $aWorkspaceDir] } {
2369     puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
2370     return
2371   }
2372
2373   # Creating workspace file.
2374   set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
2375   set aFile [open $aWsFilePath "w"]
2376
2377   # Adding header and section for main Group.
2378   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2379   puts $aFile "<Workspace"
2380   puts $aFile "   version = \"1.0\">"
2381   puts $aFile "   <Group"
2382   puts $aFile "      location = \"container:\""
2383   puts $aFile "      name = \"${theWorkspaceName}\">"
2384
2385   # Adding modules.
2386   if { [llength "$theModules"] > 1 } {
2387     foreach aModule $theModules {
2388       puts $aFile "      <Group"
2389       puts $aFile "         location = \"container:\""
2390       puts $aFile "         name = \"${aModule}\">"
2391       puts $aFile [OS:xcworkspace:toolkits $aModule]
2392       puts $aFile "      </Group>"
2393     }
2394   } else {
2395     puts $aFile [OS:xcworkspace:toolkits $theModules]
2396   }
2397
2398   # Adding footer.
2399   puts $aFile "   </Group>"
2400   puts $aFile "</Workspace>"
2401   close $aFile
2402 }
2403
2404 # Generates Xcode project files.
2405 proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
2406   upvar $theGuidsMap aGuidsMap
2407
2408   set isStatic 0
2409   if { "$theLibType" == "static" } {
2410     set isStatic 1
2411   } elseif { "$thePlatform" == "ios" } {
2412     set isStatic 1
2413   }
2414
2415   set aProjectFiles {}
2416   foreach aModule $theModules {
2417     foreach aToolKit [${aModule}:toolkits] {
2418       lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit     aGuidsMap $isStatic $thePlatform "dylib"]
2419     }
2420     foreach anExecutable [OS:executable ${aModule}] {
2421       lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
2422     }
2423   }
2424   return $aProjectFiles
2425 }
2426
2427 # Generates dependencies section for Xcode project files.
2428 proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids theIsStatic} {
2429   global path
2430   upvar $theGuidsMap         aGuidsMap
2431   upvar $theFileRefSection   aFileRefSection
2432   upvar $theDepsGuids        aDepsGuids
2433   upvar $theDepsRefGuids     aDepsRefGuids
2434
2435   set aBuildFileSection ""
2436   set aUsedToolKits     [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2437   set aDepToolkits      [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]] $theToolKit]
2438
2439   if { "$theTargetType" == "executable" } {
2440     set aFile [osutils:tk:files $theToolKit osutils:compilable 0]
2441     set aProjName [file rootname [file tail $aFile]]
2442     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2443   }
2444
2445   set aLibExt "dylib"
2446   if { $theIsStatic == 1 } {
2447     set aLibExt "a"
2448     if { "$theTargetType" != "executable" } {
2449       return $aBuildFileSection
2450     }
2451   }
2452
2453   osutils:usedOsLibs $theToolKit "mac" aLibs aFrameworks
2454   set aUsedToolKits [concat $aUsedToolKits $aLibs]
2455   set aUsedToolKits [concat $aUsedToolKits $aFrameworks]
2456   foreach tkx $aUsedToolKits {
2457     set aDepLib    "${tkx}_Dep"
2458     set aDepLibRef "${tkx}_DepRef"
2459
2460     if { ! [info exists aGuidsMap($aDepLib)] } {
2461       set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
2462     }
2463     if { ! [info exists aGuidsMap($aDepLibRef)] } {
2464       set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
2465     }
2466
2467     append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
2468     if {[lsearch -nocase $aFrameworks $tkx] == -1} {
2469       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
2470     } else {
2471       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
2472     }
2473     append aDepsGuids        "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
2474     append aDepsRefGuids     "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
2475   }
2476
2477   return $aBuildFileSection
2478 }
2479
2480 # Generates PBXBuildFile and PBXGroup sections for project file.
2481 proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
2482   upvar $theSrcFileRefSection aSrcFileRefSection
2483   upvar $theGroupSection      aGroupSection
2484   upvar $thePackageGuids      aPackagesGuids
2485   upvar $theSrcFileGuids      aSrcFileGuids
2486   upvar $theGuidsMap          aGuidsMap
2487   upvar $theIncPaths          anIncPaths
2488
2489   set listloc [osutils:tk:units $theToolKit]
2490   set resultloc [osutils:justunix $listloc]
2491   set aBuildFileSection ""
2492   set aPackages [lsort -nocase $resultloc]
2493   if { "$theTargetType" == "executable" } {
2494     set aPackages [list "$theToolKit"]
2495   }
2496
2497   # Generating PBXBuildFile, PBXGroup sections and groups for each package.
2498   foreach fxlo $aPackages {
2499     set xlo       $fxlo
2500     set aPackage "${xlo}_Package"
2501     set aSrcFileRefGuids ""
2502     if { ! [info exists aGuidsMap($aPackage)] } {
2503       set aGuidsMap($aPackage) [OS:genGUID "xcd"]
2504     }
2505
2506     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2507     foreach aSrcFile [lsort $aSrcFiles] {
2508       set aFileExt "sourcecode.cpp.cpp"
2509
2510       if { [file extension $aSrcFile] == ".c" } {
2511         set aFileExt "sourcecode.c.c"
2512       } elseif { [file extension $aSrcFile] == ".mm" } {
2513         set aFileExt "sourcecode.cpp.objcpp"
2514       }
2515
2516       if { ! [info exists aGuidsMap($aSrcFile)] } {
2517         set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
2518       }
2519       set aSrcFileRef "${aSrcFile}_Ref"
2520       if { ! [info exists aGuidsMap($aSrcFileRef)] } {
2521         set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
2522       }
2523       if { ! [info exists written([file tail $aSrcFile])] } {
2524         set written([file tail $aSrcFile]) 1
2525         append aBuildFileSection  "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
2526         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"
2527         append aSrcFileGuids      "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
2528         append aSrcFileRefGuids   "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
2529       } else {
2530         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2531       }
2532     }
2533
2534     append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
2535     append aGroupSection "\t\t\tisa = PBXGroup;\n"
2536     append aGroupSection "\t\t\tchildren = (\n"
2537     append aGroupSection $aSrcFileRefGuids
2538     append aGroupSection "\t\t\t);\n"
2539     append aGroupSection "\t\t\tname = $xlo;\n"
2540     append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
2541     append aGroupSection "\t\t\};\n"
2542
2543     # Storing packages IDs for adding them later as a child of toolkit
2544     append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
2545   }
2546
2547   # Removing unnecessary newline character from the end.
2548   set aPackagesGuids [string replace $aPackagesGuids end end]
2549
2550   return $aBuildFileSection
2551 }
2552
2553 # Creates folders structure and all necessary files for Xcode project.
2554 proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
2555   set aPBXBuildPhase "Headers"
2556   set aRunOnlyForDeployment "0"
2557   set aProductType "library.dynamic"
2558   set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
2559   set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
2560   set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
2561   set aTKDefines [list "OCC_CONVERT_SIGNALS"]
2562
2563   if { "$theTargetType" == "executable" } {
2564     set aPBXBuildPhase "CopyFiles"
2565     set aRunOnlyForDeployment "1"
2566     set aProductType "tool"
2567     set anExecExtension ""
2568     set anExecPrefix ""
2569     set aWrapperExtension ""
2570   } elseif { $theIsStatic == 1 } {
2571     set aProductType "library.static"
2572     set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
2573     set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
2574   }
2575
2576   set aUsername [exec whoami]
2577
2578   # Creation of folders for Xcode projectP.
2579   set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
2580   wokUtils:FILES:mkdir $aToolkitDir
2581   if { ! [file exists $aToolkitDir] } {
2582     puts stderr "Error: Could not create project directory \"$aToolkitDir\""
2583     return
2584   }
2585
2586   set aUserDataDir "${aToolkitDir}/xcuserdata"
2587   wokUtils:FILES:mkdir $aUserDataDir
2588   if { ! [file exists $aUserDataDir] } {
2589     puts stderr "Error: Could not create xcuserdata directorty in \"$aToolkitDir\""
2590     return
2591   }
2592
2593   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
2594   wokUtils:FILES:mkdir $aUserDataDir
2595   if { ! [file exists $aUserDataDir] } {
2596     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$aToolkitDir\"/xcuserdata"
2597     return
2598   }
2599
2600   set aSchemesDir "${aUserDataDir}/xcschemes"
2601   wokUtils:FILES:mkdir $aSchemesDir
2602   if { ! [file exists $aSchemesDir] } {
2603     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
2604     return
2605   }
2606   # End of folders creation.
2607
2608   # Generating GUID for tookit.
2609   upvar $theGuidsMap aGuidsMap
2610   if { ! [info exists aGuidsMap($theToolKit)] } {
2611     set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
2612   }
2613
2614   # Creating xcscheme file for toolkit from template.
2615   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
2616   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
2617   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
2618   set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme"  "w"]
2619   puts $aXcschemeFile $aXcschemeTmpl
2620   close $aXcschemeFile
2621
2622   # Creating xcschememanagement.plist file for toolkit from template.
2623   set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
2624   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
2625   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
2626   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
2627   puts $aPlistFile $aPlistTmpl
2628   close $aPlistFile
2629
2630   # Creating project.pbxproj file for toolkit.
2631   set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
2632   puts $aPbxprojFile "// !\$*UTF8*\$!"
2633   puts $aPbxprojFile "\{"
2634   puts $aPbxprojFile "\tarchiveVersion = 1;"
2635   puts $aPbxprojFile "\tclasses = \{"
2636   puts $aPbxprojFile "\t\};"
2637   puts $aPbxprojFile "\tobjectVersion = 46;"
2638   puts $aPbxprojFile "\tobjects = \{\n"
2639
2640   # Begin PBXBuildFile section
2641   set aPackagesGuids ""
2642   set aGroupSection ""
2643   set aSrcFileRefSection ""
2644   set aSrcFileGuids ""
2645   set aDepsFileRefSection ""
2646   set aDepsGuids ""
2647   set aDepsRefGuids ""
2648   set anIncPaths [list "../../../inc"]
2649   set anLibPaths ""
2650
2651   if { [info exists ::env(CSF_OPT_INC)] } {
2652     set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
2653     foreach anIncCfgPath $anIncCfg {
2654       lappend anIncPaths $anIncCfgPath
2655     }
2656   }
2657   if { [info exists ::env(CSF_OPT_LIB64)] } {
2658     set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
2659     foreach anLibCfgPath $anLibCfg {
2660       lappend anLibPaths $anLibCfgPath
2661     }
2662   }
2663
2664   puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
2665   puts $aPbxprojFile [osutils:xcdtk:deps    $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $theIsStatic]
2666   # End PBXBuildFile section
2667
2668   # Begin PBXFileReference section
2669   set aToolkitLib "lib${theToolKit}.dylib"
2670   set aPath "$aToolkitLib"
2671   if { "$theTargetType" == "executable" } {
2672     set aPath "$theToolKit"
2673   } elseif { $theIsStatic == 1 } {
2674     set aToolkitLib "lib${theToolKit}.a"
2675   }
2676
2677   if { ! [info exists aGuidsMap($aToolkitLib)] } {
2678     set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
2679   }
2680
2681   puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
2682   puts $aPbxprojFile $aSrcFileRefSection
2683   puts $aPbxprojFile $aDepsFileRefSection
2684   # End PBXFileReference section
2685
2686
2687   # Begin PBXFrameworksBuildPhase section
2688   set aTkFrameworks "${theToolKit}_Frameworks"
2689   if { ! [info exists aGuidsMap($aTkFrameworks)] } {
2690     set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
2691   }
2692
2693   puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
2694   puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
2695   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2696   puts $aPbxprojFile "\t\t\tfiles = ("
2697   puts $aPbxprojFile $aDepsGuids
2698   puts $aPbxprojFile "\t\t\t);"
2699   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2700   puts $aPbxprojFile "\t\t\};\n"
2701   # End PBXFrameworksBuildPhase section
2702
2703   # Begin PBXGroup section
2704   set aTkPBXGroup "${theToolKit}_PBXGroup"
2705   if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
2706     set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
2707   }
2708
2709   set aTkSrcGroup "${theToolKit}_SrcGroup"
2710   if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
2711     set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
2712   }
2713
2714   puts $aPbxprojFile $aGroupSection
2715   puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
2716   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2717   puts $aPbxprojFile "\t\t\tchildren = ("
2718   puts $aPbxprojFile $aDepsRefGuids
2719   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
2720   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
2721   puts $aPbxprojFile "\t\t\t);"
2722   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2723   puts $aPbxprojFile "\t\t\};"
2724   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
2725   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2726   puts $aPbxprojFile "\t\t\tchildren = ("
2727   puts $aPbxprojFile $aPackagesGuids
2728   puts $aPbxprojFile "\t\t\t);"
2729   puts $aPbxprojFile "\t\t\tname = \"Source files\";"
2730   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2731   puts $aPbxprojFile "\t\t\};\n"
2732   # End PBXGroup section
2733
2734   # Begin PBXHeadersBuildPhase section
2735   set aTkHeaders "${theToolKit}_Headers"
2736   if { ! [info exists aGuidsMap($aTkHeaders)] } {
2737     set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
2738   }
2739
2740   puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
2741   puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
2742   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2743   puts $aPbxprojFile "\t\t\tfiles = ("
2744   puts $aPbxprojFile "\t\t\t);"
2745   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
2746   puts $aPbxprojFile "\t\t\};\n"
2747   # End PBXHeadersBuildPhase section
2748
2749   # Begin PBXNativeTarget section
2750   set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
2751   if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
2752     set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
2753   }
2754
2755   set aTkSources "${theToolKit}_Sources"
2756   if { ! [info exists aGuidsMap($aTkSources)] } {
2757     set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
2758   }
2759
2760   puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
2761   puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
2762   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
2763   puts $aPbxprojFile "\t\t\tbuildPhases = ("
2764   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
2765   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
2766   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
2767   puts $aPbxprojFile "\t\t\t);"
2768   puts $aPbxprojFile "\t\t\tbuildRules = ("
2769   puts $aPbxprojFile "\t\t\t);"
2770   puts $aPbxprojFile "\t\t\tdependencies = ("
2771   puts $aPbxprojFile "\t\t\t);"
2772   puts $aPbxprojFile "\t\t\tname = $theToolKit;"
2773   puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
2774   puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
2775   puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
2776   puts $aPbxprojFile "\t\t\};\n"
2777   # End PBXNativeTarget section
2778
2779   # Begin PBXProject section
2780   set aTkProjectObj "${theToolKit}_ProjectObj"
2781   if { ! [info exists aGuidsMap($aTkProjectObj)] } {
2782     set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
2783   }
2784
2785   set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
2786   if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
2787     set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
2788   }
2789
2790   puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
2791   puts $aPbxprojFile "\t\t\tisa = PBXProject;"
2792   puts $aPbxprojFile "\t\t\tattributes = \{"
2793   puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
2794   puts $aPbxprojFile "\t\t\t\};"
2795   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
2796   puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
2797   puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
2798   puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
2799   puts $aPbxprojFile "\t\t\tknownRegions = ("
2800   puts $aPbxprojFile "\t\t\t\ten,"
2801   puts $aPbxprojFile "\t\t\t);"
2802   puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
2803   puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
2804   puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
2805   puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
2806   puts $aPbxprojFile "\t\t\ttargets = ("
2807   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
2808   puts $aPbxprojFile "\t\t\t);"
2809   puts $aPbxprojFile "\t\t\};\n"
2810   # End PBXProject section
2811
2812   # Begin PBXSourcesBuildPhase section
2813   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
2814   puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
2815   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2816   puts $aPbxprojFile "\t\t\tfiles = ("
2817   puts $aPbxprojFile $aSrcFileGuids
2818   puts $aPbxprojFile "\t\t\t);"
2819   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2820   puts $aPbxprojFile "\t\t\};\n"
2821   # End PBXSourcesBuildPhase section
2822
2823   # Begin XCBuildConfiguration section
2824   set aTkDebugProject "${theToolKit}_DebugProject"
2825   if { ! [info exists aGuidsMap($aTkDebugProject)] } {
2826     set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
2827   }
2828
2829   set aTkReleaseProject "${theToolKit}_ReleaseProject"
2830   if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
2831     set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
2832   }
2833
2834   set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
2835   if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
2836     set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
2837   }
2838
2839   set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
2840   if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
2841     set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
2842   }
2843
2844   # Debug target
2845   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
2846   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2847   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2848
2849   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
2850   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
2851   if { "$thePlatform" == "ios" } {
2852     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
2853     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
2854     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
2855     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
2856     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
2857   }
2858   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
2859   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
2860   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
2861   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
2862   puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
2863   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
2864   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
2865   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2866   puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
2867   puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
2868   puts $aPbxprojFile "\t\t\t\t);"
2869   puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
2870   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
2871   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
2872   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
2873   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
2874   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
2875   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
2876   if { "$thePlatform" == "ios" } {
2877     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
2878     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
2879   } else {
2880     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
2881   }
2882   puts $aPbxprojFile "\t\t\t\};"
2883
2884   puts $aPbxprojFile "\t\t\tname = Debug;"
2885   puts $aPbxprojFile "\t\t\};"
2886
2887   # Release target
2888   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
2889   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2890   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2891
2892   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
2893   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
2894   if { "$thePlatform" == "ios" } {
2895     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
2896     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
2897     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
2898     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
2899     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
2900   }
2901   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
2902   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
2903   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
2904   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
2905   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
2906   puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
2907   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
2908   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
2909   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
2910   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
2911   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
2912   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
2913   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
2914   if { "$thePlatform" == "ios" } {
2915     puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
2916     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
2917   }
2918   puts $aPbxprojFile "\t\t\t\};"
2919   puts $aPbxprojFile "\t\t\tname = Release;"
2920   puts $aPbxprojFile "\t\t\};"
2921   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
2922   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2923   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2924   puts $aPbxprojFile "${anExecExtension}"
2925   puts $aPbxprojFile "${anExecPrefix}"
2926   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2927   foreach aMacro $aTKDefines {
2928     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
2929   }
2930   puts $aPbxprojFile "\t\t\t\t);"
2931
2932   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
2933   foreach anIncPath $anIncPaths {
2934     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
2935   }
2936   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
2937   puts $aPbxprojFile "\t\t\t\t);"
2938
2939   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
2940   foreach anLibPath $anLibPaths {
2941     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
2942   }
2943   puts $aPbxprojFile "\t\t\t\t);"
2944
2945   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
2946   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
2947   puts $aPbxprojFile "\t\t\t\t);"
2948   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
2949   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
2950   puts $aPbxprojFile "\t\t\t\t);"
2951   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
2952   set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
2953   foreach anIncPath $anIncPaths {
2954     append anUserHeaderSearchPath " ${anIncPath}"
2955   }
2956   append anUserHeaderSearchPath "\";"
2957   puts $aPbxprojFile $anUserHeaderSearchPath
2958   puts $aPbxprojFile "${aWrapperExtension}"
2959   puts $aPbxprojFile "\t\t\t\};"
2960   puts $aPbxprojFile "\t\t\tname = Debug;"
2961   puts $aPbxprojFile "\t\t\};"
2962   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
2963   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2964   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2965   puts $aPbxprojFile "${anExecExtension}"
2966   puts $aPbxprojFile "${anExecPrefix}"
2967   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2968   foreach aMacro $aTKDefines {
2969     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
2970   }
2971   puts $aPbxprojFile "\t\t\t\t);"
2972   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
2973   foreach anIncPath $anIncPaths {
2974     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
2975   }
2976   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
2977   puts $aPbxprojFile "\t\t\t\t);"
2978
2979   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
2980   foreach anLibPath $anLibPaths {
2981     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
2982   }
2983   puts $aPbxprojFile "\t\t\t\t);"
2984
2985   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
2986   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
2987   puts $aPbxprojFile "\t\t\t\t);"
2988   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
2989   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
2990   puts $aPbxprojFile "\t\t\t\t);"
2991   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
2992   puts $aPbxprojFile $anUserHeaderSearchPath
2993   puts $aPbxprojFile "${aWrapperExtension}"
2994   puts $aPbxprojFile "\t\t\t\};"
2995   puts $aPbxprojFile "\t\t\tname = Release;"
2996   puts $aPbxprojFile "\t\t\};\n"
2997   # End XCBuildConfiguration section
2998
2999   # Begin XCConfigurationList section
3000   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
3001   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3002   puts $aPbxprojFile "\t\tbuildConfigurations = ("
3003   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
3004   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
3005   puts $aPbxprojFile "\t\t\t);"
3006   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3007   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3008   puts $aPbxprojFile "\t\t\};"
3009   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
3010   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3011   puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
3012   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
3013   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
3014   puts $aPbxprojFile "\t\t\t);"
3015   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3016   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3017   puts $aPbxprojFile "\t\t\};\n"
3018   # End XCConfigurationList section
3019
3020   puts $aPbxprojFile "\t\};"
3021   puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3022   puts $aPbxprojFile "\}"
3023
3024   close $aPbxprojFile
3025 }
3026
3027 proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3028   set aUsername [exec whoami]
3029
3030   # Creating folders for Xcode project file.
3031   set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3032   wokUtils:FILES:mkdir $anExecutableDir
3033   if { ! [file exists $anExecutableDir] } {
3034     puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3035     return
3036   }
3037
3038   set aUserDataDir "${anExecutableDir}/xcuserdata"
3039   wokUtils:FILES:mkdir $aUserDataDir
3040   if { ! [file exists $aUserDataDir] } {
3041     puts stderr "Error: Could not create xcuserdata directorty in \"$anExecutableDir\""
3042     return
3043   }
3044
3045   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3046   wokUtils:FILES:mkdir $aUserDataDir
3047   if { ! [file exists $aUserDataDir] } {
3048     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$anExecutableDir\"/xcuserdata"
3049     return
3050   }
3051
3052   set aSchemesDir "${aUserDataDir}/xcschemes"
3053   wokUtils:FILES:mkdir $aSchemesDir
3054   if { ! [file exists $aSchemesDir] } {
3055     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3056     return
3057   }
3058   # End folders creation.
3059
3060   # Generating GUID for tookit.
3061   upvar $theGuidsMap aGuidsMap
3062   if { ! [info exists aGuidsMap($theExecutable)] } {
3063     set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3064   }
3065
3066   # Creating xcscheme file for toolkit from template.
3067   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3068   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3069   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3070   set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme"  "w"]
3071   puts $aXcschemeFile $aXcschemeTmpl
3072   close $aXcschemeFile
3073
3074   # Creating xcschememanagement.plist file for toolkit from template.
3075   set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3076   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3077   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3078   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
3079   puts $aPlistFile $aPlistTmpl
3080   close $aPlistFile
3081 }