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