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