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