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