0023741: Research and remove CSFDB support from OCCT if it is necessary
[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     if { "$aWokStation" == "wnt" } {
2009       lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2010     } else {
2011       lappend aTKDefines "OCC_CONVERT_SIGNALS"
2012       #lappend aTKDefines "_GNU_SOURCE=1"
2013     }
2014
2015     lappend aCbpFiles [osutils:cbp $theOutDir $aProjName $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines $isExecutable]
2016   }
2017
2018   return $aCbpFiles
2019 }
2020
2021 proc osutils:optinal_libs { } {
2022   return [list tbb.lib tbbmalloc.lib FreeImage.lib FreeImagePlus.lib gl2ps.lib]
2023 }
2024
2025 # This function intended to generate Code::Blocks project file
2026 # @param theOutDir     - output directory to place project file
2027 # @param theProjName   - project name
2028 # @param theSrcFiles   - list of source files
2029 # @param theLibsList   - dependencies (libraries  list)
2030 # @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2031 # @param theIncPaths   - header search paths
2032 # @param theDefines    - compiler macro definitions
2033 # @param theIsExe      - flag to indicate executable / library target
2034 proc osutils:cbp { theOutDir theProjName theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2035   global targetStation
2036   set aWokStation "$targetStation"
2037   set aWokArch    "$::env(ARCH)"
2038
2039   set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2040   set aFile [open $aCbpFilePath "w"]
2041   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2042   puts $aFile "<CodeBlocks_project_file>"
2043   puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2044   puts $aFile "\t<Project>"
2045   puts $aFile "\t\t<Option title=\"$theProjName\" />"
2046   puts $aFile "\t\t<Option pch_mode=\"2\" />"
2047   if { "$aWokStation" == "wnt" } {
2048     puts $aFile "\t\t<Option compiler=\"msvc8\" />"
2049   } else {
2050     puts $aFile "\t\t<Option compiler=\"gcc\" />"
2051   }
2052   puts $aFile "\t\t<Build>"
2053
2054   # Release target configuration
2055   puts $aFile "\t\t\t<Target title=\"Release\">"
2056   if { "$theIsExe" == "true" } {
2057     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2058     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2059   } else {
2060     if { "$aWokStation" == "wnt" } {
2061       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2062     } else {
2063       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2064     }
2065     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2066   }
2067   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
2068   if { "$aWokStation" == "wnt" } {
2069     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2070   } else {
2071     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2072   }
2073   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2074   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2075
2076   # compiler options per TARGET (including defines)
2077   puts $aFile "\t\t\t\t<Compiler>"
2078   if { "$aWokStation" == "wnt" } {
2079     puts $aFile "\t\t\t\t\t<Add option=\"-MD\" />"
2080     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2081     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2082     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2083     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2084     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2085   } else {
2086     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2087     puts $aFile "\t\t\t\t\t<Add option=\"-std=c++0x\" />"
2088     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2089     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2090     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2091     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2092   }
2093   foreach aMacro $theDefines {
2094     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2095   }
2096   puts $aFile "\t\t\t\t\t<Add option=\"-DNDEBUG\" />"
2097   puts $aFile "\t\t\t\t\t<Add option=\"-DNo_Exception\" />"
2098
2099   puts $aFile "\t\t\t\t</Compiler>"
2100
2101   puts $aFile "\t\t\t\t<Linker>"
2102   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
2103   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2104     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2105   }
2106   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
2107   puts $aFile "\t\t\t\t</Linker>"
2108
2109   puts $aFile "\t\t\t</Target>"
2110
2111   # Debug target configuration
2112   puts $aFile "\t\t\t<Target title=\"Debug\">"
2113   if { "$theIsExe" == "true" } {
2114     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2115     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2116   } else {
2117     if { "$aWokStation" == "wnt" } {
2118       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2119     } else {
2120       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2121     }
2122     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2123   }
2124   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
2125   if { "$aWokStation" == "wnt" } {
2126     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2127   } else {
2128     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2129   }
2130   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2131   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2132
2133   # compiler options per TARGET (including defines)
2134   puts $aFile "\t\t\t\t<Compiler>"
2135   if { "$aWokStation" == "wnt" } {
2136     puts $aFile "\t\t\t\t\t<Add option=\"-MDd\" />"
2137     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2138     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2139     puts $aFile "\t\t\t\t\t<Add option=\"-Od\" />"
2140     puts $aFile "\t\t\t\t\t<Add option=\"-Zi\" />"
2141     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2142     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2143   } else {
2144     puts $aFile "\t\t\t\t\t<Add option=\"-O0\" />"
2145     puts $aFile "\t\t\t\t\t<Add option=\"-std=c++0x\" />"
2146     puts $aFile "\t\t\t\t\t<Add option=\"-g\" />"
2147     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2148     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2149     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2150     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2151   }
2152   foreach aMacro $theDefines {
2153     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2154   }
2155   puts $aFile "\t\t\t\t\t<Add option=\"-D_DEBUG\" />"
2156   puts $aFile "\t\t\t\t\t<Add option=\"-DDEB\" />"
2157   puts $aFile "\t\t\t\t</Compiler>"
2158
2159   puts $aFile "\t\t\t\t<Linker>"
2160   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
2161   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2162     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2163   }
2164   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
2165   puts $aFile "\t\t\t\t</Linker>"
2166
2167   puts $aFile "\t\t\t</Target>"
2168
2169   puts $aFile "\t\t</Build>"
2170
2171   # COMMON compiler options
2172   puts $aFile "\t\t<Compiler>"
2173   puts $aFile "\t\t\t<Add option=\"-Wall\" />"
2174   puts $aFile "\t\t\t<Add option=\"-fexceptions\" />"
2175   puts $aFile "\t\t\t<Add option=\"-fPIC\" />"
2176   puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2177   foreach anIncPath $theIncPaths {
2178     puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2179   }
2180   puts $aFile "\t\t</Compiler>"
2181
2182   # COMMON linker options
2183   puts $aFile "\t\t<Linker>"
2184   foreach aFrameworkName $theFrameworks {
2185     if { "$aFrameworkName" != "" } {
2186       puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2187     }
2188   }
2189   foreach aLibName $theLibsList {
2190     if { "$aLibName" != "" } {
2191       puts $aFile "\t\t\t<Add library=\"$aLibName\" />"
2192     }
2193   }
2194   puts $aFile "\t\t</Linker>"
2195
2196   # list of sources
2197   foreach aSrcFile $theSrcFiles {
2198     if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2199       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2200       puts $aFile "\t\t\t<Option compile=\"1\" />"
2201       puts $aFile "\t\t\t<Option link=\"1\" />"
2202       puts $aFile "\t\t</Unit>"
2203     } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2204       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2205       puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2206       puts $aFile "\t\t</Unit>"
2207     } else {
2208       puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
2209     }
2210   }
2211
2212   puts $aFile "\t</Project>"
2213   puts $aFile "</CodeBlocks_project_file>"
2214   close $aFile
2215
2216   return $aCbpFilePath
2217 }
2218
2219 # Auxiliary function to achieve complete information to build Toolkit
2220 # @param theRelativePath - relative path to CASROOT
2221 # @param theToolKit      - Toolkit name
2222 # @param theUsedLib      - dependencies (libraries  list)
2223 # @param theFrameworks   - dependencies (frameworks list, Mac OS X specific)
2224 # @param theIncPaths     - header search paths
2225 # @param theTKDefines    - compiler macro definitions
2226 # @param theTKSrcFiles   - list of source files
2227 proc osutils:tkinfo { theRelativePath theToolKit theUsedLib theFrameworks theIncPaths theTKDefines theTKSrcFiles } {
2228   global path targetStation
2229   set aWokStation "$targetStation"
2230
2231   # collect list of referred libraries to link with
2232   upvar $theUsedLib    aUsedLibs
2233   upvar $theFrameworks aFrameworks
2234   upvar $theIncPaths   anIncPaths
2235   upvar $theTKDefines  aTKDefines
2236   upvar $theTKSrcFiles aTKSrcFiles
2237
2238   osutils:usedOsLibs $theToolKit "$aWokStation" aUsedLibs aFrameworks
2239   set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2240   foreach tkx $aDepToolkits {
2241     lappend aUsedLibs "${tkx}"
2242   }
2243
2244   lappend anIncPaths "$theRelativePath/inc"
2245   set listloc [osutils:tk:units $theToolKit]
2246
2247   if { [llength $listloc] == 0 } {
2248     set listloc $theToolKit
2249   }
2250
2251   if { "$aWokStation" == "wnt" } {
2252     set resultloc [osutils:justwnt  $listloc]
2253   } else {
2254     set resultloc [osutils:justunix $listloc]
2255   }
2256   if [array exists written] { unset written }
2257   foreach fxlo $resultloc {
2258     set xlo       $fxlo
2259     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2260     foreach aSrcFile [lsort $aSrcFiles] {
2261       if { ![info exists written([file tail $aSrcFile])] } {
2262         set written([file tail $aSrcFile]) 1
2263         lappend aTKSrcFiles "${theRelativePath}/[wokUtils:FILES:wtail $aSrcFile 3]"
2264       } else {
2265         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2266       }
2267     }
2268
2269     # macros for correct DLL exports
2270     if { "$aWokStation" == "wnt" } {
2271       lappend aTKDefines "__${xlo}_DLL"
2272     }
2273
2274     # common include paths
2275 #    lappend anIncPaths "${theRelativePath}/src/${xlo}"
2276   }
2277
2278   # extra macros
2279   if { "$aWokStation" == "wnt" } {
2280     lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2281   } else {
2282     lappend aTKDefines "OCC_CONVERT_SIGNALS"
2283     #lappend aTKDefines "_GNU_SOURCE=1"
2284   }
2285 }
2286
2287 # Define libraries to link using only EXTERNLIB file
2288 proc LibToLinkX {thePackage theDummyName} {
2289   set aToolKits [LibToLink $thePackage]
2290   return $aToolKits
2291 }
2292
2293 # Function to generate Xcode workspace and project files
2294 proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
2295
2296   puts stderr "Generating project files for Xcode"
2297
2298   # Generate projects for toolkits and separate workspace for each module
2299   foreach aModule $theModules {
2300     OS:xcworkspace $aModule $aModule $theOutDir
2301     OS:xcodeproj   $aModule          $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
2302   }
2303
2304   # Generate single workspace "OCCT" containing projects from all modules
2305   if { "$theAllSolution" != "" } {
2306     OS:xcworkspace $theAllSolution $theModules $theOutDir
2307   }
2308 }
2309
2310 # Generates toolkits sections for Xcode workspace file.
2311 proc OS:xcworkspace:toolkits { theModule } {
2312   set aBuff ""
2313
2314   # Adding toolkits for module in workspace.
2315   foreach aToolKit [osutils:tk:sort [${theModule}:toolkits]] {
2316     append aBuff "         <FileRef\n"
2317     append aBuff "            location = \"group:${aToolKit}.xcodeproj\">\n"
2318     append aBuff "         </FileRef>\n"
2319   }
2320
2321   # Adding executables for module, assume one project per cxx file...
2322   foreach aUnit [OS:executable ${theModule}] {
2323     set aUnitLoc $aUnit
2324     set src_files [_get_used_files $aUnit false]
2325     set aSrcFiles {}
2326     foreach s $src_files {
2327       regexp {source ([^\s]+)} $s dummy name
2328       lappend aSrcFiles $name
2329     }
2330     foreach aSrcFile $aSrcFiles {
2331       set aFileExtension [file extension $aSrcFile]
2332       if { $aFileExtension == ".cxx" } {
2333         set aPrjName [file rootname $aSrcFile]
2334         append aBuff "         <FileRef\n"
2335         append aBuff "            location = \"group:${aPrjName}.xcodeproj\">\n"
2336         append aBuff "         </FileRef>\n"
2337       }
2338     }
2339   }
2340
2341   # Removing unnecessary newline character from the end.
2342   set aBuff [string replace $aBuff end end]
2343   return $aBuff
2344 }
2345
2346 # Generates workspace files for Xcode.
2347 proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
2348   # Creating workspace directory for Xcode.
2349   set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
2350   wokUtils:FILES:mkdir $aWorkspaceDir
2351   if { ! [file exists $aWorkspaceDir] } {
2352     puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
2353     return
2354   }
2355
2356   # Creating workspace file.
2357   set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
2358   set aFile [open $aWsFilePath "w"]
2359
2360   # Adding header and section for main Group.
2361   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2362   puts $aFile "<Workspace"
2363   puts $aFile "   version = \"1.0\">"
2364   puts $aFile "   <Group"
2365   puts $aFile "      location = \"container:\""
2366   puts $aFile "      name = \"${theWorkspaceName}\">"
2367
2368   # Adding modules.
2369   if { [llength "$theModules"] > 1 } {
2370     foreach aModule $theModules {
2371       puts $aFile "      <Group"
2372       puts $aFile "         location = \"container:\""
2373       puts $aFile "         name = \"${aModule}\">"
2374       puts $aFile [OS:xcworkspace:toolkits $aModule]
2375       puts $aFile "      </Group>"
2376     }
2377   } else {
2378     puts $aFile [OS:xcworkspace:toolkits $theModules]
2379   }
2380
2381   # Adding footer.
2382   puts $aFile "   </Group>"
2383   puts $aFile "</Workspace>"
2384   close $aFile
2385 }
2386
2387 # Generates Xcode project files.
2388 proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
2389   upvar $theGuidsMap aGuidsMap
2390
2391   set isStatic 0
2392   if { "$theLibType" == "static" } {
2393     set isStatic 1
2394   } elseif { "$thePlatform" == "ios" } {
2395     set isStatic 1
2396   }
2397
2398   set aProjectFiles {}
2399   foreach aModule $theModules {
2400     foreach aToolKit [${aModule}:toolkits] {
2401       lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit     aGuidsMap $isStatic $thePlatform "dylib"]
2402     }
2403     foreach anExecutable [OS:executable ${aModule}] {
2404       lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
2405     }
2406   }
2407   return $aProjectFiles
2408 }
2409
2410 # Generates dependencies section for Xcode project files.
2411 proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids theIsStatic} {
2412   global path
2413   upvar $theGuidsMap         aGuidsMap
2414   upvar $theFileRefSection   aFileRefSection
2415   upvar $theDepsGuids        aDepsGuids
2416   upvar $theDepsRefGuids     aDepsRefGuids
2417
2418   set aBuildFileSection ""
2419   set aUsedToolKits     [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2420   set aDepToolkits      [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]] $theToolKit]
2421
2422   if { "$theTargetType" == "executable" } {
2423     set aFile [osutils:tk:files $theToolKit osutils:compilable 0]
2424     set aProjName [file rootname [file tail $aFile]]
2425     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2426   }
2427
2428   set aLibExt "dylib"
2429   if { $theIsStatic == 1 } {
2430     set aLibExt "a"
2431     if { "$theTargetType" != "executable" } {
2432       return $aBuildFileSection
2433     }
2434   }
2435
2436   osutils:usedOsLibs $theToolKit "mac" aLibs aFrameworks
2437   set aUsedToolKits [concat $aUsedToolKits $aLibs]
2438   set aUsedToolKits [concat $aUsedToolKits $aFrameworks]
2439   foreach tkx $aUsedToolKits {
2440     set aDepLib    "${tkx}_Dep"
2441     set aDepLibRef "${tkx}_DepRef"
2442
2443     if { ! [info exists aGuidsMap($aDepLib)] } {
2444       set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
2445     }
2446     if { ! [info exists aGuidsMap($aDepLibRef)] } {
2447       set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
2448     }
2449
2450     append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
2451     if {[lsearch -nocase $aFrameworks $tkx] == -1} {
2452       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
2453     } else {
2454       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
2455     }
2456     append aDepsGuids        "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
2457     append aDepsRefGuids     "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
2458   }
2459
2460   return $aBuildFileSection
2461 }
2462
2463 # Generates PBXBuildFile and PBXGroup sections for project file.
2464 proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
2465   upvar $theSrcFileRefSection aSrcFileRefSection
2466   upvar $theGroupSection      aGroupSection
2467   upvar $thePackageGuids      aPackagesGuids
2468   upvar $theSrcFileGuids      aSrcFileGuids
2469   upvar $theGuidsMap          aGuidsMap
2470   upvar $theIncPaths          anIncPaths
2471
2472   set listloc [osutils:tk:units $theToolKit]
2473   set resultloc [osutils:justunix $listloc]
2474   set aBuildFileSection ""
2475   set aPackages [lsort -nocase $resultloc]
2476   if { "$theTargetType" == "executable" } {
2477     set aPackages [list "$theToolKit"]
2478   }
2479
2480   # Generating PBXBuildFile, PBXGroup sections and groups for each package.
2481   foreach fxlo $aPackages {
2482     set xlo       $fxlo
2483     set aPackage "${xlo}_Package"
2484     set aSrcFileRefGuids ""
2485     if { ! [info exists aGuidsMap($aPackage)] } {
2486       set aGuidsMap($aPackage) [OS:genGUID "xcd"]
2487     }
2488
2489     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2490     foreach aSrcFile [lsort $aSrcFiles] {
2491       set aFileExt "sourcecode.cpp.cpp"
2492
2493       if { [file extension $aSrcFile] == ".c" } {
2494         set aFileExt "sourcecode.c.c"
2495       } elseif { [file extension $aSrcFile] == ".mm" } {
2496         set aFileExt "sourcecode.cpp.objcpp"
2497       }
2498
2499       if { ! [info exists aGuidsMap($aSrcFile)] } {
2500         set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
2501       }
2502       set aSrcFileRef "${aSrcFile}_Ref"
2503       if { ! [info exists aGuidsMap($aSrcFileRef)] } {
2504         set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
2505       }
2506       if { ! [info exists written([file tail $aSrcFile])] } {
2507         set written([file tail $aSrcFile]) 1
2508         append aBuildFileSection  "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
2509         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"
2510         append aSrcFileGuids      "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
2511         append aSrcFileRefGuids   "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
2512       } else {
2513         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2514       }
2515     }
2516
2517     append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
2518     append aGroupSection "\t\t\tisa = PBXGroup;\n"
2519     append aGroupSection "\t\t\tchildren = (\n"
2520     append aGroupSection $aSrcFileRefGuids
2521     append aGroupSection "\t\t\t);\n"
2522     append aGroupSection "\t\t\tname = $xlo;\n"
2523     append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
2524     append aGroupSection "\t\t\};\n"
2525
2526     # Storing packages IDs for adding them later as a child of toolkit
2527     append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
2528   }
2529
2530   # Removing unnecessary newline character from the end.
2531   set aPackagesGuids [string replace $aPackagesGuids end end]
2532
2533   return $aBuildFileSection
2534 }
2535
2536 # Creates folders structure and all necessary files for Xcode project.
2537 proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
2538   set aPBXBuildPhase "Headers"
2539   set aRunOnlyForDeployment "0"
2540   set aProductType "library.dynamic"
2541   set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
2542   set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
2543   set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
2544   set aTKDefines [list "OCC_CONVERT_SIGNALS"]
2545
2546   if { "$theTargetType" == "executable" } {
2547     set aPBXBuildPhase "CopyFiles"
2548     set aRunOnlyForDeployment "1"
2549     set aProductType "tool"
2550     set anExecExtension ""
2551     set anExecPrefix ""
2552     set aWrapperExtension ""
2553   } elseif { $theIsStatic == 1 } {
2554     set aProductType "library.static"
2555     set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
2556     set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
2557   }
2558
2559   set aUsername [exec whoami]
2560
2561   # Creation of folders for Xcode projectP.
2562   set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
2563   wokUtils:FILES:mkdir $aToolkitDir
2564   if { ! [file exists $aToolkitDir] } {
2565     puts stderr "Error: Could not create project directory \"$aToolkitDir\""
2566     return
2567   }
2568
2569   set aUserDataDir "${aToolkitDir}/xcuserdata"
2570   wokUtils:FILES:mkdir $aUserDataDir
2571   if { ! [file exists $aUserDataDir] } {
2572     puts stderr "Error: Could not create xcuserdata directorty in \"$aToolkitDir\""
2573     return
2574   }
2575
2576   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
2577   wokUtils:FILES:mkdir $aUserDataDir
2578   if { ! [file exists $aUserDataDir] } {
2579     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$aToolkitDir\"/xcuserdata"
2580     return
2581   }
2582
2583   set aSchemesDir "${aUserDataDir}/xcschemes"
2584   wokUtils:FILES:mkdir $aSchemesDir
2585   if { ! [file exists $aSchemesDir] } {
2586     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
2587     return
2588   }
2589   # End of folders creation.
2590
2591   # Generating GUID for tookit.
2592   upvar $theGuidsMap aGuidsMap
2593   if { ! [info exists aGuidsMap($theToolKit)] } {
2594     set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
2595   }
2596
2597   # Creating xcscheme file for toolkit from template.
2598   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
2599   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
2600   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
2601   set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme"  "w"]
2602   puts $aXcschemeFile $aXcschemeTmpl
2603   close $aXcschemeFile
2604
2605   # Creating xcschememanagement.plist file for toolkit from template.
2606   set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
2607   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
2608   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
2609   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
2610   puts $aPlistFile $aPlistTmpl
2611   close $aPlistFile
2612
2613   # Creating project.pbxproj file for toolkit.
2614   set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
2615   puts $aPbxprojFile "// !\$*UTF8*\$!"
2616   puts $aPbxprojFile "\{"
2617   puts $aPbxprojFile "\tarchiveVersion = 1;"
2618   puts $aPbxprojFile "\tclasses = \{"
2619   puts $aPbxprojFile "\t\};"
2620   puts $aPbxprojFile "\tobjectVersion = 46;"
2621   puts $aPbxprojFile "\tobjects = \{\n"
2622
2623   # Begin PBXBuildFile section
2624   set aPackagesGuids ""
2625   set aGroupSection ""
2626   set aSrcFileRefSection ""
2627   set aSrcFileGuids ""
2628   set aDepsFileRefSection ""
2629   set aDepsGuids ""
2630   set aDepsRefGuids ""
2631   set anIncPaths [list "../../../inc"]
2632   set anLibPaths ""
2633
2634   if { [info exists ::env(CSF_OPT_INC)] } {
2635     set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
2636     foreach anIncCfgPath $anIncCfg {
2637       lappend anIncPaths $anIncCfgPath
2638     }
2639   }
2640   if { [info exists ::env(CSF_OPT_LIB64)] } {
2641     set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
2642     foreach anLibCfgPath $anLibCfg {
2643       lappend anLibPaths $anLibCfgPath
2644     }
2645   }
2646
2647   puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
2648   puts $aPbxprojFile [osutils:xcdtk:deps    $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $theIsStatic]
2649   # End PBXBuildFile section
2650
2651   # Begin PBXFileReference section
2652   set aToolkitLib "lib${theToolKit}.dylib"
2653   set aPath "$aToolkitLib"
2654   if { "$theTargetType" == "executable" } {
2655     set aPath "$theToolKit"
2656   } elseif { $theIsStatic == 1 } {
2657     set aToolkitLib "lib${theToolKit}.a"
2658   }
2659
2660   if { ! [info exists aGuidsMap($aToolkitLib)] } {
2661     set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
2662   }
2663
2664   puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
2665   puts $aPbxprojFile $aSrcFileRefSection
2666   puts $aPbxprojFile $aDepsFileRefSection
2667   # End PBXFileReference section
2668
2669
2670   # Begin PBXFrameworksBuildPhase section
2671   set aTkFrameworks "${theToolKit}_Frameworks"
2672   if { ! [info exists aGuidsMap($aTkFrameworks)] } {
2673     set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
2674   }
2675
2676   puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
2677   puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
2678   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2679   puts $aPbxprojFile "\t\t\tfiles = ("
2680   puts $aPbxprojFile $aDepsGuids
2681   puts $aPbxprojFile "\t\t\t);"
2682   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2683   puts $aPbxprojFile "\t\t\};\n"
2684   # End PBXFrameworksBuildPhase section
2685
2686   # Begin PBXGroup section
2687   set aTkPBXGroup "${theToolKit}_PBXGroup"
2688   if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
2689     set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
2690   }
2691
2692   set aTkSrcGroup "${theToolKit}_SrcGroup"
2693   if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
2694     set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
2695   }
2696
2697   puts $aPbxprojFile $aGroupSection
2698   puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
2699   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2700   puts $aPbxprojFile "\t\t\tchildren = ("
2701   puts $aPbxprojFile $aDepsRefGuids
2702   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
2703   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
2704   puts $aPbxprojFile "\t\t\t);"
2705   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2706   puts $aPbxprojFile "\t\t\};"
2707   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
2708   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2709   puts $aPbxprojFile "\t\t\tchildren = ("
2710   puts $aPbxprojFile $aPackagesGuids
2711   puts $aPbxprojFile "\t\t\t);"
2712   puts $aPbxprojFile "\t\t\tname = \"Source files\";"
2713   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2714   puts $aPbxprojFile "\t\t\};\n"
2715   # End PBXGroup section
2716
2717   # Begin PBXHeadersBuildPhase section
2718   set aTkHeaders "${theToolKit}_Headers"
2719   if { ! [info exists aGuidsMap($aTkHeaders)] } {
2720     set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
2721   }
2722
2723   puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
2724   puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
2725   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2726   puts $aPbxprojFile "\t\t\tfiles = ("
2727   puts $aPbxprojFile "\t\t\t);"
2728   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
2729   puts $aPbxprojFile "\t\t\};\n"
2730   # End PBXHeadersBuildPhase section
2731
2732   # Begin PBXNativeTarget section
2733   set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
2734   if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
2735     set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
2736   }
2737
2738   set aTkSources "${theToolKit}_Sources"
2739   if { ! [info exists aGuidsMap($aTkSources)] } {
2740     set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
2741   }
2742
2743   puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
2744   puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
2745   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
2746   puts $aPbxprojFile "\t\t\tbuildPhases = ("
2747   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
2748   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
2749   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
2750   puts $aPbxprojFile "\t\t\t);"
2751   puts $aPbxprojFile "\t\t\tbuildRules = ("
2752   puts $aPbxprojFile "\t\t\t);"
2753   puts $aPbxprojFile "\t\t\tdependencies = ("
2754   puts $aPbxprojFile "\t\t\t);"
2755   puts $aPbxprojFile "\t\t\tname = $theToolKit;"
2756   puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
2757   puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
2758   puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
2759   puts $aPbxprojFile "\t\t\};\n"
2760   # End PBXNativeTarget section
2761
2762   # Begin PBXProject section
2763   set aTkProjectObj "${theToolKit}_ProjectObj"
2764   if { ! [info exists aGuidsMap($aTkProjectObj)] } {
2765     set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
2766   }
2767
2768   set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
2769   if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
2770     set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
2771   }
2772
2773   puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
2774   puts $aPbxprojFile "\t\t\tisa = PBXProject;"
2775   puts $aPbxprojFile "\t\t\tattributes = \{"
2776   puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
2777   puts $aPbxprojFile "\t\t\t\};"
2778   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
2779   puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
2780   puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
2781   puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
2782   puts $aPbxprojFile "\t\t\tknownRegions = ("
2783   puts $aPbxprojFile "\t\t\t\ten,"
2784   puts $aPbxprojFile "\t\t\t);"
2785   puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
2786   puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
2787   puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
2788   puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
2789   puts $aPbxprojFile "\t\t\ttargets = ("
2790   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
2791   puts $aPbxprojFile "\t\t\t);"
2792   puts $aPbxprojFile "\t\t\};\n"
2793   # End PBXProject section
2794
2795   # Begin PBXSourcesBuildPhase section
2796   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
2797   puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
2798   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2799   puts $aPbxprojFile "\t\t\tfiles = ("
2800   puts $aPbxprojFile $aSrcFileGuids
2801   puts $aPbxprojFile "\t\t\t);"
2802   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2803   puts $aPbxprojFile "\t\t\};\n"
2804   # End PBXSourcesBuildPhase section
2805
2806   # Begin XCBuildConfiguration section
2807   set aTkDebugProject "${theToolKit}_DebugProject"
2808   if { ! [info exists aGuidsMap($aTkDebugProject)] } {
2809     set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
2810   }
2811
2812   set aTkReleaseProject "${theToolKit}_ReleaseProject"
2813   if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
2814     set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
2815   }
2816
2817   set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
2818   if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
2819     set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
2820   }
2821
2822   set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
2823   if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
2824     set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
2825   }
2826
2827   # Debug target
2828   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
2829   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2830   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2831
2832   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
2833   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
2834   if { "$thePlatform" == "ios" } {
2835     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
2836     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
2837     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
2838     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
2839     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
2840   }
2841   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
2842   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
2843   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
2844   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
2845   puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
2846   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
2847   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
2848   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2849   puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
2850   puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
2851   puts $aPbxprojFile "\t\t\t\t);"
2852   puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
2853   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
2854   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
2855   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
2856   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
2857   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
2858   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
2859   if { "$thePlatform" == "ios" } {
2860     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
2861     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
2862   } else {
2863     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
2864   }
2865   puts $aPbxprojFile "\t\t\t\};"
2866
2867   puts $aPbxprojFile "\t\t\tname = Debug;"
2868   puts $aPbxprojFile "\t\t\};"
2869
2870   # Release target
2871   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
2872   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2873   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2874
2875   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
2876   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
2877   if { "$thePlatform" == "ios" } {
2878     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
2879     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
2880     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
2881     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
2882     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
2883   }
2884   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
2885   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
2886   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
2887   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
2888   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
2889   puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
2890   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
2891   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
2892   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
2893   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
2894   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
2895   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
2896   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
2897   if { "$thePlatform" == "ios" } {
2898     puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
2899     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
2900   }
2901   puts $aPbxprojFile "\t\t\t\};"
2902   puts $aPbxprojFile "\t\t\tname = Release;"
2903   puts $aPbxprojFile "\t\t\};"
2904   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
2905   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2906   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2907   puts $aPbxprojFile "${anExecExtension}"
2908   puts $aPbxprojFile "${anExecPrefix}"
2909   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2910   foreach aMacro $aTKDefines {
2911     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
2912   }
2913   puts $aPbxprojFile "\t\t\t\t);"
2914
2915   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
2916   foreach anIncPath $anIncPaths {
2917     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
2918   }
2919   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
2920   puts $aPbxprojFile "\t\t\t\t);"
2921
2922   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
2923   foreach anLibPath $anLibPaths {
2924     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
2925   }
2926   puts $aPbxprojFile "\t\t\t\t);"
2927
2928   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
2929   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
2930   puts $aPbxprojFile "\t\t\t\t);"
2931   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
2932   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
2933   puts $aPbxprojFile "\t\t\t\t);"
2934   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
2935   set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
2936   foreach anIncPath $anIncPaths {
2937     append anUserHeaderSearchPath " ${anIncPath}"
2938   }
2939   append anUserHeaderSearchPath "\";"
2940   puts $aPbxprojFile $anUserHeaderSearchPath
2941   puts $aPbxprojFile "${aWrapperExtension}"
2942   puts $aPbxprojFile "\t\t\t\};"
2943   puts $aPbxprojFile "\t\t\tname = Debug;"
2944   puts $aPbxprojFile "\t\t\};"
2945   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
2946   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
2947   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
2948   puts $aPbxprojFile "${anExecExtension}"
2949   puts $aPbxprojFile "${anExecPrefix}"
2950   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
2951   foreach aMacro $aTKDefines {
2952     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
2953   }
2954   puts $aPbxprojFile "\t\t\t\t);"
2955   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
2956   foreach anIncPath $anIncPaths {
2957     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
2958   }
2959   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
2960   puts $aPbxprojFile "\t\t\t\t);"
2961
2962   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
2963   foreach anLibPath $anLibPaths {
2964     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
2965   }
2966   puts $aPbxprojFile "\t\t\t\t);"
2967
2968   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
2969   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
2970   puts $aPbxprojFile "\t\t\t\t);"
2971   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
2972   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
2973   puts $aPbxprojFile "\t\t\t\t);"
2974   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
2975   puts $aPbxprojFile $anUserHeaderSearchPath
2976   puts $aPbxprojFile "${aWrapperExtension}"
2977   puts $aPbxprojFile "\t\t\t\};"
2978   puts $aPbxprojFile "\t\t\tname = Release;"
2979   puts $aPbxprojFile "\t\t\};\n"
2980   # End XCBuildConfiguration section
2981
2982   # Begin XCConfigurationList section
2983   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
2984   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
2985   puts $aPbxprojFile "\t\tbuildConfigurations = ("
2986   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
2987   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
2988   puts $aPbxprojFile "\t\t\t);"
2989   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
2990   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
2991   puts $aPbxprojFile "\t\t\};"
2992   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
2993   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
2994   puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
2995   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
2996   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
2997   puts $aPbxprojFile "\t\t\t);"
2998   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
2999   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3000   puts $aPbxprojFile "\t\t\};\n"
3001   # End XCConfigurationList section
3002
3003   puts $aPbxprojFile "\t\};"
3004   puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3005   puts $aPbxprojFile "\}"
3006
3007   close $aPbxprojFile
3008 }
3009
3010 proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3011   set aUsername [exec whoami]
3012
3013   # Creating folders for Xcode project file.
3014   set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3015   wokUtils:FILES:mkdir $anExecutableDir
3016   if { ! [file exists $anExecutableDir] } {
3017     puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3018     return
3019   }
3020
3021   set aUserDataDir "${anExecutableDir}/xcuserdata"
3022   wokUtils:FILES:mkdir $aUserDataDir
3023   if { ! [file exists $aUserDataDir] } {
3024     puts stderr "Error: Could not create xcuserdata directorty in \"$anExecutableDir\""
3025     return
3026   }
3027
3028   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3029   wokUtils:FILES:mkdir $aUserDataDir
3030   if { ! [file exists $aUserDataDir] } {
3031     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$anExecutableDir\"/xcuserdata"
3032     return
3033   }
3034
3035   set aSchemesDir "${aUserDataDir}/xcschemes"
3036   wokUtils:FILES:mkdir $aSchemesDir
3037   if { ! [file exists $aSchemesDir] } {
3038     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3039     return
3040   }
3041   # End folders creation.
3042
3043   # Generating GUID for tookit.
3044   upvar $theGuidsMap aGuidsMap
3045   if { ! [info exists aGuidsMap($theExecutable)] } {
3046     set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3047   }
3048
3049   # Creating xcscheme file for toolkit from template.
3050   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3051   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3052   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3053   set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme"  "w"]
3054   puts $aXcschemeFile $aXcschemeTmpl
3055   close $aXcschemeFile
3056
3057   # Creating xcschememanagement.plist file for toolkit from template.
3058   set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3059   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3060   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3061   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
3062   puts $aPlistFile $aPlistTmpl
3063   close $aPlistFile
3064 }