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