0024816: Tool for upgrading OCCT and dependent code
[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" "amk" "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" "amk" "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 "amk"}
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       amk   -  AutoMake"
193       return
194   }
195
196   if {!$isTargetDefault} {
197     puts "the \'$anTarget\' target has been applied"
198   }
199   
200   if {"$anTarget" == "amk"} {
201     set targetStation "lin"
202   }
203   set anAdmPath "$path/adm"
204
205   OS:MKPRC "$anAdmPath" "$anTarget" "$aLibType" "$aPlatform"
206
207   genprojbat "$anAdmPath" "$anTarget"
208 }
209
210 proc genprojbat {thePath theIDE} {
211   global path
212   
213   set anOsIncPath "$path/src/OS"
214   set anOsRootPath "$path"
215
216   set aTargetPlatform "lin"
217   if { "$::tcl_platform(platform)" == "windows" } {
218     set aTargetPlatform "wnt"
219   }
220   
221   if {[regexp {(vc)[0-9]*$} $theIDE] == 1} {
222     set aTargetPlatform wnt
223   } elseif {"$theIDE" == "amk"} {
224     set aTargetPlatform lin
225   } elseif {"$theIDE" == "xcd"} {
226     set aTargetPlatform mac
227   }
228
229   set aTargetPlatformExt sh
230   if { "$aTargetPlatform" == "wnt" } {
231     set aTargetPlatformExt bat
232   }
233
234   set aBox [file normalize "$thePath/.."]
235
236   if {"$theIDE" != "cmake"} {
237     set anEnvTmplFile [open "$path/adm/templates/env.${aTargetPlatformExt}" "r"]
238     set anEnvTmpl [read $anEnvTmplFile]
239     close $anEnvTmplFile
240
241     set aCasRoot ""
242     if { [file normalize "$anOsRootPath"] != "$aBox" } {
243       set aCasRoot [relativePath "$aBox" "$anOsRootPath"]
244     }
245     set anOsIncPath [relativePath "$aBox" "$anOsRootPath"]
246
247     regsub -all -- {__CASROOT__}   $anEnvTmpl "$aCasRoot" anEnvTmpl
248
249     set anEnvFile [open "$aBox/env.${aTargetPlatformExt}" "w"]
250     puts $anEnvFile $anEnvTmpl
251     close $anEnvFile
252
253     file copy -force -- "$path/adm/templates/draw.${aTargetPlatformExt}" "$aBox/draw.${aTargetPlatformExt}"
254   }
255
256   if {[regexp {(vc)[0-9]*$} $theIDE] == 1} {
257     file copy -force -- "$path/adm/templates/msvc.bat" "$aBox/msvc.bat"
258   } else {
259     switch -exact -- "$theIDE" {
260       "cbp"   { file copy -force -- "$path/adm/templates/codeblocks.sh" "$aBox/codeblocks.sh" }
261       "xcd"   { file copy -force -- "$path/adm/templates/xcode.sh"      "$aBox/xcode.sh" }
262     }
263   }
264 }
265
266 ###### MSVC #############################################################33
267 proc removeAllOccurrencesOf { theObject theList } {
268   set aSortIndices [lsort -decreasing [lsearch -all -nocase $theList $theObject]]
269   foreach anIndex $aSortIndices {
270     set theList [lreplace $theList $anIndex $anIndex]
271   }
272   return $theList
273 }
274
275 set aTKNullKey "TKNull"
276 set THE_GUIDS_LIST($aTKNullKey) "{00000000-0000-0000-0000-000000000000}"
277
278 # Entry function to generate project files and solutions for IDE
279 proc OS:MKPRC { {theOutDir {}} {theIDE ""} {theLibType "dynamic"} {thePlatform ""} } {
280   global path targetStation
281   set aSupportedIDE { "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "cbp" "amk" "xcd" }
282
283   if { [lsearch $aSupportedIDE $theIDE] < 0 } {
284     puts stderr "WOK does not support generation of project files for the selected IDE: $theIDE\nSupported IDEs: [join ${aSupportedIDE} " "]"
285     return
286   }
287   
288   set anOutRoot $theOutDir
289   if { $anOutRoot == "" } {
290     error "Error : \"theOutDir\" is not initialized"
291   }
292
293   # Create output directory
294   set aWokStation "$targetStation"
295
296   if { [lsearch -exact {vc7 vc8 vc9 vc10 vc11 vc12 vc14} $theIDE] != -1 } {
297     set aWokStation "msvc"
298   }
299
300   set anOutDir "${anOutRoot}/${aWokStation}/${theIDE}"
301
302   # read map of already generated GUIDs
303   set aGuidsFilePath [file join $anOutDir "wok_${theIDE}_guids.txt"]
304   if [file exists "$aGuidsFilePath"] {
305     set aFileIn [open "$aGuidsFilePath" r]
306     set aFileDataRaw [read $aFileIn]
307     close $aFileIn
308     set aFileData [split $aFileDataRaw "\n"]
309     foreach aLine $aFileData {
310       set aLineSplt [split $aLine "="]
311       if { [llength $aLineSplt] == 2 } {
312         set ::THE_GUIDS_LIST([lindex $aLineSplt 0]) [lindex $aLineSplt 1]
313       }
314     }
315   }
316
317   # make list of modules and platforms
318   set aModules [OS:init]
319   if { "$thePlatform" == "ios" } {
320     set goaway [list Draw]
321     set aModules [osutils:juststation $goaway $aModules]
322   }
323
324   # generate one solution for all projects if complete OS or VAS is processed
325   set anAllSolution "OCCT"
326
327   wokUtils:FILES:mkdir $anOutDir
328   if { ![file exists $anOutDir] } {
329     puts stderr "Error: Could not create output directory \"$anOutDir\""
330     return
331   }
332
333   # create the out dir if it does not exist
334   if (![file isdirectory $path/inc]) {
335     puts "$path/inc folder does not exists and will be created"
336     wokUtils:FILES:mkdir $path/inc
337   }
338
339   # collect all required header files
340   puts "Collecting required header files into $path/inc ..."
341   osutils:collectinc $aModules $path/inc $targetStation
342
343   # Generating project files for the selected IDE
344   switch -exact -- "$theIDE" {
345     "vc7"   -
346     "vc8"   -
347     "vc9"   -
348     "vc10"   -
349     "vc11"   -
350     "vc12"   -
351     "vc14"  { OS:MKVC  $anOutDir $aModules $anAllSolution $theIDE }
352     "cbp"   { OS:MKCBP $anOutDir $aModules $anAllSolution }
353     "amk"   { OS:MKAMK $anOutDir $aModules "adm/${aWokStation}/${theIDE}"}
354     "xcd"   {
355       set ::THE_GUIDS_LIST($::aTKNullKey) "000000000000000000000000"
356       OS:MKXCD $anOutDir $aModules $anAllSolution $theLibType $thePlatform
357     }
358   }
359
360   # Store generated GUIDs map
361   set anOutFile [open "$aGuidsFilePath" "w"]
362   fconfigure $anOutFile -translation lf
363   foreach aKey [array names ::THE_GUIDS_LIST] {
364     set aValue $::THE_GUIDS_LIST($aKey)
365     puts $anOutFile "${aKey}=${aValue}"
366   }
367   close $anOutFile
368 }
369
370 # Function to generate Visual Studio solution and project files
371 proc OS:MKVC { theOutDir {theModules {}} {theAllSolution ""} {theVcVer "vc8"} } {
372
373   puts stderr "Generating VS project files for $theVcVer"
374
375   # generate projects for toolkits and separate solution for each module
376   foreach aModule $theModules {
377     OS:vcsolution $theVcVer $aModule $aModule $theOutDir ::THE_GUIDS_LIST
378     OS:vcproj     $theVcVer $aModule          $theOutDir ::THE_GUIDS_LIST
379   }
380
381   # generate single solution "OCCT" containing projects from all modules
382   if { "$theAllSolution" != "" } {
383     OS:vcsolution $theVcVer $theAllSolution $theModules $theOutDir ::THE_GUIDS_LIST
384   }
385
386   puts "The Visual Studio solution and project files are stored in the $theOutDir directory"
387 }
388
389 proc OS:init {{os {}}} {
390     global path
391     global env
392     global tcl_platform
393     
394     set askplat $os
395     if { "$os" == "" } {
396       set os $tcl_platform(os)
397     }
398
399     ;# Load list of OCCT modules and their definitions
400     source "$path/src/OS/Modules.tcl"
401     set Modules {}
402     foreach module [OS:Modules] {
403         set f "$path/src/OS/${module}.tcl"
404         if [file exists $f] {
405             source $f
406             lappend Modules $module
407         } else {
408             puts stderr "Definition file for module $module is not found in unit OS"
409         }
410     }
411
412     # Load list of products and their definitions
413 #    set Products [woklocate -p VAS:source:Products.tcl]
414     #if { "$Products" != "" } {
415         #source "$Products"
416         #foreach product [VAS:Products] {
417             #set f [woklocate -p VAS:source:${product}.tcl]
418             #if [file exists $f] {
419                 #source $f
420             #} else {
421                 #puts stderr "Definition file for product $product is not found in unit VAS"
422             #}
423         #}
424     #}
425
426     return $Modules
427 }
428
429 # topological sort. returns a list {  {a h} {b g} {c f} {c h} {d i}  } => { d a b c i g f h }
430 proc wokUtils:EASY:tsort { listofpairs } {
431     foreach x $listofpairs {
432         set e1 [lindex $x 0]
433         set e2 [lindex $x 1]
434         if ![info exists pcnt($e1)] {
435             set pcnt($e1) 0
436         }
437         if ![ info exists pcnt($e2)] {
438             set pcnt($e2) 1
439         } else {
440             incr pcnt($e2)
441         }
442         if ![info exists scnt($e1)] {
443             set scnt($e1) 1
444         } else {
445             incr scnt($e1)
446         }
447         set l {}
448         if [info exists slist($e1)] {
449             set l $slist($e1)
450         }
451         lappend l $e2
452         set slist($e1) $l
453     }
454     set nodecnt 0
455     set back 0
456     foreach node [array names pcnt] {
457         incr nodecnt
458         if { $pcnt($node) == 0 } {
459             incr back
460             set q($back) $node
461         }
462         if ![info exists scnt($node)] {
463             set scnt($node) 0
464         }
465     }
466     set res {}
467     for {set front 1} { $front <= $back } { incr front } {
468         lappend res [set node $q($front)]
469         for {set i 1} {$i <= $scnt($node) } { incr i } {
470             set ll $slist($node)
471             set j [expr {$i - 1}]
472             set u [expr { $pcnt([lindex $ll $j]) - 1 }]
473             if { [set pcnt([lindex $ll $j]) $u] == 0 } {
474                 incr back
475                 set q($back) [lindex $ll $j]
476             }
477         }
478     }
479     if { $back != $nodecnt } {
480         puts stderr "input contains a cycle"
481         return {}
482     } else {
483         return $res
484     }
485 }
486
487 proc wokUtils:LIST:Purge { l } {
488     set r {}
489      foreach e $l {
490          if ![info exist tab($e)] {
491              lappend r $e
492              set tab($e) {}
493          } 
494      }
495      return $r
496 }
497
498 # Read file pointed to by path
499 # 1. sort = 1 tri 
500 # 2. trim = 1 plusieurs blancs => 1 seul blanc
501 # 3. purge= not yet implemented.
502 # 4. emptl= dont process blank lines
503 proc wokUtils:FILES:FileToList { path {sort 0} {trim 0} {purge 0} {emptl 1} } {
504     if ![ catch { set id [ open $path r ] } ] {
505         set l  {}
506         while {[gets $id line] >= 0 } {
507             if { $trim } {
508                 regsub -all {[ ]+} $line " " line
509             }
510             if { $emptl } {
511                 if { [string length ${line}] != 0 } {
512                     lappend l $line
513                 }
514             } else {
515                 lappend l $line
516             }
517         }
518         close $id
519         if { $sort } {
520             return [lsort $l]
521         } else {
522             return $l
523         }
524     } else {
525         return {}
526     }
527 }
528
529 # retorn the list of executables in module.
530 proc OS:executable { module } {
531     set lret {}
532     foreach XXX  [${module}:ressources] {
533         if { "[lindex $XXX 1]" == "x" } {
534             lappend lret [lindex $XXX 2]
535         }
536     }
537     return $lret
538 }
539
540 # Topological sort of toolkits in tklm
541 proc osutils:tk:sort { tklm } {
542   set tkby2 {}
543   foreach tkloc $tklm {
544     set lprg [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
545     foreach tkx  $lprg {
546       if { [lsearch $tklm $tkx] != -1 } {
547         lappend tkby2 [list $tkx $tkloc]
548       } else {
549         lappend tkby2 [list $tkloc {}]
550       }
551     }
552   }
553   set lret {}
554   foreach e [wokUtils:EASY:tsort $tkby2] {
555     if { $e != {} } {
556       lappend lret $e
557     }
558   }
559   return $lret
560 }
561
562 #  close dependencies of ltk. (full wok pathes of toolkits)
563 # The CURRENT WOK LOCATION MUST contains ALL TOOLKITS required.
564 # (locate not performed.)
565 proc osutils:tk:close { ltk } {
566   set result {}
567   set recurse {}
568   foreach dir $ltk {
569     set ids [LibToLink $dir]
570     set eated [osutils:tk:eatpk $ids]
571     set result [concat $result $eated]
572     set ids [LibToLink $dir]
573     set result [concat $result $ids]
574
575     foreach file $eated {
576       set kds "$path/src/$file/EXTERNLIB"
577       if { [osutils:tk:eatpk $kds] !=  {} } {
578         lappend recurse $file
579       }
580     }
581   }
582   if { $recurse != {} } {
583     set result [concat $result [osutils:tk:close $recurse]]
584   }
585   return $result
586 }
587
588 proc osutils:tk:eatpk { EXTERNLIB  } {
589   set l [wokUtils:FILES:FileToList $EXTERNLIB]
590   set lret  {}
591   foreach str $l {
592     if ![regexp -- {(CSF_[^ ]*)} $str csf] {
593       lappend lret $str
594     }
595   }
596   return $lret
597 }
598 # Define libraries to link using only EXTERNLIB file
599
600 proc LibToLink {theTKit} {
601   global path
602   regexp {^.*:([^:]+)$} $theTKit dummy theTKit
603   set type [_get_type $theTKit]
604   if {$type != "t" && $type != "x"} {
605     return
606   }
607   set aToolkits {}
608   set anExtLibList [osutils:tk:eatpk "$path/src/$theTKit/EXTERNLIB"]
609   foreach anExtLib $anExtLibList {
610     set aFullPath [LocateRecur $anExtLib]
611     if { "$aFullPath" != "" && [_get_type $anExtLib] == "t" } {
612       lappend aToolkits $anExtLib
613     }
614   }
615   return $aToolkits
616 }
617 # Search unit recursively
618
619 proc LocateRecur {theName} {
620   global path
621   set theNamePath "$path/src/$theName"
622   if {[file isdirectory $theNamePath]} {
623     return $theNamePath
624   }
625   return ""
626 }
627
628 proc OS:genGUID { {theIDE "vc"} } {
629   if { "$theIDE" == "vc" } {
630     set p1 "[format %07X [expr { int(rand() * 268435456) }]][format %X [expr { int(rand() * 16) }]]"
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 %06X [expr { int(rand() * 16777216) }]][format %06X [expr { int(rand() * 16777216) }]]"
635     return "{$p1-$p2-$p3-$p4-$p5}"
636   } else {
637     set p1 "[format %04X [expr { int(rand() * 6536) }]]"
638     set p2 "[format %04X [expr { int(rand() * 6536) }]]"
639     set p3 "[format %04X [expr { int(rand() * 6536) }]]"
640     set p4 "[format %04X [expr { int(rand() * 6536) }]]"
641     set p5 "[format %04X [expr { int(rand() * 6536) }]]"
642     set p6 "[format %04X [expr { int(rand() * 6536) }]]"
643     return "$p1$p2$p3$p4$p5$p6"
644   }
645 }
646
647 # collect all include file that required for theModules in theOutDir
648 proc osutils:collectinc {theModules theIncPath theTargetStation} {
649   global path
650
651   set aCasRoot [file normalize $path]
652   set anIncPath [file normalize $theIncPath]
653
654   if {![file isdirectory $aCasRoot]} {
655     puts "OCCT directory is not defined correctly: $aCasRoot"
656     return
657   }
658
659   set anUsedToolKits {}
660   foreach aModule $theModules {
661     foreach aToolKit [${aModule}:toolkits] {
662       lappend anUsedToolKits $aToolKit
663
664       foreach aDependency [LibToLink $aToolKit] {
665         lappend anUsedToolKits $aDependency
666       }
667     }
668     foreach anExecutable [OS:executable ${aModule}] {
669       lappend anUsedToolKits $anExecutable
670
671       foreach aDependency [LibToLink $anExecutable] {
672         lappend anUsedToolKits $aDependency
673       }
674     }
675   }
676   lsort -unique $anUsedToolKits
677
678   set anUnits {}
679   foreach anUsedToolKit $anUsedToolKits {
680     set anUnits [concat $anUnits [osutils:tk:units $anUsedToolKit]]
681   }
682   lsort -unique $anUnits
683
684   if { [info exists ::env(SHORTCUT_HEADERS)] && 
685        $::env(SHORTCUT_HEADERS) == "true" } {
686     # template preparation
687     if { ![file exists $aCasRoot/adm/templates/header.in] } {
688       puts "template file does not exist: $aCasRoot/adm/templates/header.in"
689       return
690     }
691     set aHeaderTmpl [wokUtils:FILES:FileToString $aCasRoot/adm/templates/header.in]
692
693     # relative anIncPath in connection with aCasRoot/src
694     set aFromBuildIncToSrcPath [relativePath "$anIncPath" "$aCasRoot/src"]
695
696     # create and copy short-cut header files
697     foreach anUnit $anUnits {
698       set aHFiles [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.h"]
699       foreach aHeaderFile [concat [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.\[hgl\]xx"] $aHFiles] {
700         set aHeaderFileName [file tail $aHeaderFile]
701
702         regsub -all -- {@OCCT_HEADER_FILE@} $aHeaderTmpl "$aFromBuildIncToSrcPath/$anUnit/$aHeaderFileName" aShortCutHeaderFileContent
703
704         if {[file exists "$theIncPath/$aHeaderFileName"] && [file readable "$theIncPath/$aHeaderFileName"]} {
705           set fp [open "$theIncPath/$aHeaderFileName" r]
706           set aHeaderContent [read $fp]
707           close $fp
708
709           # minus eof
710           set aHeaderLenght  [expr [string length $aHeaderContent] - 1]
711
712           if {$aHeaderLenght == [string length $aShortCutHeaderFileContent]} {
713             # remove eof from string
714             set aHeaderContent [string range $aHeaderContent 0 [expr $aHeaderLenght - 1]]
715
716             if {[string compare $aShortCutHeaderFileContent $aHeaderContent] == 0} {
717               continue
718             }
719           }
720         }
721
722         set aShortCutHeaderFile [open "$theIncPath/$aHeaderFileName" "w"]
723         fconfigure $aShortCutHeaderFile -translation lf
724         puts $aShortCutHeaderFile $aShortCutHeaderFileContent
725         close $aShortCutHeaderFile
726       }
727     }  
728   } else {
729     set nbcopied 0
730     foreach anUnit $anUnits {
731       set aHFiles [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.h"]
732       foreach aHeaderFile [concat [glob -nocomplain -dir $aCasRoot/src/$anUnit "*.\[hgl\]xx"] $aHFiles] {
733         set aHeaderFileName [file tail $aHeaderFile]
734
735         # copy file only if target does not exist or is older than original
736         set torig [file mtime $aHeaderFile]
737         if { ! [file isfile $anIncPath/$aHeaderFileName] } {
738           set tcopy 0
739         } else {
740           set tcopy [file mtime $anIncPath/$aHeaderFileName]
741         }
742         if { $tcopy < $torig } {
743           incr nbcopied
744           file copy -force $aHeaderFile $anIncPath/$aHeaderFileName
745         } elseif { $tcopy != $torig } {
746           puts "Warning: file $anIncPath/$aHeaderFileName is newer than $aHeaderFile, not changed!"
747         }
748       }
749     }
750     puts "Info: $nbcopied files updated"
751   }
752 }
753
754 # Generate header for VS solution file
755 proc osutils:vcsolution:header { vcversion } {
756   if { "$vcversion" == "vc7" } {
757     append var \
758       "Microsoft Visual Studio Solution File, Format Version 8.00\n"
759   } elseif { "$vcversion" == "vc8" } {
760     append var \
761       "Microsoft Visual Studio Solution File, Format Version 9.00\n" \
762       "# Visual Studio 2005\n"
763   } elseif { "$vcversion" == "vc9" } {
764     append var \
765       "Microsoft Visual Studio Solution File, Format Version 10.00\n" \
766       "# Visual Studio 2008\n"
767   } elseif { "$vcversion" == "vc10" } {
768     append var \
769       "Microsoft Visual Studio Solution File, Format Version 11.00\n" \
770       "# Visual Studio 2010\n"
771   } elseif { "$vcversion" == "vc11" } {
772     append var \
773       "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
774       "# Visual Studio 2012\n"
775   } elseif { "$vcversion" == "vc12" } {
776     append var \
777       "Microsoft Visual Studio Solution File, Format Version 13.00\n" \
778       "# Visual Studio 2013\n"
779   } elseif { "$vcversion" == "vc14" } {
780     append var \
781       "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
782       "# Visual Studio 14\n"
783   } else {
784     puts stderr "Error: Visual Studio version $vcversion is not supported by this function!"
785   }
786   return $var
787 }
788 # Returns extension (without dot) for project files of given version of VC
789
790 proc osutils:vcproj:ext { vcversion } {
791   if { "$vcversion" == "vc7" || "$vcversion" == "vc8" || "$vcversion" == "vc9" } {
792     return "vcproj"
793   } else {
794     return "vcxproj"
795   }
796 }
797 # Generate start of configuration section of VS solution file
798
799 proc osutils:vcsolution:config:begin { vcversion } {
800   if { "$vcversion" == "vc7" } {
801     append var \
802       "Global\n" \
803       "\tGlobalSection(SolutionConfiguration) = preSolution\n" \
804       "\t\tDebug = Debug\n" \
805       "\t\tRelease = Release\n" \
806       "\tEndGlobalSection\n" \
807       "\tGlobalSection(ProjectConfiguration) = postSolution\n"
808   } else {
809     append var \
810       "Global\n" \
811       "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" \
812       "\t\tDebug|Win32 = Debug|Win32\n" \
813       "\t\tRelease|Win32 = Release|Win32\n" \
814       "\t\tDebug|x64 = Debug|x64\n" \
815       "\t\tRelease|x64 = Release|x64\n" \
816       "\tEndGlobalSection\n" \
817       "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"
818   }
819   return $var
820 }
821 # Generate part of configuration section of VS solution file describing one project
822
823 proc osutils:vcsolution:config:project { vcversion guid } {
824   if { "$vcversion" == "vc7" } {
825     append var \
826       "\t\t$guid.Debug.ActiveCfg = Debug|Win32\n" \
827       "\t\t$guid.Debug.Build.0 = Debug|Win32\n" \
828       "\t\t$guid.Release.ActiveCfg = Release|Win32\n" \
829       "\t\t$guid.Release.Build.0 = Release|Win32\n"
830   } else {
831     append var \
832       "\t\t$guid.Debug|Win32.ActiveCfg = Debug|Win32\n" \
833       "\t\t$guid.Debug|Win32.Build.0 = Debug|Win32\n" \
834       "\t\t$guid.Release|Win32.ActiveCfg = Release|Win32\n" \
835       "\t\t$guid.Release|Win32.Build.0 = Release|Win32\n" \
836       "\t\t$guid.Debug|x64.ActiveCfg = Debug|x64\n" \
837       "\t\t$guid.Debug|x64.Build.0 = Debug|x64\n" \
838       "\t\t$guid.Release|x64.ActiveCfg = Release|x64\n" \
839       "\t\t$guid.Release|x64.Build.0 = Release|x64\n"
840   }
841   return $var
842 }
843 # Generate start of configuration section of VS solution file
844
845 proc osutils:vcsolution:config:end { vcversion } {
846   if { "$vcversion" == "vc7" } {
847     append var \
848       "\tEndGlobalSection\n" \
849       "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" \
850       "\tEndGlobalSection\n" \
851       "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" \
852       "\tEndGlobalSection\n"
853   } else {
854     append var \
855       "\tEndGlobalSection\n" \
856       "\tGlobalSection(SolutionProperties) = preSolution\n" \
857       "\t\tHideSolutionNode = FALSE\n" \
858       "\tEndGlobalSection\n"
859   }
860   return $var
861 }
862 # generate Visual Studio solution file
863 # if module is empty, generates one solution for all known modules
864
865 proc OS:vcsolution { theVcVer theSolName theModules theOutDir theGuidsMap } {
866   global path
867   upvar $theGuidsMap aGuidsMap
868
869   # collect list of projects to be created
870   set aProjects {}
871   set aDependencies {}
872   foreach aModule $theModules {
873     # toolkits
874     foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
875       lappend aProjects $aToolKit
876       lappend aProjectsInModule($aModule) $aToolKit
877       lappend aDependencies [LibToLink $aToolKit]
878     }
879     # executables, assume one project per cxx file...
880     foreach aUnit [OS:executable ${aModule}] {
881       set aUnitLoc $aUnit
882       set src_files [_get_used_files $aUnit false]
883       set aSrcFiles {}
884       foreach s $src_files {
885         regexp {source ([^\s]+)} $s dummy name
886         lappend aSrcFiles $name
887       }
888       foreach aSrcFile $aSrcFiles {
889         set aFileExtension [file extension $aSrcFile]
890         if { $aFileExtension == ".cxx" } {
891           set aPrjName [file rootname $aSrcFile]
892           lappend aProjects $aPrjName
893           lappend aProjectsInModule($aModule) $aPrjName
894           if {[file isdirectory $path/src/$aUnitLoc]} {
895             lappend aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
896           } else {
897             lappend aDependencies {}
898           }
899         }
900       }
901     }
902   }
903
904 # generate GUIDs for projects (unless already known)
905   foreach aProject $aProjects {
906     if { ! [info exists aGuidsMap($aProject)] } {
907       set aGuidsMap($aProject) [OS:genGUID]
908     }
909   }
910
911   # generate solution file
912 #  puts "Generating Visual Studio ($theVcVer) solution file for $theSolName ($aProjects)"
913   append aFileBuff [osutils:vcsolution:header $theVcVer]
914
915   # GUID identifying group projects in Visual Studio
916   set VC_GROUP_GUID "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"
917
918   # generate group projects -- one per module
919   if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
920     foreach aModule $theModules {
921       if { ! [info exists aGuidsMap(_$aModule)] } {
922         set aGuidsMap(_$aModule) [OS:genGUID]
923       }
924       set aGuid $aGuidsMap(_$aModule)
925       append aFileBuff "Project(\"${VC_GROUP_GUID}\") = \"$aModule\", \"$aModule\", \"$aGuid\"\nEndProject\n"
926     }
927   }
928
929   # extension of project files
930   set aProjExt [osutils:vcproj:ext $theVcVer]
931
932   # GUID identifying C++ projects in Visual Studio
933   set VC_CPP_GUID "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
934
935   # generate normal projects
936   set aProjsNb [llength $aProjects]
937   for {set aProjId 0} {$aProjId < $aProjsNb} {incr aProjId} {
938     set aProj [lindex $aProjects $aProjId]
939     set aGuid $aGuidsMap($aProj)
940     append aFileBuff "Project(\"${VC_CPP_GUID}\") = \"$aProj\", \"$aProj.${aProjExt}\", \"$aGuid\"\n"
941     # write projects dependencies information (vc7 to vc9)
942     set aDepGuids ""
943     foreach aDepLib [lindex $aDependencies $aProjId] {
944       if { $aDepLib != $aProj && [lsearch $aProjects $aDepLib] != "-1" } {
945         set depGUID $aGuidsMap($aDepLib)
946         append aDepGuids "\t\t$depGUID = $depGUID\n"
947       }
948     }
949     if { "$aDepGuids" != "" } {
950       append aFileBuff "\tProjectSection(ProjectDependencies) = postProject\n"
951       append aFileBuff "$aDepGuids"
952       append aFileBuff "\tEndProjectSection\n"
953     }
954     append aFileBuff "EndProject\n"
955   }
956
957   # generate configuration section
958   append aFileBuff [osutils:vcsolution:config:begin $theVcVer]
959   foreach aProj $aProjects {
960     append aFileBuff [osutils:vcsolution:config:project $theVcVer $aGuidsMap($aProj)]
961   }
962   append aFileBuff [osutils:vcsolution:config:end $theVcVer]
963
964   # write information of grouping of projects by module
965   if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
966     append aFileBuff "  GlobalSection(NestedProjects) = preSolution\n"
967     foreach aModule $theModules {
968       if { ! [info exists aProjectsInModule($aModule)] } { continue }
969       foreach aProject $aProjectsInModule($aModule) {
970         append aFileBuff "              $aGuidsMap($aProject) = $aGuidsMap(_$aModule)\n"
971       }
972     }
973     append aFileBuff "  EndGlobalSection\n"
974   }
975
976   # final word (footer)
977   append aFileBuff "EndGlobal"
978
979   # write solution
980   set aFile [open [set fdsw [file join $theOutDir ${theSolName}.sln]] w]
981   fconfigure $aFile -translation crlf
982   puts $aFile $aFileBuff
983   close $aFile
984   return [file join $theOutDir ${theSolName}.sln]
985 }
986 # Generate Visual Studio projects for specified version
987
988 proc OS:vcproj { theVcVer theModules theOutDir theGuidsMap } {
989   upvar $theGuidsMap aGuidsMap
990
991   set aProjectFiles {}
992
993   foreach aModule $theModules {
994     foreach aToolKit [${aModule}:toolkits] {
995       lappend aProjectFiles [osutils:vcproj  $theVcVer $theOutDir $aToolKit     aGuidsMap]
996     }
997     foreach anExecutable [OS:executable ${aModule}] {
998       lappend aProjectFiles [osutils:vcprojx $theVcVer $theOutDir $anExecutable aGuidsMap]
999     }
1000   }
1001   return $aProjectFiles
1002 }
1003 # generate template name and load it for given version of Visual Studio and platform
1004
1005 proc osutils:vcproj:readtemplate {theVcVer isexec} {
1006   set anExt $theVcVer
1007   if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1008     set anExt vc10
1009   }
1010
1011   set what "$theVcVer"
1012   set aVerExt [string range $theVcVer 2 end]
1013   set aVerExt "v${aVerExt}0"
1014   set aCmpl32 ""
1015   set aCmpl64 ""
1016   if { $isexec } {
1017     set anExt "${anExt}x"
1018     set what "$what executable"
1019   }
1020   if { "$theVcVer" == "vc10" } {
1021     # SSE2 is enabled by default in vc11+, but not in vc10 for 32-bit target
1022     set aCmpl32 "\n      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>"
1023   }
1024   set aTmpl [osutils:readtemplate $anExt "MS VC++ project ($what)"]
1025   regsub -all -- {__VCVER__}    $aTmpl $theVcVer aTmpl
1026   regsub -all -- {__VCVEREXT__} $aTmpl $aVerExt  aTmpl
1027   regsub -all -- {__VCMPL32__}  $aTmpl $aCmpl32  aTmpl
1028   regsub -all -- {__VCMPL64__}  $aTmpl $aCmpl64  aTmpl
1029   return $aTmpl
1030 }
1031
1032 proc osutils:readtemplate {ext what} {
1033   global env
1034   global path
1035   set loc "$path/adm/templates/template.$ext"
1036   return [wokUtils:FILES:FileToString $loc]
1037 }
1038 # Read a file in a string as is.
1039
1040 proc wokUtils:FILES:FileToString { fin } {
1041     if { [catch { set in [ open $fin r ] } errin] == 0 } {
1042         set strin [read $in [file size $fin]]
1043         close $in
1044         return $strin
1045     } else {
1046         return {}
1047     }
1048 }
1049 # List extensions of compilable files in OCCT
1050
1051 proc osutils:compilable { } {
1052   global targetStation
1053   set aWokStation "$targetStation"
1054   if { "$aWokStation" == "mac" } {
1055     return [list .c .cxx .cpp .mm]
1056   }
1057   return [list .c .cxx .cpp]
1058 }
1059
1060 proc osutils:commonUsedTK { theToolKit } {
1061   global path
1062   set anUsedToolKits [list]
1063   set aDepToolkits [LibToLink $theToolKit]
1064   foreach tkx $aDepToolkits {
1065     if {[_get_type $tkx] == "t"} {
1066       lappend anUsedToolKits "${tkx}"
1067     }
1068   }
1069   return $anUsedToolKits
1070 }
1071
1072 # Return the list of name *CSF_ in a EXTERNLIB description of a toolkit
1073 proc osutils:tk:csfInExternlib { EXTERNLIB } {
1074   set l [wokUtils:FILES:FileToList $EXTERNLIB]
1075   set lret  {STLPort}
1076   foreach str $l {
1077     if [regexp -- {(CSF_[^ ]*)} $str csf] {
1078       lappend lret $csf
1079     }
1080   }
1081   return $lret
1082 }
1083
1084 # @param theCsfLibsMap - libraries  map
1085 # @param theCsfFrmsMap - frameworks map, OS X specific
1086 proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
1087   upvar $theCsfLibsMap aLibsMap
1088   upvar $theCsfFrmsMap aFrmsMap
1089
1090   unset theCsfLibsMap
1091   unset theCsfFrmsMap
1092
1093   if { "$theOS" == "wnt" } {
1094     #  WinAPI libraries
1095     set aLibsMap(CSF_kernel32)     "kernel32.lib"
1096     set aLibsMap(CSF_advapi32)     "advapi32.lib"
1097     set aLibsMap(CSF_gdi32)        "gdi32.lib"
1098     set aLibsMap(CSF_user32)       "user32.lib"
1099     set aLibsMap(CSF_glu32)        "glu32.lib"
1100     set aLibsMap(CSF_opengl32)     "opengl32.lib"
1101     set aLibsMap(CSF_wsock32)      "wsock32.lib"
1102     set aLibsMap(CSF_netapi32)     "netapi32.lib"
1103     set aLibsMap(CSF_AviLibs)      "ws2_32.lib vfw32.lib"
1104     set aLibsMap(CSF_OpenGlLibs)   "opengl32.lib glu32.lib"
1105
1106     set aLibsMap(CSF_QT)           "QtCore4.lib QtGui4.lib"
1107
1108     # VTK
1109     set aLibsMap(CSF_VTK)         [osutils:vtkCsf "wnt"]
1110   } else {
1111     set aLibsMap(CSF_FREETYPE)     "freetype"
1112     if { "$theOS" == "mac" } {
1113       set aLibsMap(CSF_objc)       "objc"
1114       set aFrmsMap(CSF_Appkit)     "Appkit"
1115       set aFrmsMap(CSF_IOKit)      "IOKit"
1116       set aFrmsMap(CSF_OpenGlLibs) "OpenGL"
1117       set aFrmsMap(CSF_TclLibs)    "Tcl"
1118       set aFrmsMap(CSF_TclTkLibs)  "Tk"
1119     } else {
1120       set aLibsMap(CSF_ThreadLibs) "pthread rt"
1121       set aLibsMap(CSF_OpenGlLibs) "GLU GL"
1122       set aLibsMap(CSF_TclLibs)    "tcl8.6"
1123       set aLibsMap(CSF_TclTkLibs)  "X11 tk8.6"
1124       set aLibsMap(CSF_XwLibs)     "X11 Xext Xmu Xi"
1125       set aLibsMap(CSF_MotifLibs)  "X11"
1126     }
1127
1128     # optional 3rd-parties
1129     if { "$::HAVE_TBB" == "true" } {
1130       set aLibsMap(CSF_TBB)        "tbb tbbmalloc"
1131     }
1132     if { "$::HAVE_FREEIMAGE" == "true" } {
1133       set aLibsMap(CSF_FreeImagePlus)  "freeimage"
1134     }
1135     if { "$::HAVE_GL2PS" == "true" } {
1136       set aLibsMap(CSF_GL2PS)      "gl2ps"
1137     }
1138     if { "$::HAVE_VTK" == "true" } {
1139       set aLibsMap(CSF_VTK)         [osutils:vtkCsf "unix"]
1140     }
1141   }
1142 }
1143
1144 # Returns string of library dependencies for generation of Visual Studio project or make lists.
1145 proc osutils:vtkCsf {{theOS ""}} {
1146   set aVtkVer "6.1"
1147
1148   set aLibSuffix ""
1149   set aPathSplitter ":"
1150   
1151   if {"$theOS" == "wnt"} {
1152     set aPathSplitter ";"
1153     set aLibSuffix ".lib"
1154   }
1155
1156   set anOptIncs [split $::env(CSF_OPT_INC) "$aPathSplitter"]
1157   foreach anIncItem $anOptIncs {
1158     if {[regexp -- "vtk-(.*)$" [file tail $anIncItem] dummy aFoundVtkVer]} {
1159       set aVtkVer $aFoundVtkVer
1160     }
1161   }
1162
1163   set aLibArray [list vtkCommonCore vtkCommonDataModel vtkCommonExecutionModel vtkCommonMath vtkCommonTransforms vtkRenderingCore \
1164                       vtkRenderingOpenGL  vtkFiltersGeneral vtkIOCore vtkIOImage vtkImagingCore vtkInteractionStyle]
1165
1166   # Additional suffices for the libraries
1167   set anIdx 0
1168   foreach anItem $aLibArray {
1169     lset aLibArray $anIdx $anItem-$aVtkVer$aLibSuffix
1170     incr anIdx
1171   }
1172
1173   return [join $aLibArray " "]
1174 }
1175
1176 # @param theLibsList   - dependencies (libraries  list)
1177 # @param theFrameworks - dependencies (frameworks list, OS X specific)
1178 proc osutils:usedOsLibs { theToolKit theOS theLibsList theFrameworks } {
1179   global path
1180   upvar $theLibsList   aLibsList
1181   upvar $theFrameworks aFrameworks
1182   set aLibsList   [list]
1183   set aFrameworks [list]
1184
1185   osutils:csfList $theOS aLibsMap aFrmsMap
1186
1187   foreach aCsfElem [osutils:tk:csfInExternlib "$path/src/${theToolKit}/EXTERNLIB"] {
1188     if [info exists aLibsMap($aCsfElem)] {
1189       foreach aLib [split "$aLibsMap($aCsfElem)"] {
1190         if { [lsearch $aLibsList $aLib] == "-1" } {
1191           lappend aLibsList $aLib
1192         }
1193       }
1194     }
1195     if [info exists aFrmsMap($aCsfElem)] {
1196       foreach aFrm [split "$aFrmsMap($aCsfElem)"] {
1197         if { [lsearch $aFrameworks $aFrm] == "-1" } {
1198           lappend aFrameworks $aFrm
1199         }
1200       }
1201     }
1202   }
1203 }
1204
1205 # Returns liste of UD in a toolkit. tkloc is a full path wok.
1206 proc osutils:tk:units { tkloc } {
1207   global path
1208   set l {}
1209   set PACKAGES "$path/src/$tkloc/PACKAGES"
1210   foreach u [wokUtils:FILES:FileToList $PACKAGES] {
1211     if {[file isdirectory "$path/src/$u"]} {
1212       lappend l $u
1213     }
1214   }
1215   if { $l == {} } {
1216     ;#puts stderr "Warning. No devunit included in $tkloc"
1217   }
1218   return $l
1219 }
1220
1221 proc osutils:justwnt { listloc } {
1222   # ImageUtility is required for support for old (<6.5.4) versions of OCCT
1223   set goaway [list Xdps Xw  ImageUtility WOKUnix]
1224   return [osutils:juststation $goaway $listloc]
1225 }
1226
1227 # remove from listloc OpenCascade units indesirables on NT
1228 proc osutils:juststation {goaway listloc} {
1229   global path
1230   set lret {}
1231   foreach u $listloc {
1232     if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1233      || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1234       lappend lret $u
1235     }
1236   }
1237   return $lret
1238 }
1239
1240 # intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1241 # The first list is everything in the first list that wasn't in the second,
1242 # the second list contains the intersection of the two lists, the third list contains everything
1243 # in the second list that wasn't in the first.
1244 proc osutils:intersect3 {list1 list2} {
1245   set la1(0) {} ; unset la1(0)
1246   set lai(0) {} ; unset lai(0)
1247   set la2(0) {} ; unset la2(0)
1248   foreach v $list1 {
1249     set la1($v) {}
1250   }
1251   foreach v $list2 {
1252     set la2($v) {}
1253   }
1254   foreach elem [concat $list1 $list2] {
1255     if {[info exists la1($elem)] && [info exists la2($elem)]} {
1256       unset la1($elem)
1257       unset la2($elem)
1258       set lai($elem) {}
1259     }
1260   }
1261   list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1262 }
1263
1264 # Prepare relative path
1265 proc relativePath {thePathFrom thePathTo} {
1266   if { [file isdirectory "$thePathFrom"] == 0 } {
1267     return ""
1268   }
1269
1270   set aPathFrom [file normalize "$thePathFrom"]
1271   set aPathTo   [file normalize "$thePathTo"]
1272
1273   set aCutedPathFrom "${aPathFrom}/dummy"
1274   set aRelatedDeepPath ""
1275
1276   while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1277     set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1278     # does aPathTo contain aCutedPathFrom?
1279     regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1280     if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1281       if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1282         set aPathTo ".${aPathTo}"
1283       } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1284         set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1285       }
1286       regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1287       regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1288       return $aPathToAfterCut
1289     }
1290     set aRelatedDeepPath "$aRelatedDeepPath../"
1291
1292   }
1293
1294   return $thePathTo
1295 }
1296
1297 proc wokUtils:EASY:bs1 { s } {
1298     regsub -all {/} $s {\\} r
1299     return $r
1300 }
1301
1302 # Returs for a full path the liste of n last directory part
1303 # n = 1 => tail
1304 # n = 2 => dir/file.c
1305 # n = 3 => sdir/dir/file.c
1306 # etc..
1307 proc wokUtils:FILES:wtail { f n } {
1308     set ll [expr [llength [set lif [file split $f]]] -$n]
1309     return [join [lrange $lif $ll end] /]
1310 }
1311
1312 # Generate entry for one source file in Visual Studio 10 project file
1313 proc osutils:vcxproj:file { vcversion file params } {
1314   append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1315   if { $params != "" } {
1316     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1317   }
1318
1319   if { $params != "" } {
1320     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1321   }
1322
1323   if { $params != "" } {
1324     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1325   }
1326
1327   if { $params != "" } {
1328     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1329   }
1330
1331   append text "    </ClCompile>\n"
1332   return $text
1333 }
1334
1335 # Generate Visual Studio 2010 project filters file
1336 proc osutils:vcxproj:filters { dir proj theFilesMap } {
1337   upvar $theFilesMap aFilesMap
1338
1339   # header
1340   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1341   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1342
1343   # list of "filters" (units)
1344   append text "  <ItemGroup>\n"
1345   append text "    <Filter Include=\"Source files\">\n"
1346   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1347   append text "    </Filter>\n"
1348   foreach unit $aFilesMap(units) {
1349     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1350     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1351     append text "    </Filter>\n"
1352   }
1353   append text "  </ItemGroup>\n"
1354
1355   # list of files
1356   append text "  <ItemGroup>\n"
1357   foreach unit $aFilesMap(units) {
1358     foreach file $aFilesMap($unit) {
1359       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1360       append text "      <Filter>Source files\\${unit}</Filter>\n"
1361       append text "    </ClCompile>\n"
1362     }
1363   }
1364   append text "  </ItemGroup>\n"
1365
1366   # end
1367   append text "</Project>"
1368
1369   # write file
1370   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1371   fconfigure $fp -translation crlf
1372   puts $fp $text
1373   close $fp
1374
1375   return ${proj}.vcxproj.filters
1376 }
1377
1378 # Generate Visual Studio 2011 project filters file
1379 proc osutils:vcx1proj:filters { dir proj theFilesMap } {
1380   upvar $theFilesMap aFilesMap
1381
1382   # header
1383   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1384   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1385
1386   # list of "filters" (units)
1387   append text "  <ItemGroup>\n"
1388   append text "    <Filter Include=\"Source files\">\n"
1389   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1390   append text "    </Filter>\n"
1391   foreach unit $aFilesMap(units) {
1392     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1393     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1394     append text "    </Filter>\n"
1395   }
1396   append text "  </ItemGroup>\n"
1397
1398   # list of files
1399   append text "  <ItemGroup>\n"
1400   foreach unit $aFilesMap(units) {
1401     foreach file $aFilesMap($unit) {
1402       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1403       append text "      <Filter>Source files\\${unit}</Filter>\n"
1404       append text "    </ClCompile>\n"
1405     }
1406   }
1407   append text "  </ItemGroup>\n"
1408
1409   append text "  <ItemGroup>\n"
1410   append text "    <ResourceCompile Include=\"${proj}.rc\" />"
1411   append text "  </ItemGroup>\n"
1412
1413   # end
1414   append text "</Project>"
1415
1416   # write file
1417   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1418   fconfigure $fp -translation crlf
1419   puts $fp $text
1420   close $fp
1421
1422   return ${proj}.vcxproj.filters
1423 }
1424
1425 # Generate RC file content for ToolKit from template
1426 proc osutils:readtemplate:rc {theOutDir theToolKit} {
1427   global path
1428   set aLoc "$path/adm/templates/template_dll.rc"
1429   set aBody [wokUtils:FILES:FileToString $aLoc]
1430   regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1431
1432   set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1433   fconfigure $aFile -translation lf
1434   puts $aFile $aBody
1435   close $aFile
1436   return "${theOutDir}/${theToolKit}.rc"
1437 }
1438
1439 # Generate Visual Studio project file for ToolKit
1440 proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1441   if { $theProjTmpl == {} } {set theProjTmpl [osutils:vcproj:readtemplate $theVcVer 0]}
1442
1443   set l_compilable [osutils:compilable]
1444   regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1445
1446   upvar $theGuidsMap aGuidsMap
1447   if { ! [info exists aGuidsMap($theToolKit)] } {
1448     set aGuidsMap($theToolKit) [OS:genGUID]
1449   }
1450   regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1451
1452   set aCommonUsedTK [list]
1453   foreach tkx [osutils:commonUsedTK  $theToolKit] {
1454     lappend aCommonUsedTK "${tkx}.lib"
1455   }
1456
1457   osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
1458   set aUsedToolKits [concat $aCommonUsedTK $aLibs]
1459
1460   # correct names of referred third-party libraries that are named with suffix
1461   # depending on VC version
1462   regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1463
1464   # and put this list to project file
1465   #puts "$theToolKit requires  $aUsedToolKits"
1466   if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1467     set aUsedToolKits [join $aUsedToolKits {;}]
1468   }
1469   regsub -all -- {__TKDEP__} $theProjTmpl $aUsedToolKits theProjTmpl
1470
1471   set anIncPaths "..\\..\\..\\inc"
1472   set aTKDefines ""
1473   set aFilesSection ""
1474   set aVcFilesX(units) ""
1475   set listloc [osutils:tk:units $theToolKit]
1476   set resultloc [osutils:justwnt $listloc]
1477   if [array exists written] { unset written }
1478   #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1479   #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1480   #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1481   #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1482   set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1483   set fxloparamfc   [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1484   set fxloparam ""
1485   foreach fxlo $resultloc {
1486     set xlo $fxlo
1487     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
1488         set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
1489     if {$fxlo_cmplrs_options_cxx == ""} {
1490       set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1491     }
1492         set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1493     if {$fxlo_cmplrs_options_c == ""} {
1494       set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1495     }
1496     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1497     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1498         #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1499         #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo  CXX"
1500         #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1501         #puts "\t6 [wokparam -v %CMPLRS_C_Options   $fxlo] $fxlo  C"
1502     set needparam ""
1503     foreach partopt $fxloparam {
1504       if {[string first "-I" $partopt] == "0"} {
1505         # this is an additional includes search path
1506         continue
1507       }
1508       set needparam "$needparam $partopt"
1509     }
1510
1511     # Format of projects in vc10+ is different from vc7-9
1512     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1513       foreach aSrcFile [lsort $aSrcFiles] {
1514         if { ![info exists written([file tail $aSrcFile])] } {
1515           set written([file tail $aSrcFile]) 1
1516           append aFilesSection [osutils:vcxproj:file $theVcVer $aSrcFile $needparam]
1517         } else {
1518           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1519         }
1520         if { ! [info exists aVcFilesX($xlo)] } { lappend aVcFilesX(units) $xlo }
1521         lappend aVcFilesX($xlo) $aSrcFile
1522       }
1523     } else {
1524       append aFilesSection "\t\t\t<Filter\n"
1525       append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1526       append aFilesSection "\t\t\t\t>\n"
1527       foreach aSrcFile [lsort $aSrcFiles] {
1528         if { ![info exists written([file tail $aSrcFile])] } {
1529           set written([file tail $aSrcFile]) 1
1530           append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1531         } else {
1532           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1533         }
1534       }
1535       append aFilesSection "\t\t\t</Filter>\n"
1536     }
1537
1538     # macros
1539     append aTKDefines ";__${xlo}_DLL"
1540     # common includes
1541 #    append anIncPaths ";..\\..\\..\\src\\${xlo}"
1542   }
1543
1544   regsub -all -- {__TKINC__}  $theProjTmpl $anIncPaths theProjTmpl
1545   regsub -all -- {__TKDEFS__} $theProjTmpl $aTKDefines theProjTmpl
1546   regsub -all -- {__FILES__}  $theProjTmpl $aFilesSection theProjTmpl
1547
1548   # write file
1549   set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1550   fconfigure $aFile -translation crlf
1551   puts $aFile $theProjTmpl
1552   close $aFile
1553
1554   # write filters file for vc10+
1555   if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" || "$theVcVer" == "vc9" } {
1556     # nothing
1557   } elseif { "$theVcVer" == "vc10" } {
1558     lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesX]
1559   } else {
1560     lappend aVcFiles [osutils:vcx1proj:filters $theOutDir $theToolKit aVcFilesX]
1561   }
1562
1563   # write resource file
1564   lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1565
1566   return $aVcFiles
1567 }
1568
1569 # for a unit returns a map containing all its file in the current
1570 # workbench
1571 # local = 1 only local files
1572 proc osutils:tk:loadunit { loc map } {
1573   #puts $loc
1574   upvar $map TLOC
1575   catch { unset TLOC }
1576   set lfiles [_get_used_files $loc]
1577   foreach f $lfiles {
1578     #puts "\t$f"
1579     set t [lindex $f 0]
1580     set p [lindex $f 2]
1581     if [info exists TLOC($t)] {
1582       set l $TLOC($t)
1583       lappend l $p
1584       set TLOC($t) $l
1585     } else {
1586       set TLOC($t) $p
1587     }
1588   }
1589   return
1590 }
1591
1592 # Returns the list of all compilable files name in a toolkit, or devunit of any type
1593 # Call unit filter on units name to accept or reject a unit
1594 # Tfiles lists for each unit the type of file that can be compiled.
1595 proc osutils:tk:files { tkloc  {l_compilable {} } {justail 1} {unitfilter {}} } {
1596   global path
1597   set Tfiles(source,nocdlpack)     {source pubinclude}
1598   set Tfiles(source,toolkit)       {}
1599   set Tfiles(source,executable)    {source pubinclude}
1600   set listloc [concat [osutils:tk:units $tkloc] $tkloc]
1601   #puts " listloc = $listloc"
1602   if { $l_compilable == {} } {
1603     set l_comp [list .c .cxx .cpp]
1604   } else {
1605     set l_comp [$l_compilable]
1606   }
1607   if { $unitfilter == {} } {
1608     set resultloc $listloc
1609   } else {
1610     set resultloc [$unitfilter $listloc]
1611   }
1612   set lret {}
1613   foreach loc $resultloc {
1614     set utyp [_get_type $loc]
1615     #puts "\"$utyp\" \"$loc\""
1616     switch $utyp {
1617          "t" { set utyp "toolkit" }
1618          "n" { set utyp "nocdlpack" }
1619          "x" { set utyp "executable" }
1620     }
1621     if [array exists map] { unset map }
1622     osutils:tk:loadunit $loc map
1623     #puts " loc = $loc === > [array names map]"
1624     set LType $Tfiles(source,${utyp})
1625     foreach typ [array names map] {
1626       if { [lsearch $LType $typ] == -1 } {
1627         unset map($typ)
1628       }
1629     }
1630     foreach type [array names map] {
1631       #puts $type
1632       foreach f $map($type) {
1633         #puts $f
1634         if { [lsearch $l_comp [file extension $f]] != -1 } {
1635           if { $justail == 1 } {
1636             if {$type == "source"} {
1637               if {[lsearch $lret "@top_srcdir@/src/$loc/[file tail $f]"] == -1} {
1638                 lappend lret @top_srcdir@/src/$loc/[file tail $f]
1639               }
1640             }
1641           } else {
1642             lappend lret $f
1643           }
1644         }
1645       }
1646     }
1647   }
1648   return $lret
1649 }
1650
1651 # Generate Visual Studio project file for executable
1652 proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1653   global path
1654   set aVcFiles {}
1655   foreach f [osutils:tk:files $theToolKit osutils:compilable 0] {
1656     if { $theProjTmpl == {} } {
1657       set aProjTmpl [osutils:vcproj:readtemplate $theVcVer 1]
1658     } else {
1659       set aProjTmpl $theProjTmpl
1660     }
1661     set aProjName [file rootname [file tail $f]]
1662     set l_compilable [osutils:compilable]
1663     regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
1664
1665     upvar $theGuidsMap aGuidsMap
1666     if { ! [info exists aGuidsMap($aProjName)] } {
1667       set aGuidsMap($aProjName) [OS:genGUID]
1668     }
1669     regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
1670
1671     set aCommonUsedTK [list]
1672     foreach tkx [osutils:commonUsedTK  $theToolKit] {
1673       lappend aCommonUsedTK "${tkx}.lib"
1674     }
1675
1676     osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
1677     set aUsedToolKits [concat $aCommonUsedTK $aLibs]
1678
1679     # correct names of referred third-party libraries that are named with suffix
1680     # depending on VC version
1681     regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1682
1683 #    puts "$aProjName requires  $aUsedToolKits"
1684     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1685       set aUsedToolKits [join $aUsedToolKits {;}]
1686     }
1687     regsub -all -- {__TKDEP__} $aProjTmpl $aUsedToolKits aProjTmpl
1688
1689     set aFilesSection ""
1690     set aVcFilesX(units) ""
1691
1692     if { ![info exists written([file tail $f])] } {
1693       set written([file tail $f]) 1
1694
1695       if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1696         append aFilesSection [osutils:vcxproj:file $theVcVer $f ""]
1697         if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
1698         lappend aVcFilesX($theToolKit) $f
1699       } else {
1700         append aFilesSection "\t\t\t<Filter\n"
1701         append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
1702         append aFilesSection "\t\t\t\t>\n"
1703         append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
1704         append aFilesSection "\t\t\t</Filter>"
1705       }
1706     } else {
1707       puts "Warning : in vcproj there are than one occurences for [file tail $f]"
1708     }
1709     #puts "$aProjTmpl $aFilesSection"
1710     set aTKDefines ";__${theToolKit}_DLL"
1711     set anIncPaths "..\\..\\..\\inc"
1712     regsub -all -- {__TKINC__}  $aProjTmpl $anIncPaths    aProjTmpl
1713     regsub -all -- {__TKDEFS__} $aProjTmpl $aTKDefines    aProjTmpl
1714     regsub -all -- {__FILES__}  $aProjTmpl $aFilesSection aProjTmpl
1715     regsub -all -- {__CONF__}   $aProjTmpl Application    aProjTmpl
1716
1717     regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
1718
1719     set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
1720     fconfigure $aFile -translation crlf
1721     puts $aFile $aProjTmpl
1722     close $aFile
1723
1724     set aCommonSettingsFile "$aVcFilePath.user"
1725     lappend aVcFiles $aVcFilePath
1726
1727     # write filters file for vc10
1728     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1729       lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesX]
1730     }
1731
1732     set aCommonSettingsFileTmpl ""
1733     if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
1734       # nothing
1735     } elseif { "$theVcVer" == "vc9" } {
1736       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$path/adm/templates/vcproj.user.vc9x"]
1737     } else {
1738       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$path/adm/templates/vcxproj.user.vc10x"]
1739     }
1740     if { "$aCommonSettingsFileTmpl" != "" } {
1741       regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $theVcVer aCommonSettingsFileTmpl
1742
1743       set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
1744       fconfigure $aFile -translation crlf
1745       puts $aFile $aCommonSettingsFileTmpl
1746       close $aFile
1747
1748       lappend aVcFiles "$aCommonSettingsFile"
1749     }
1750   }
1751   return $aVcFiles
1752 }
1753
1754 # Generate entry for one source file in Visual Studio 7 - 9 project file
1755 proc osutils:vcproj:file { theVcVer theFile theOptions } {
1756   append aText "\t\t\t\t<File\n"
1757   append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1758   if { $theOptions == "" } {
1759     append aText "\t\t\t\t</File>\n"
1760     return $aText
1761   }
1762
1763   append aText "\t\t\t\t\t<FileConfiguration\n"
1764   append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
1765   append aText "\t\t\t\t\t\t<Tool\n"
1766   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1767   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1768   foreach aParam $theOptions {
1769     append aText "$aParam "
1770   }
1771   append aText "\"\n"
1772   append aText "\t\t\t\t\t\t/>\n"
1773   append aText "\t\t\t\t\t</FileConfiguration>\n"
1774
1775   append aText "\t\t\t\t\t<FileConfiguration\n"
1776   append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
1777   append aText "\t\t\t\t\t\t<Tool\n"
1778   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1779   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1780   foreach aParam $theOptions {
1781     append aText "$aParam "
1782   }
1783   append aText "\"\n"
1784   append aText "\t\t\t\t\t\t/>\n"
1785   append aText "\t\t\t\t\t</FileConfiguration>\n"
1786   if { "$theVcVer" == "vc7" } {
1787     append aText "\t\t\t\t</File>\n"
1788     return $aText
1789   }
1790
1791   append aText "\t\t\t\t\t<FileConfiguration\n"
1792   append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
1793   append aText "\t\t\t\t\t\t<Tool\n"
1794   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1795   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1796   foreach aParam $theOptions {
1797     append aText "$aParam "
1798   }
1799   append aText "\"\n"
1800   append aText "\t\t\t\t\t\t/>\n"
1801   append aText "\t\t\t\t\t</FileConfiguration>\n"
1802
1803   append aText "\t\t\t\t\t<FileConfiguration\n"
1804   append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
1805   append aText "\t\t\t\t\t\t<Tool\n"
1806   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1807   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1808   foreach aParam $theOptions {
1809     append aText "$aParam "
1810   }
1811   append aText "\"\n"
1812   append aText "\t\t\t\t\t\t/>\n"
1813   append aText "\t\t\t\t\t</FileConfiguration>\n"
1814
1815   append aText "\t\t\t\t</File>\n"
1816   return $aText
1817 }
1818
1819 ### AUTOMAKE ###############################################################################
1820 proc OS:MKAMK { theOutDir {theModules {}} theSubPath} {
1821   global path
1822   wokUtils:FILES:mkdir $theOutDir
1823
1824   foreach aModule $theModules {
1825     foreach aToolKit [$aModule:toolkits] {
1826       puts " toolkit: $aToolKit ==> $path/src/$aToolKit/EXTERNLIB"
1827       wokUtils:FILES:rmdir $theOutDir/$aToolKit
1828       wokUtils:FILES:mkdir $theOutDir/$aToolKit
1829       osutils:tk:mkam $theOutDir/$aToolKit $aToolKit
1830     }
1831     foreach anExecutable [OS:executable $aModule] {
1832       wokUtils:FILES:rmdir $theOutDir/$anExecutable
1833       wokUtils:FILES:mkdir $theOutDir/$anExecutable
1834       osutils:tk:mkamx $theOutDir/$anExecutable $anExecutable
1835     }
1836   }
1837   osutils:am:adm $theOutDir $theModules
1838   osutils:am:root $path $theSubPath $theModules
1839
1840   puts "The automake files are stored in the $theOutDir directory"
1841 }
1842
1843 proc wokUtils:FILES:rmdir { d } {
1844     global env
1845     global tcl_platform tcl_version  
1846     regsub -all {\.[^.]*} $tcl_version "" major
1847     if { $major == 8 } {
1848         file delete -force $d
1849     } else {
1850         if { "$tcl_platform(platform)" == "unix" } {
1851             catch { exec rm -rf $d}
1852         } else {
1853             
1854         }
1855     }
1856     return 
1857 }
1858
1859 proc wokUtils:FILES:mkdir { d } {
1860     global tcl_version
1861     regsub -all {\.[^.]*} $tcl_version "" major
1862     if { $major == 8 } {
1863         file mkdir $d
1864     } else {
1865         if ![file exists $d] {
1866             if { "[info command mkdir]" == "mkdir" } {
1867                 mkdir -path $d
1868             } else {
1869                 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
1870             }
1871         }
1872     }
1873     if [file exists $d] {
1874         return $d
1875     } else {
1876         return {}
1877     }
1878 }
1879
1880 # "Nice letter: %s" { a b c } => {Nice letter: %a}  {Nice letter: %b} ..
1881 # as a string without backslash
1882 proc wokUtils:EASY:FmtSimple1 { fmt l {backslh 1} } {
1883     foreach e $l {
1884         if { $backslh } {
1885             append str [format $fmt $e] "\n"
1886         } else {
1887             append str [format $fmt $e]
1888         }
1889     }
1890     return $str
1891 }
1892
1893 # edit_last is performed ONCE fmt has been applied.
1894 proc wokUtils:EASY:FmtString2 { fmt l {yes_for_last 0} {edit_last {}} } {
1895     set ldeb [lrange $l 0 [expr [llength $l] -2]]
1896     set last [lrange $l end end]
1897     foreach e $ldeb {
1898         append str [format $fmt $e $e] " \\" "\n"
1899     }
1900
1901     if {$edit_last != {} } {
1902         set slast [$edit_last [format $fmt $last $last]]
1903     } else {
1904         set slast [format $fmt $last $last]
1905     }
1906
1907     if { $yes_for_last } {
1908         append str $slast " \\" "\n" 
1909     } else {
1910         append str $slast "\n"
1911     }
1912
1913     return $str
1914 }
1915
1916 # { a.x b.c c.v } => { a b c}
1917 proc wokUtils:LIST:sanspoint { l } {
1918     set rr {}
1919     foreach x $l {
1920         lappend rr [file root $x]
1921     }
1922     return $rr
1923 }
1924
1925 # remove from listloc OpenCascade units indesirables on Unix
1926 proc osutils:justunix { listloc } {
1927   if { "$::tcl_platform(os)" == "Darwin" } {
1928     set goaway [list Xw WNT]
1929   } else {
1930     set goaway [list WNT]
1931   }
1932   return [osutils:juststation $goaway $listloc]
1933 }
1934
1935 # remove ":" from last item of dependencies list in target VPATH of Makefile.am
1936 proc osutils:am:__VPATH__lastoccur { str } {
1937   if { [regsub {:$} $str "" u] != 0 } {
1938     return $u
1939   }
1940 }
1941
1942 #  ((((((((((((( Formats in Makefile.am )))))))))))))
1943 # Used to replace the string __VPATH__ in Makefile.am
1944 # l is the list of the units in a toolkit.
1945 proc osutils:am:__VPATH__ { l } {
1946   set fmt "@top_srcdir@/src/%s:"
1947   return [wokUtils:EASY:FmtString2 $fmt $l 0 osutils:am:__VPATH__lastoccur]
1948 }
1949
1950 # Used to replace the string __INCLUDES__ in Makefile.am
1951 # l is the list of packages in a toolkit.
1952 proc osutils:am:__INCLUDES__ { l } {
1953   set fmt "-I@top_srcdir@/src/%s"
1954   return [wokUtils:EASY:FmtString2 $fmt $l]
1955 }
1956
1957 # Used to replace the string __LIBADD__ in Makefile.am
1958 # l is the toolkit closure list of a toolkit.
1959 proc osutils:am:__LIBADD__ { theIncToolkits {final 0} } {
1960   global path
1961   global fBranch
1962   set aFatherModules ""
1963   set aCurrentWorkBench [file tail $path]
1964   if { $fBranch != "" } {
1965     set fd [open $fBranch/adm/UDLIST rb]
1966     set fileContent [split [read $fd] "\n"]
1967     close $fd
1968     set ftoolkits [lsearch -all -inline $fileContent "t *"]
1969     foreach ft $ftoolkits {
1970       set aFatherModules "$aFatherModules [string range $ft 2 end]"
1971     }
1972   }
1973   set aLibString ""
1974   foreach aIncToolkit $theIncToolkits {
1975     if { [lsearch [split $aFatherModules " "] $aIncToolkit] != -1} {
1976       append aLibString " \\\n-l$aIncToolkit"
1977     } else {
1978       append aLibString " \\\n../$aIncToolkit/lib$aIncToolkit.la"
1979     }
1980   }
1981   return $aLibString
1982 }
1983
1984 # Used to replace the string __SOURCES__ in Makefile.am
1985 # l is the list of all compilable files in a toolkit.
1986 proc osutils:am:__SOURCES__ { l } {
1987   set fmt "%s"
1988   return [wokUtils:EASY:FmtString1 $fmt $l]
1989 }
1990
1991 proc osutils:am:__CXXFLAG__ { l } {
1992   set fmt "%s"
1993   return [wokUtils:EASY:FmtString1 $fmt [osutils:am:PkCXXOption $l]]
1994 }
1995
1996 proc osutils:am:PkCXXOption { ppk } {
1997   global path
1998   #puts "\t 1 [lindex [wokparam -e  %CMPLRS_CXX_Options [wokcd]] 0]"
1999   set CXXCOMMON [_get_options lin cmplrs_cxx b]
2000   #puts "\t 2 [wokparam -v %CMPLRS_CXX_Options [w_info -f]]"
2001   #puts "\t 3 [wokparam -v %CMPLRS_CXX_Options]"
2002   set FoundFlag "[lindex [osutils:intersect3 [split [_get_options lin cmplrs_cxx f]] [split [_get_options lin cmplrs_cxx b]] ] 2]"
2003   foreach pk $ppk {
2004     #puts $pk
2005         if {![file isdirectory $path/src/$pk]} {
2006           continue
2007         }
2008     set src_files [_get_used_files $pk false]
2009     set only_src_files {}
2010     foreach s $src_files { 
2011       regexp {source ([^\s]+)} $s dummy name
2012       lappend only_src_files $name
2013     }
2014     if {[lsearch $only_src_files ${pk}_CMPLRS.edl] != "-1"} {
2015       set pk_cmplrs_cxx [_get_options lin cmplrs_cxx $pk]
2016       if {$pk_cmplrs_cxx == ""} {
2017             set pk_cmplrs_cxx [_get_options lin cmplrs_cxx b]
2018           }
2019       set CXXStr  $pk_cmplrs_cxx
2020           #puts "\t 4 [wokparam -e %CMPLRS_CXX_Options [woklocate -u $pk]] $pk"
2021       set LastIndex [expr {[string length $CXXCOMMON ] - 1}]
2022       if {[string equal $CXXCOMMON [string range $CXXStr 0 $LastIndex]]} {
2023         set CXXOption " "
2024       } else {
2025         set CXXOption [string range $CXXStr 0 [expr {[string last $CXXCOMMON $CXXStr] - 1}]]
2026       }
2027       if {$CXXOption != " " && $CXXOption != "" && $CXXOption != "  " && $CXXOption != "   "} {
2028         set FoundList [split $CXXOption " "]
2029         foreach elem $FoundList {
2030           if {$elem != ""} {
2031             if {[string first "-I" $elem] == "-1"  } {
2032               if {[string first $elem $FoundFlag] == "-1"} {
2033                 set FoundFlag "$FoundFlag $elem"
2034               }
2035             }
2036           }
2037         }
2038       }
2039     }
2040   }
2041   return $FoundFlag
2042 }
2043
2044 # Create in dir the Makefile.am associated with toolkit tkloc.
2045 # Returns the full path of the created file.
2046 proc osutils:tk:mkam { dir tkloc } {
2047   global path
2048   set pkgs $path/src/${tkloc}/PACKAGES
2049   if { ![file exists $pkgs] } {
2050     puts stderr "osutils:tk:mkam : Error. File PACKAGES not found for toolkit $tkloc."
2051     return {}
2052   }
2053
2054   set tmplat [osutils:readtemplate mam "Makefile.am"]
2055   set lpkgs  [osutils:justunix [wokUtils:FILES:FileToList $pkgs]]
2056   set close  [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
2057   set lsrc   [lsort [osutils:tk:files $tkloc osutils:compilable 1 osutils:justunix]]
2058   set lobj   [wokUtils:LIST:sanspoint $lsrc]
2059
2060   set lcsf   [osutils:tk:csfInExternlib $path/src/${tkloc}/EXTERNLIB]
2061
2062   set final 0
2063   set externinc ""
2064   set externlib ""
2065   if { $lcsf != {} } {
2066     set final 1
2067     set fmtinc "\$(%s_INCLUDES) "
2068     set fmtlib "\$(%s_LIB) "
2069     set externinc [wokUtils:EASY:FmtSimple1 $fmtinc $lcsf 0]
2070     set externlib [wokUtils:EASY:FmtSimple1 $fmtlib $lcsf 0]
2071   }
2072
2073   regsub -all -- {__TKNAM__} $tmplat $tkloc tmplat
2074   set vpath [osutils:am:__VPATH__ $lpkgs]
2075   regsub -all -- {__VPATH__} $tmplat $vpath tmplat
2076   set inclu [osutils:am:__INCLUDES__ $lpkgs]
2077   regsub -all -- {__INCLUDES__} $tmplat $inclu tmplat
2078   if { $close != {} } {
2079     set libadd [osutils:am:__LIBADD__ $close $final]
2080   } else {
2081     set libadd ""
2082   }
2083   regsub -all -- {__LIBADD__} $tmplat $libadd tmplat
2084   set source [osutils:am:__SOURCES__ $lsrc]
2085   regsub -all -- {__SOURCES__} $tmplat $source tmplat
2086   regsub -all -- {__EXTERNINC__} $tmplat $externinc tmplat
2087   set CXXFl [osutils:am:__CXXFLAG__ $lpkgs]
2088   regsub -all -- {__CXXFLAG__} $tmplat $CXXFl tmplat
2089   set CFl [osutils:am:__CFLAG__ $lpkgs]
2090   regsub -all -- {__CFLAG__} $tmplat $CFl tmplat
2091
2092   regsub -all -- {__EXTERNLIB__} $tmplat $externlib tmplat
2093
2094   wokUtils:FILES:StringToFile $tmplat [set fmam [file join $dir Makefile.am]]
2095   return [list $fmam]
2096 }
2097
2098 # Write a string in a file
2099 proc wokUtils:FILES:StringToFile { str path } {
2100     if { [catch { set out [ open $path w ] } errout] == 0 } {
2101         puts -nonewline $out $str
2102         close $out
2103         return 1
2104     } else {
2105         return {}
2106     }
2107 }
2108
2109 # Create in dir the Makefile.am associated with toolkit tkloc.
2110 # Returns the full path of the created file.
2111 proc osutils:tk:mkamx { dir tkloc } {
2112   global path
2113   set src_files [_get_used_files $tkloc false]
2114   set only_src_files {}
2115   foreach s $src_files { 
2116     regexp {source ([^\s]+)} $s dummy name
2117     lappend only_src_files $name
2118   }
2119   if { [lsearch $only_src_files ${tkloc}_WOKSteps.edl] != "-1"} {
2120     set pkgs "$path/src/${tkloc}/EXTERNLIB"
2121     if { $pkgs == {} } {
2122       puts stderr "osutils:tk:mkamx : Error. File EXTERNLIB not found for executable $tkloc."
2123       #return {}
2124     }
2125     set tmplat [osutils:readtemplate mamx "Makefile.am (executable)"]
2126     set close  [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
2127     set lsrc   [lsort [osutils:tk:files $tkloc osutils:compilable 1 osutils:justunix]]
2128     set lobj   [wokUtils:LIST:sanspoint $lsrc]
2129     set CXXList {}
2130     foreach SourceFile $only_src_files {
2131       if {[file extension $SourceFile] == ".cxx"} {
2132         lappend CXXList [file rootname $SourceFile]
2133       }
2134     }
2135     set pkgs [LibToLinkX $tkloc [lindex $CXXList 0]]
2136     set lpkgs  [osutils:justunix [wokUtils:FILES:FileToList $pkgs]]
2137     puts "pkgs $pkgs"
2138     #set lcsf   [osutils:tk:csfInExternlib [woklocate -p ${tkloc}:source:EXTERNLIB [wokcd]]]
2139
2140     set lcsf {}
2141     foreach tk $pkgs {
2142       foreach element [osutils:tk:csfInExternlib "$path/src/${tk}/EXTERNLIB"] {
2143         if {[lsearch $lcsf $element] == "-1"} {
2144           set lcsf [concat $lcsf $element]
2145         }
2146       }
2147     }
2148     set final 0
2149     set externinc ""
2150     set externlib ""
2151     if { $lcsf != {} } {
2152       set final 1
2153       set fmtinc "\$(%s_INCLUDES) "
2154       set fmtlib "\$(%s_LIB) "
2155       set externinc [wokUtils:EASY:FmtSimple1 $fmtinc $lcsf 0]
2156       set externlib [wokUtils:EASY:FmtSimple1 $fmtlib $lcsf 0]
2157     }
2158     regsub -all -- {__XQTNAM__} $tmplat $tkloc tmplat
2159     set tmplat "$tmplat \nlib_LTLIBRARIES="
2160     foreach entity $CXXList {
2161       set tmplat "$tmplat lib${entity}.la"
2162     }
2163     set tmplat "$tmplat\n"
2164     set inclu [osutils:am:__INCLUDES__ $lpkgs]
2165     regsub -all -- {__INCLUDES__} $tmplat $inclu tmplat
2166     if { $pkgs != {} } {
2167       set libadd [osutils:am:__LIBADD__ $pkgs $final]
2168     } else {
2169       set libadd ""
2170     }
2171     regsub -all -- {__LIBADD__} $tmplat $libadd tmplat
2172     set source [osutils:am:__SOURCES__ $CXXList]
2173     regsub -all -- {__SOURCES__} $tmplat $source tmplat
2174     regsub -all -- {__EXTERNINC__} $tmplat $externinc tmplat
2175     foreach entity $CXXList {
2176       set tmplat "$tmplat lib${entity}_la_SOURCES = @top_srcdir@/src/${tkloc}/${entity}.cxx \n"
2177     }
2178     foreach entity $CXXList {
2179       set tmplat "$tmplat lib${entity}_la_LIBADD = $libadd $externlib \n"
2180     }
2181     wokUtils:FILES:StringToFile $tmplat [set fmam [file join $dir Makefile.am]]
2182
2183     unset tmplat
2184
2185     return [list $fmam]
2186
2187   } else {
2188     set pkgs "$path/src/${tkloc}/EXTERNLIB"
2189     if { $pkgs == {} } {
2190       puts stderr "osutils:tk:mkamx : Error. File EXTERNLIB not found for executable $tkloc."
2191       #return {}
2192     }
2193     set tmplat [osutils:readtemplate mamx "Makefile.am (executable)"]
2194     set close  [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
2195     set lsrc   [lsort [osutils:tk:files $tkloc osutils:compilable 1 osutils:justunix]]
2196     set lobj   [wokUtils:LIST:sanspoint $lsrc]
2197     set CXXList {}
2198     foreach SourceFile $only_src_files {
2199       if {[file extension $SourceFile] == ".cxx"} {
2200         lappend CXXList [file rootname $SourceFile]
2201       }
2202     }
2203     set pkgs [LibToLinkX $tkloc [lindex $CXXList 0]]
2204     set lpkgs  [osutils:justunix [wokUtils:FILES:FileToList $pkgs]]
2205     set lcsf   [osutils:tk:csfInExternlib "$path/src/${tkloc}/EXTERNLIB"]
2206
2207     set lcsf {}
2208     foreach tk $pkgs {
2209       foreach element [osutils:tk:csfInExternlib "$path/src/${tk}/EXTERNLIB"] {
2210         if {[lsearch $lcsf $element] == "-1"} {
2211           set lcsf [concat $lcsf $element]
2212         }
2213       }
2214     }
2215     set final 0
2216     set externinc ""
2217     set externlib ""
2218     if { $lcsf != {} } {
2219       set final 1
2220       set fmtinc "\$(%s_INCLUDES) "
2221       set fmtlib "\$(%s_LIB) "
2222       set externinc [wokUtils:EASY:FmtSimple1 $fmtinc $lcsf 0]
2223       set externlib [wokUtils:EASY:FmtSimple1 $fmtlib $lcsf 0]
2224     }
2225     regsub -all -- {__XQTNAM__} $tmplat $tkloc tmplat
2226     set tmplat "$tmplat \nbin_PROGRAMS="
2227     foreach entity $CXXList {
2228       set tmplat "${tmplat} ${entity}"
2229     }
2230
2231     set tmplat "${tmplat}\n"
2232     set inclu [osutils:am:__INCLUDES__ $lpkgs]
2233     regsub -all -- {__INCLUDES__} $tmplat $inclu tmplat
2234     if { $pkgs != {} } {
2235       set libadd [osutils:am:__LIBADD__ $pkgs $final]
2236     } else {
2237       set libadd ""
2238     }
2239     set source [osutils:am:__SOURCES__ $CXXList]
2240     regsub -all -- {__SOURCES__} $tmplat $source tmplat
2241     regsub -all -- {__EXTERNINC__} $tmplat $externinc tmplat
2242     foreach entity $CXXList {
2243       set tmplat "$tmplat ${entity}_SOURCES = @top_srcdir@/src/${tkloc}/${entity}.cxx \n"
2244     }
2245     foreach entity $CXXList {
2246       set tmplat "$tmplat ${entity}_LDADD = $libadd $externlib \n"
2247     }
2248     wokUtils:FILES:StringToFile $tmplat [set fmam [file join $dir Makefile.am]]
2249
2250     return [list $fmam]
2251   }
2252 }
2253
2254 # Create in dir the Makefile.am in $dir directory.
2255 # Returns the full path of the created file.
2256 proc osutils:am:adm { dir {lesmodules {}} } {
2257   set amstring "srcdir = @srcdir@\n\n"
2258   set subdirs "SUBDIRS ="
2259   set vpath "VPATH = @srcdir@ ${dir}: "
2260   set make ""
2261   set phony ".PHONY:"
2262   foreach theModule $lesmodules {
2263     set units [osutils:tk:sort [$theModule:toolkits]]
2264     set units [concat $units [OS:executable $theModule]]
2265     append amstring "${theModule}_PKGS ="
2266     append vpath "\\\n"
2267     foreach unit $units {
2268       append amstring " ${unit}"
2269       append vpath "${dir}/${unit}: "
2270     }
2271     set up ${theModule}
2272     if { [info procs ${theModule}:alias] != "" } {
2273       set up [${theModule}:alias]
2274     }
2275     set up [string toupper ${up}]
2276     append amstring "\n\nif ENABLE_${up}\n"
2277     append amstring "  ${theModule}_DIRS = \$(${theModule}_PKGS)\n"
2278     append amstring "else\n"
2279     append amstring "  ${theModule}_DIRS = \n"
2280     append amstring "endif\n\n"
2281     append subdirs " \$(${theModule}_DIRS)"
2282     append make "${theModule}:\n"
2283     append make "\tfor d in \$(${theModule}_PKGS); do \\\n"
2284     append make "\t\tcd \$\$d; \$(MAKE) \$(AM_MAKEFLAGS) lib\$\$d.la; cd ..; \\\n"
2285     append make "\tdone\n\n"
2286     append phony " ${theModule}"
2287   }
2288   append amstring "$subdirs\n\n"
2289   append amstring "$vpath\n\n"
2290   append amstring $make
2291   append amstring $phony
2292   wokUtils:FILES:StringToFile $amstring [set fmam [file join $dir Makefile.am]]
2293   return [list $fmam]
2294 }
2295
2296 # retourne la liste de dependances de module.
2297 proc OS:lsdep { m } {
2298     set res {}
2299     set l [${m}:depends]
2300     if { $l != {} } {
2301         set res [concat $res $l]
2302         foreach h $l {
2303             set res [concat $res [OS:lsdep ${h}]]
2304         }
2305     }
2306     return $res
2307 }
2308
2309 # Create in dir the Makefile.am and configure.ac in CASROOT directory.
2310 # Returns the full path of the created file.
2311 proc osutils:am:root { dir theSubPath {lesmodules {}} } {
2312   global path
2313   set amstring "srcdir = @srcdir@\n\n"
2314   append amstring "SUBDIRS = ${theSubPath}\n\n"
2315   append amstring "VPATH = @srcdir@ @top_srcdir@/${theSubPath}: @top_srcdir@/${theSubPath}:\n\n"
2316
2317   set phony ".PHONY:"
2318
2319   set acstring [osutils:readtemplate ac "Makefile.am"]
2320   set enablestr ""
2321   set confstr ""
2322   set condstr ""
2323   set repstr ""
2324   set acconfstr ""
2325
2326   set exelocal "install-exec-local:\n"
2327   append exelocal "\t"
2328   append exelocal {$(INSTALL) -d $(prefix)/$(platform)}
2329   append exelocal "\n"
2330   foreach d {bin lib} {
2331     append exelocal "\t"
2332     append exelocal "if \[ -e \$(prefix)/${d} -a ! -e \$(prefix)/\$(platform)/${d} \]; then \\\n"
2333     append exelocal "\t\tcd \$(prefix)/\$(platform) && ln -s ../${d} ${d}; \\\n"
2334     append exelocal "\tfi\n"
2335   }
2336   append exelocal "\t"
2337   append exelocal {buildd=`pwd`; cd $(top_srcdir); sourced=`pwd`; cd $(prefix); installd=`pwd`; cd $$buildd;}
2338   append exelocal " \\\n"
2339   append exelocal "\t"
2340   append exelocal {if [ "$$installd" != "$$sourced" ]; then}
2341   append exelocal " \\\n"
2342   append exelocal "\t\t"
2343   append exelocal {$(INSTALL) -d $(prefix)/src;}
2344   append exelocal " \\\n"
2345   append exelocal "\t\t"
2346   append exelocal {cp -frL $(top_srcdir)/src $(prefix);}
2347   append exelocal " \\\n"
2348   append exelocal "\t\t"
2349   append exelocal {cp -frL $$buildd/config.h $(prefix);}
2350   append exelocal " \\\n"
2351   append exelocal "\t\tfor d in "
2352
2353   foreach theModule $lesmodules {
2354     append amstring "${theModule}_PKGS ="
2355     foreach r [${theModule}:ressources] {
2356       if { "[lindex $r 1]" == "r" } {
2357         append amstring " [lindex $r 2]"
2358       }
2359     }
2360     set up ${theModule}
2361     if { [info procs ${theModule}:alias] != "" } {
2362       set up [${theModule}:alias]
2363     }
2364     set up [string toupper ${up}]
2365     set lower ${theModule}
2366     if { [info procs ${theModule}:alias] != "" } {
2367       set lower [${theModule}:alias]
2368     }
2369     set lower [string tolower ${lower}]
2370
2371     append amstring "\n\nif ENABLE_${up}\n"
2372     append amstring "  ${theModule}_DIRS = \$(${theModule}_PKGS)\n"
2373     append amstring "else\n"
2374     append amstring "  ${theModule}_DIRS = \n"
2375     append amstring "endif\n\n"
2376     append amstring "${theModule}:\n"
2377     append amstring "\tcd \$(top_builddir)/${theSubPath} && \$(MAKE) \$(AM_MAKEFLAGS) ${theModule}\n\n"
2378     append phony " ${theModule}"
2379
2380     append exelocal " \$(${theModule}_DIRS)"
2381
2382     append enablestr "AC_ARG_ENABLE(\[${lower}\],\n"
2383     append enablestr "  \[AS_HELP_STRING(\[--disable-${lower}\],\[Disable ${theModule} components\])\],\n"
2384     append enablestr "  \[ENABLE_${up}=\${enableval}\],\[ENABLE_${up}=yes\])\n"
2385
2386     set deplist [OS:lsdep ${theModule}]
2387     set acdeplist {}
2388     if { [info procs ${theModule}:acdepends] != "" } {
2389       set acdeplist [${theModule}:acdepends]
2390     }
2391
2392     if { [llength $deplist] > 0 || [llength $acdeplist] > 0} {
2393       append confstr "if test \"xyes\" = \"x\$ENABLE_${up}\"; then\n"
2394     } else {
2395       append confstr "if test \"xyes\" != \"x\$ENABLE_${up}\"; then\n"
2396     }
2397     foreach dep $deplist {
2398       set dup ${dep}
2399       if { [info procs ${dep}:alias] != "" } {
2400         set dup [${dep}:alias]
2401       }
2402       set dup [string toupper ${dup}]
2403       append confstr "  if test \"xyes\" = \"x\$ENABLE_${up}\" -a \"xyes\" != \"x\$ENABLE_${dup}\"; then\n"
2404       append confstr "    AC_MSG_NOTICE(\[Disabling ${theModule}: not building ${dep} component\])\n"
2405       append confstr "    DISABLE_${up}_REASON=\"(${dep} component disabled)\"\n"
2406       append confstr "    ENABLE_${up}=no\n"
2407       append confstr "  fi\n"
2408     }
2409     foreach dep $acdeplist {
2410       append confstr "  if test \"xyes\" = \"x\$ENABLE_${up}\" -a \"xyes\" != \"x\$HAVE_${dep}\"; then\n"
2411       append confstr "    AC_MSG_NOTICE(\[Disabling ${theModule}: ${dep} not found\])\n"
2412       append confstr "    DISABLE_${up}_REASON=\"(${dep} not found)\"\n"
2413       append confstr "    ENABLE_${up}=no\n"
2414       append confstr "  fi\n"
2415     }
2416     if { [llength $deplist] > 0 || [llength $acdeplist] > 0 } {
2417       append confstr "else\n"
2418     }
2419     append confstr "  DISABLE_${up}_REASON=\"(Disabled)\"\n"
2420     append confstr "fi\n"
2421
2422     append condstr "AM_CONDITIONAL(\[ENABLE_${up}\], \[test \"xyes\" = \"x\$ENABLE_${up}\"\])\n"
2423     append repstr [format "echo \"%-*s  \$ENABLE_${up} \$DISABLE_${up}_REASON\"" 26 ${theModule}]
2424     append repstr "\n"
2425
2426     set units [$theModule:toolkits]
2427     set units [concat $units [OS:executable $theModule]]
2428     foreach unit $units {
2429       append acconfstr "${theSubPath}/${unit}/Makefile \\\n"
2430     }
2431   }
2432
2433   append exelocal "; do \\\n"
2434   append exelocal "\t\t\t"
2435   append exelocal {$(INSTALL) -d $(prefix)/src/$$d;}
2436   append exelocal " \\\n"
2437   append exelocal "\t\t\t"
2438   append exelocal {cp -frL $(top_srcdir)/src/$$d $(prefix)/src;}
2439   append exelocal " \\\n"
2440   append exelocal "\t\tdone; \\\n"
2441   append exelocal "\tfi\n"
2442   append exelocal "\t"
2443   append exelocal {if [ -e $(prefix)/src/config.h ]; then}
2444   append exelocal " \\\n"
2445   append exelocal "\t\t"
2446   append exelocal {unlink $(prefix)/src/config.h;}
2447   append exelocal " \\\n"
2448   append exelocal "\tfi\n"
2449   append exelocal "\t"
2450   append exelocal {cd $(prefix)/src && ln -s ../config.h config.h}
2451   append exelocal "\n"
2452   append exelocal "\t"
2453   append exelocal {cd $(top_srcdir) && cp *.sh $(prefix)}
2454   append exelocal "\n"
2455   append exelocal "\n"
2456
2457   append amstring $exelocal
2458   append amstring $phony
2459
2460   regsub -all -- {__ENABLEMODULES__} $acstring $enablestr acstring
2461   regsub -all -- {__CONFMODULES__} $acstring $confstr acstring
2462   regsub -all -- {__CONDMODULES__} $acstring $condstr acstring
2463   regsub -all -- {__REPMODULES__} $acstring $repstr acstring
2464   regsub -all -- {__ACCONFMODULES__} $acstring $acconfstr acstring
2465
2466   wokUtils:FILES:StringToFile $amstring [set fmam [file join $dir Makefile.am]]
2467   wokUtils:FILES:StringToFile $acstring [set fmam [file join $dir configure.ac]]
2468   file copy -force -- [file join $path/adm/templates build_configure] [file join $dir build_configure]
2469   file copy -force -- [file join $path/adm/templates acinclude.m4] [file join $dir acinclude.m4]
2470   file copy -force -- [file join $path/adm/templates custom.sh.in] [file join $dir custom.sh.in]
2471   return [list $fmam]
2472 }
2473
2474 proc wokUtils:EASY:FmtString1 { fmt l {yes_for_last 0} {edit_last {}} } {
2475     set ldeb [lrange $l 0 [expr [llength $l] -2]]
2476     set last [lrange $l end end]
2477     foreach e $ldeb {
2478         append str [format $fmt $e] " \\" "\n"
2479     }
2480
2481     if {$edit_last != {} } {
2482         set slast [$edit_last [format $fmt $last]]
2483     } else {
2484         set slast [format $fmt $last]
2485     }
2486
2487     if { $yes_for_last } {
2488         append str $slast " \\" "\n" 
2489     } else {
2490         append str $slast "\n"
2491     }
2492     return $str
2493 }
2494
2495 # Used to replace the string __CFLAG__ in Makefile.am
2496 # l is the list of all compilable files in a toolkit.
2497 proc osutils:am:__CFLAG__ { l } {
2498   set fmt "%s"
2499   return [wokUtils:EASY:FmtString1 $fmt [osutils:am:PkCOption $l]]
2500 }
2501
2502 proc osutils:am:PkCOption { ppk } {
2503   global path
2504   #puts "\t\t $ppk"
2505   #puts "\t 5 [lindex [wokparam -e  %CMPLRS_C_Options [wokcd]] 0]"
2506   set CCOMMON [_get_options lin cmplrs_c b]
2507   #puts "\t 6 [lindex [wokparam -v %CMPLRS_C_Options [w_info -f]] 0]"
2508   set FoundFlag "[lindex [osutils:intersect3 [split [_get_options lin cmplrs_c f]] [split [_get_options lin cmplrs_c b]]] 2]"
2509   foreach pk $ppk {
2510     if {![file isdirectory $path/src/$pk]} {
2511           continue
2512         }
2513         set src_files [_get_used_files $pk false]
2514     set only_src_files {}
2515     foreach s $src_files {
2516       regexp {source ([^\s]+)} $s dummy name
2517       lappend only_src_files $name
2518     }
2519     if {[lsearch $src_files ${pk}_CMPLRS.edl] != "-1"} {
2520           #puts "\t 7 [lindex [wokparam -e %CMPLRS_C_Options [woklocate -u $pk]] 0] $pk"
2521       set aPkList   [split "[_get_options lin cmplrs_c $pk]" " "]
2522       set aCcomList [split "$CCOMMON" " "]
2523
2524       foreach aPkItem $aPkList {
2525         if { [lsearch aCcomList $aPkItem] != -1 } {
2526           if {[string first "-I" $aPkItem] == "-1"  } {
2527             set FoundFlag "$FoundFlag $aPkItem"
2528           }
2529         }
2530       }
2531     }
2532   }
2533   return $FoundFlag
2534 }
2535
2536 proc osutils:tksrcfiles { theUnits  theRelatedPath {theCompatible {}} } {
2537   set aTKSrcFiles [list]
2538
2539   if [array exists written] { unset written }
2540   foreach anUnit $theUnits {
2541     set xlo       $anUnit
2542     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2543
2544     if { $theCompatible != {} } {
2545       set aSrcFiles [osutils:tk:files $xlo $theCompatible 0]
2546     }
2547
2548     foreach aSrcFile [lsort $aSrcFiles] {
2549       if { ![info exists written([file tail $aSrcFile])] } {
2550         set written([file tail $aSrcFile]) 1
2551         lappend aTKSrcFiles "${theRelatedPath}/[wokUtils:FILES:wtail $aSrcFile 3]"
2552       } else {
2553         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2554       }
2555     }
2556   }
2557
2558   return $aTKSrcFiles
2559 }
2560
2561 proc osutils:mm_compilable { } {
2562   return [list .mm]
2563 }
2564
2565 proc osutils:tkdefs { theUnits } {
2566   set aTKDefines [list]
2567
2568   foreach anUnit $theUnits {
2569     lappend aTKDefines "__${anUnit}_DLL"
2570   }
2571
2572   return $aTKDefines
2573 }
2574
2575 proc osutils:fileGroupName { theSrcFile } {
2576   set path [file dirname [file normalize ${theSrcFile}]]
2577   regsub -all [file normalize "${path}/.."] ${path} "" aGroupName
2578
2579   return $aGroupName
2580 }
2581
2582
2583 ####### CODEBLOCK ###################################################################
2584 # Function to generate Code Blocks workspace and project files
2585 proc OS:MKCBP { theOutDir {theModules {}} {theAllSolution ""} } {
2586   puts stderr "Generating project files for Code Blocks"
2587
2588   # Generate projects for toolkits and separate workspace for each module
2589   foreach aModule $theModules {
2590     OS:cworkspace $aModule $aModule $theOutDir
2591     OS:cbp        $aModule          $theOutDir
2592   }
2593
2594   # Generate single workspace "OCCT" containing projects from all modules
2595   if { "$theAllSolution" != "" } {
2596     OS:cworkspace $theAllSolution $theModules $theOutDir
2597   }
2598
2599   puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
2600 }
2601
2602 # Generate Code Blocks projects
2603 proc OS:cbp { theModules theOutDir } {
2604   set aProjectFiles {}
2605   foreach aModule $theModules {
2606     foreach aToolKit [${aModule}:toolkits] {
2607       lappend aProjectFiles [osutils:cbptk $theOutDir $aToolKit ]
2608     }
2609     foreach anExecutable [OS:executable ${aModule}] {
2610       lappend aProjectFiles [osutils:cbpx  $theOutDir $anExecutable]
2611     }
2612   }
2613   return $aProjectFiles
2614 }
2615
2616 # Generate Code::Blocks project file for ToolKit
2617 proc osutils:cbptk { theOutDir theToolKit } {
2618   set aUsedToolKits [list]
2619   set aFrameworks   [list]
2620   set anIncPaths    [list]
2621   set aTKDefines    [list]
2622   set aTKSrcFiles   [list]
2623
2624   osutils:tkinfo "../../.." $theToolKit aUsedToolKits aFrameworks anIncPaths aTKDefines aTKSrcFiles
2625
2626   return [osutils:cbp $theOutDir $theToolKit $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines]
2627 }
2628
2629 # Generates Code Blocks workspace.
2630 proc OS:cworkspace { theSolName theModules theOutDir } {
2631   global path
2632   set aWsFilePath "${theOutDir}/${theSolName}.workspace"
2633   set aFile [open $aWsFilePath "w"]
2634   set isActiveSet 0
2635   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2636   puts $aFile "<CodeBlocks_workspace_file>"
2637   puts $aFile "\t<Workspace title=\"${theSolName}\">"
2638
2639   # collect list of projects to be created
2640   foreach aModule $theModules {
2641     # toolkits
2642     foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
2643       set aDependencies [LibToLink $aToolKit]
2644       if { [llength $aDependencies] == 0 } {
2645         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
2646       } else {
2647         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
2648         foreach aDepTk $aDependencies {
2649           puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2650         }
2651         puts $aFile "\t\t</Project>"
2652       }
2653     }
2654
2655     # executables, assume one project per cxx file...
2656     foreach aUnit [OS:executable ${aModule}] {
2657       set aUnitLoc $aUnit
2658       set src_files [_get_used_files $aUnit false]
2659       set aSrcFiles {}
2660       foreach s $src_files { 
2661         regexp {source ([^\s]+)} $s dummy name
2662         lappend aSrcFiles $name
2663       }
2664       foreach aSrcFile $aSrcFiles {
2665         set aFileExtension [file extension $aSrcFile]
2666         if { $aFileExtension == ".cxx" } {
2667           set aPrjName [file rootname $aSrcFile]
2668           set aDependencies [list]
2669           if {[file isdirectory $path/src/$aUnitLoc]} {
2670             set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
2671           }
2672           set anActiveState ""
2673           if { $isActiveSet == 0 } {
2674             set anActiveState " active=\"1\""
2675             set isActiveSet 1
2676           }
2677           if { [llength $aDependencies] == 0 } {
2678             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
2679           } else {
2680             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
2681             foreach aDepTk $aDependencies {
2682               puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2683             }
2684             puts $aFile "\t\t</Project>"
2685           }
2686         }
2687       }
2688     }
2689   }
2690
2691   puts $aFile "\t</Workspace>"
2692   puts $aFile "</CodeBlocks_workspace_file>"
2693   close $aFile
2694
2695   return $aWsFilePath
2696 }
2697
2698 # Generate Code::Blocks project file for Executable
2699 proc osutils:cbpx { theOutDir theToolKit } {
2700   global path targetStation
2701   set aWokStation "$targetStation"
2702   set aWokArch    "$::env(ARCH)"
2703
2704   set aCbpFiles {}
2705   foreach aSrcFile [osutils:tk:files $theToolKit osutils:compilable 0] {
2706     # collect list of referred libraries to link with
2707     set aUsedToolKits [list]
2708     set aFrameworks   [list]
2709     set anIncPaths    [list]
2710     set aTKDefines    [list]
2711     set aTKSrcFiles   [list]
2712     set aProjName [file rootname [file tail $aSrcFile]]
2713
2714     osutils:usedOsLibs $theToolKit "$aWokStation" aUsedToolKits aFrameworks
2715     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2716     foreach tkx $aDepToolkits {
2717       if {[_get_type $tkx] == "t"} {
2718         lappend aUsedToolKits "${tkx}"
2719       }
2720       if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
2721         lappend aUsedToolKits "${tkx}"
2722       }
2723     }
2724
2725     set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
2726     if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
2727       set isExecutable "false"
2728     } else {
2729       set isExecutable "true"
2730     }
2731
2732     if { ![info exists written([file tail $aSrcFile])] } {
2733       set written([file tail $aSrcFile]) 1
2734       lappend aTKSrcFiles $aSrcFile
2735     } else {
2736       puts "Warning : in cbp there are more than one occurences for [file tail $aSrcFile]"
2737     }
2738
2739     # macros for correct DLL exports
2740     if { "$aWokStation" == "wnt" } {
2741       lappend aTKDefines "__${theToolKit}_DLL"
2742     }
2743
2744     # common include paths
2745     lappend anIncPaths "../../../inc"
2746
2747     # extra macros
2748     lappend aTKDefines "CSFDB"
2749     if { "$aWokStation" == "wnt" } {
2750       lappend aTKDefines "WNT"
2751       lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2752     } else {
2753       if { "$aWokStation" == "lin" } {
2754         lappend aTKDefines "LIN"
2755       }
2756       lappend aTKDefines "OCC_CONVERT_SIGNALS"
2757       #lappend aTKDefines "_GNU_SOURCE=1"
2758     }
2759
2760     lappend aCbpFiles [osutils:cbp $theOutDir $aProjName $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines $isExecutable]
2761   }
2762
2763   return $aCbpFiles
2764 }
2765
2766 proc osutils:optinal_libs { } {
2767   return [list tbb.lib tbbmalloc.lib FreeImage.lib FreeImagePlus.lib gl2ps.lib]
2768 }
2769
2770 # This function intended to generate Code::Blocks project file
2771 # @param theOutDir     - output directory to place project file
2772 # @param theProjName   - project name
2773 # @param theSrcFiles   - list of source files
2774 # @param theLibsList   - dependencies (libraries  list)
2775 # @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2776 # @param theIncPaths   - header search paths
2777 # @param theDefines    - compiler macro definitions
2778 # @param theIsExe      - flag to indicate executable / library target
2779 proc osutils:cbp { theOutDir theProjName theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2780   global targetStation
2781   set aWokStation "$targetStation"
2782   set aWokArch    "$::env(ARCH)"
2783
2784   set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2785   set aFile [open $aCbpFilePath "w"]
2786   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2787   puts $aFile "<CodeBlocks_project_file>"
2788   puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2789   puts $aFile "\t<Project>"
2790   puts $aFile "\t\t<Option title=\"$theProjName\" />"
2791   puts $aFile "\t\t<Option pch_mode=\"2\" />"
2792   if { "$aWokStation" == "wnt" } {
2793     puts $aFile "\t\t<Option compiler=\"msvc8\" />"
2794   } else {
2795     puts $aFile "\t\t<Option compiler=\"gcc\" />"
2796   }
2797   puts $aFile "\t\t<Build>"
2798
2799   # Release target configuration
2800   puts $aFile "\t\t\t<Target title=\"Release\">"
2801   if { "$theIsExe" == "true" } {
2802     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2803     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2804   } else {
2805     if { "$aWokStation" == "wnt" } {
2806       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2807     } else {
2808       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2809     }
2810     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2811   }
2812   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
2813   if { "$aWokStation" == "wnt" } {
2814     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2815   } else {
2816     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2817   }
2818   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2819   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2820
2821   # compiler options per TARGET (including defines)
2822   puts $aFile "\t\t\t\t<Compiler>"
2823   if { "$aWokStation" == "wnt" } {
2824     puts $aFile "\t\t\t\t\t<Add option=\"-MD\" />"
2825     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2826     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2827     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2828     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2829     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2830   } else {
2831     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2832     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2833     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2834     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2835     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2836   }
2837   foreach aMacro $theDefines {
2838     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2839   }
2840   puts $aFile "\t\t\t\t\t<Add option=\"-DNDEBUG\" />"
2841   puts $aFile "\t\t\t\t\t<Add option=\"-DNo_Exception\" />"
2842
2843   puts $aFile "\t\t\t\t</Compiler>"
2844
2845   puts $aFile "\t\t\t\t<Linker>"
2846   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
2847   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2848     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2849   }
2850   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
2851   puts $aFile "\t\t\t\t</Linker>"
2852
2853   puts $aFile "\t\t\t</Target>"
2854
2855   # Debug target configuration
2856   puts $aFile "\t\t\t<Target title=\"Debug\">"
2857   if { "$theIsExe" == "true" } {
2858     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2859     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2860   } else {
2861     if { "$aWokStation" == "wnt" } {
2862       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2863     } else {
2864       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2865     }
2866     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2867   }
2868   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
2869   if { "$aWokStation" == "wnt" } {
2870     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2871   } else {
2872     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2873   }
2874   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2875   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2876
2877   # compiler options per TARGET (including defines)
2878   puts $aFile "\t\t\t\t<Compiler>"
2879   if { "$aWokStation" == "wnt" } {
2880     puts $aFile "\t\t\t\t\t<Add option=\"-MDd\" />"
2881     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2882     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2883     puts $aFile "\t\t\t\t\t<Add option=\"-Od\" />"
2884     puts $aFile "\t\t\t\t\t<Add option=\"-Zi\" />"
2885     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2886     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2887   } else {
2888     puts $aFile "\t\t\t\t\t<Add option=\"-O0\" />"
2889     puts $aFile "\t\t\t\t\t<Add option=\"-g\" />"
2890     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2891     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2892     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2893     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2894   }
2895   foreach aMacro $theDefines {
2896     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2897   }
2898   puts $aFile "\t\t\t\t\t<Add option=\"-D_DEBUG\" />"
2899   puts $aFile "\t\t\t\t\t<Add option=\"-DDEB\" />"
2900   puts $aFile "\t\t\t\t</Compiler>"
2901
2902   puts $aFile "\t\t\t\t<Linker>"
2903   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
2904   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2905     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2906   }
2907   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
2908   puts $aFile "\t\t\t\t</Linker>"
2909
2910   puts $aFile "\t\t\t</Target>"
2911
2912   puts $aFile "\t\t</Build>"
2913
2914   # COMMON compiler options
2915   puts $aFile "\t\t<Compiler>"
2916   puts $aFile "\t\t\t<Add option=\"-Wall\" />"
2917   puts $aFile "\t\t\t<Add option=\"-fexceptions\" />"
2918   puts $aFile "\t\t\t<Add option=\"-fPIC\" />"
2919   puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2920   foreach anIncPath $theIncPaths {
2921     puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2922   }
2923   puts $aFile "\t\t</Compiler>"
2924
2925   # COMMON linker options
2926   puts $aFile "\t\t<Linker>"
2927   foreach aFrameworkName $theFrameworks {
2928     if { "$aFrameworkName" != "" } {
2929       puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2930     }
2931   }
2932   foreach aLibName $theLibsList {
2933     if { "$aLibName" != "" } {
2934       puts $aFile "\t\t\t<Add library=\"$aLibName\" />"
2935     }
2936   }
2937   puts $aFile "\t\t</Linker>"
2938
2939   # list of sources
2940   foreach aSrcFile $theSrcFiles {
2941     if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2942       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2943       puts $aFile "\t\t\t<Option compile=\"1\" />"
2944       puts $aFile "\t\t\t<Option link=\"1\" />"
2945       puts $aFile "\t\t</Unit>"
2946     } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2947       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2948       puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2949       puts $aFile "\t\t</Unit>"
2950     } else {
2951       puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
2952     }
2953   }
2954
2955   puts $aFile "\t</Project>"
2956   puts $aFile "</CodeBlocks_project_file>"
2957   close $aFile
2958
2959   return $aCbpFilePath
2960 }
2961
2962 # Auxiliary function to achieve complete information to build Toolkit
2963 # @param theRelativePath - relative path to CASROOT
2964 # @param theToolKit      - Toolkit name
2965 # @param theUsedLib      - dependencies (libraries  list)
2966 # @param theFrameworks   - dependencies (frameworks list, Mac OS X specific)
2967 # @param theIncPaths     - header search paths
2968 # @param theTKDefines    - compiler macro definitions
2969 # @param theTKSrcFiles   - list of source files
2970 proc osutils:tkinfo { theRelativePath theToolKit theUsedLib theFrameworks theIncPaths theTKDefines theTKSrcFiles } {
2971   global path targetStation
2972   set aWokStation "$targetStation"
2973
2974   # collect list of referred libraries to link with
2975   upvar $theUsedLib    aUsedLibs
2976   upvar $theFrameworks aFrameworks
2977   upvar $theIncPaths   anIncPaths
2978   upvar $theTKDefines  aTKDefines
2979   upvar $theTKSrcFiles aTKSrcFiles
2980
2981   osutils:usedOsLibs $theToolKit "$aWokStation" aUsedLibs aFrameworks
2982   set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2983   foreach tkx $aDepToolkits {
2984     lappend aUsedLibs "${tkx}"
2985   }
2986
2987   lappend anIncPaths "$theRelativePath/inc"
2988   set listloc [osutils:tk:units $theToolKit]
2989
2990   if { [llength $listloc] == 0 } {
2991     set listloc $theToolKit
2992   }
2993
2994   if { "$aWokStation" == "wnt" } {
2995     set resultloc [osutils:justwnt  $listloc]
2996   } else {
2997     set resultloc [osutils:justunix $listloc]
2998   }
2999   if [array exists written] { unset written }
3000   foreach fxlo $resultloc {
3001     set xlo       $fxlo
3002     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
3003     foreach aSrcFile [lsort $aSrcFiles] {
3004       if { ![info exists written([file tail $aSrcFile])] } {
3005         set written([file tail $aSrcFile]) 1
3006         lappend aTKSrcFiles "${theRelativePath}/[wokUtils:FILES:wtail $aSrcFile 3]"
3007       } else {
3008         puts "Warning : more than one occurences for [file tail $aSrcFile]"
3009       }
3010     }
3011
3012     # macros for correct DLL exports
3013     if { "$aWokStation" == "wnt" } {
3014       lappend aTKDefines "__${xlo}_DLL"
3015     }
3016
3017     # common include paths
3018 #    lappend anIncPaths "${theRelativePath}/src/${xlo}"
3019   }
3020
3021   # extra macros
3022   lappend aTKDefines "CSFDB"
3023   if { "$aWokStation" == "wnt" } {
3024     lappend aTKDefines "WNT"
3025     lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
3026   } else {
3027     if { "$aWokStation" == "lin" } {
3028       lappend aTKDefines "LIN"
3029     }
3030     lappend aTKDefines "OCC_CONVERT_SIGNALS"
3031     #lappend aTKDefines "_GNU_SOURCE=1"
3032   }
3033 }
3034
3035 # Define libraries to link using only EXTERNLIB file
3036 proc LibToLinkX {thePackage theDummyName} {
3037   set aToolKits [LibToLink $thePackage]
3038   return $aToolKits
3039 }
3040
3041 # Function to generate Xcode workspace and project files
3042 proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
3043
3044   puts stderr "Generating project files for Xcode"
3045
3046   # Generate projects for toolkits and separate workspace for each module
3047   foreach aModule $theModules {
3048     OS:xcworkspace $aModule $aModule $theOutDir
3049     OS:xcodeproj   $aModule          $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
3050   }
3051
3052   # Generate single workspace "OCCT" containing projects from all modules
3053   if { "$theAllSolution" != "" } {
3054     OS:xcworkspace $theAllSolution $theModules $theOutDir
3055   }
3056 }
3057
3058 # Generates toolkits sections for Xcode workspace file.
3059 proc OS:xcworkspace:toolkits { theModule } {
3060   set aBuff ""
3061
3062   # Adding toolkits for module in workspace.
3063   foreach aToolKit [osutils:tk:sort [${theModule}:toolkits]] {
3064     append aBuff "         <FileRef\n"
3065     append aBuff "            location = \"group:${aToolKit}.xcodeproj\">\n"
3066     append aBuff "         </FileRef>\n"
3067   }
3068
3069   # Adding executables for module, assume one project per cxx file...
3070   foreach aUnit [OS:executable ${theModule}] {
3071     set aUnitLoc $aUnit
3072     set src_files [_get_used_files $aUnit false]
3073     set aSrcFiles {}
3074     foreach s $src_files {
3075       regexp {source ([^\s]+)} $s dummy name
3076       lappend aSrcFiles $name
3077     }
3078     foreach aSrcFile $aSrcFiles {
3079       set aFileExtension [file extension $aSrcFile]
3080       if { $aFileExtension == ".cxx" } {
3081         set aPrjName [file rootname $aSrcFile]
3082         append aBuff "         <FileRef\n"
3083         append aBuff "            location = \"group:${aPrjName}.xcodeproj\">\n"
3084         append aBuff "         </FileRef>\n"
3085       }
3086     }
3087   }
3088
3089   # Removing unnecessary newline character from the end.
3090   set aBuff [string replace $aBuff end end]
3091   return $aBuff
3092 }
3093
3094 # Generates workspace files for Xcode.
3095 proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
3096   # Creating workspace directory for Xcode.
3097   set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
3098   wokUtils:FILES:mkdir $aWorkspaceDir
3099   if { ! [file exists $aWorkspaceDir] } {
3100     puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
3101     return
3102   }
3103
3104   # Creating workspace file.
3105   set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
3106   set aFile [open $aWsFilePath "w"]
3107
3108   # Adding header and section for main Group.
3109   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
3110   puts $aFile "<Workspace"
3111   puts $aFile "   version = \"1.0\">"
3112   puts $aFile "   <Group"
3113   puts $aFile "      location = \"container:\""
3114   puts $aFile "      name = \"${theWorkspaceName}\">"
3115
3116   # Adding modules.
3117   if { [llength "$theModules"] > 1 } {
3118     foreach aModule $theModules {
3119       puts $aFile "      <Group"
3120       puts $aFile "         location = \"container:\""
3121       puts $aFile "         name = \"${aModule}\">"
3122       puts $aFile [OS:xcworkspace:toolkits $aModule]
3123       puts $aFile "      </Group>"
3124     }
3125   } else {
3126     puts $aFile [OS:xcworkspace:toolkits $theModules]
3127   }
3128
3129   # Adding footer.
3130   puts $aFile "   </Group>"
3131   puts $aFile "</Workspace>"
3132   close $aFile
3133 }
3134
3135 # Generates Xcode project files.
3136 proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
3137   upvar $theGuidsMap aGuidsMap
3138
3139   set isStatic 0
3140   if { "$theLibType" == "static" } {
3141     set isStatic 1
3142   } elseif { "$thePlatform" == "ios" } {
3143     set isStatic 1
3144   }
3145
3146   set aProjectFiles {}
3147   foreach aModule $theModules {
3148     foreach aToolKit [${aModule}:toolkits] {
3149       lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit     aGuidsMap $isStatic $thePlatform "dylib"]
3150     }
3151     foreach anExecutable [OS:executable ${aModule}] {
3152       lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
3153     }
3154   }
3155   return $aProjectFiles
3156 }
3157
3158 # Generates dependencies section for Xcode project files.
3159 proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids theIsStatic} {
3160   global path
3161   upvar $theGuidsMap         aGuidsMap
3162   upvar $theFileRefSection   aFileRefSection
3163   upvar $theDepsGuids        aDepsGuids
3164   upvar $theDepsRefGuids     aDepsRefGuids
3165
3166   set aBuildFileSection ""
3167   set aUsedToolKits     [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
3168   set aDepToolkits      [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]] $theToolKit]
3169
3170   if { "$theTargetType" == "executable" } {
3171     set aFile [osutils:tk:files $theToolKit osutils:compilable 0]
3172     set aProjName [file rootname [file tail $aFile]]
3173     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
3174   }
3175
3176   set aLibExt "dylib"
3177   if { $theIsStatic == 1 } {
3178     set aLibExt "a"
3179     if { "$theTargetType" != "executable" } {
3180       return $aBuildFileSection
3181     }
3182   }
3183
3184   osutils:usedOsLibs $theToolKit "mac" aLibs aFrameworks
3185   set aUsedToolKits [concat $aUsedToolKits $aLibs]
3186   set aUsedToolKits [concat $aUsedToolKits $aFrameworks]
3187   foreach tkx $aUsedToolKits {
3188     set aDepLib    "${tkx}_Dep"
3189     set aDepLibRef "${tkx}_DepRef"
3190
3191     if { ! [info exists aGuidsMap($aDepLib)] } {
3192       set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
3193     }
3194     if { ! [info exists aGuidsMap($aDepLibRef)] } {
3195       set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
3196     }
3197
3198     append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
3199     if {[lsearch -nocase $aFrameworks $tkx] == -1} {
3200       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
3201     } else {
3202       append aFileRefSection   "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
3203     }
3204     append aDepsGuids        "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
3205     append aDepsRefGuids     "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
3206   }
3207
3208   return $aBuildFileSection
3209 }
3210
3211 # Generates PBXBuildFile and PBXGroup sections for project file.
3212 proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
3213   upvar $theSrcFileRefSection aSrcFileRefSection
3214   upvar $theGroupSection      aGroupSection
3215   upvar $thePackageGuids      aPackagesGuids
3216   upvar $theSrcFileGuids      aSrcFileGuids
3217   upvar $theGuidsMap          aGuidsMap
3218   upvar $theIncPaths          anIncPaths
3219
3220   set listloc [osutils:tk:units $theToolKit]
3221   set resultloc [osutils:justunix $listloc]
3222   set aBuildFileSection ""
3223   set aPackages [lsort -nocase $resultloc]
3224   if { "$theTargetType" == "executable" } {
3225     set aPackages [list "$theToolKit"]
3226   }
3227
3228   # Generating PBXBuildFile, PBXGroup sections and groups for each package.
3229   foreach fxlo $aPackages {
3230     set xlo       $fxlo
3231     set aPackage "${xlo}_Package"
3232     set aSrcFileRefGuids ""
3233     if { ! [info exists aGuidsMap($aPackage)] } {
3234       set aGuidsMap($aPackage) [OS:genGUID "xcd"]
3235     }
3236
3237     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
3238     foreach aSrcFile [lsort $aSrcFiles] {
3239       set aFileExt "sourcecode.cpp.cpp"
3240
3241       if { [file extension $aSrcFile] == ".c" } {
3242         set aFileExt "sourcecode.c.c"
3243       } elseif { [file extension $aSrcFile] == ".mm" } {
3244         set aFileExt "sourcecode.cpp.objcpp"
3245       }
3246
3247       if { ! [info exists aGuidsMap($aSrcFile)] } {
3248         set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
3249       }
3250       set aSrcFileRef "${aSrcFile}_Ref"
3251       if { ! [info exists aGuidsMap($aSrcFileRef)] } {
3252         set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
3253       }
3254       if { ! [info exists written([file tail $aSrcFile])] } {
3255         set written([file tail $aSrcFile]) 1
3256         append aBuildFileSection  "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
3257         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"
3258         append aSrcFileGuids      "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
3259         append aSrcFileRefGuids   "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
3260       } else {
3261         puts "Warning : more than one occurences for [file tail $aSrcFile]"
3262       }
3263     }
3264
3265     append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
3266     append aGroupSection "\t\t\tisa = PBXGroup;\n"
3267     append aGroupSection "\t\t\tchildren = (\n"
3268     append aGroupSection $aSrcFileRefGuids
3269     append aGroupSection "\t\t\t);\n"
3270     append aGroupSection "\t\t\tname = $xlo;\n"
3271     append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
3272     append aGroupSection "\t\t\};\n"
3273
3274     # Storing packages IDs for adding them later as a child of toolkit
3275     append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
3276   }
3277
3278   # Removing unnecessary newline character from the end.
3279   set aPackagesGuids [string replace $aPackagesGuids end end]
3280
3281   return $aBuildFileSection
3282 }
3283
3284 # Creates folders structure and all necessary files for Xcode project.
3285 proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
3286   set aPBXBuildPhase "Headers"
3287   set aRunOnlyForDeployment "0"
3288   set aProductType "library.dynamic"
3289   set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
3290   set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
3291   set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
3292   set aTKDefines [list "CSFDB" "OCC_CONVERT_SIGNALS"]
3293
3294   if { "$theTargetType" == "executable" } {
3295     set aPBXBuildPhase "CopyFiles"
3296     set aRunOnlyForDeployment "1"
3297     set aProductType "tool"
3298     set anExecExtension ""
3299     set anExecPrefix ""
3300     set aWrapperExtension ""
3301   } elseif { $theIsStatic == 1 } {
3302     set aProductType "library.static"
3303     set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
3304     set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
3305   }
3306
3307   set aUsername [exec whoami]
3308
3309   # Creation of folders for Xcode projectP.
3310   set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
3311   wokUtils:FILES:mkdir $aToolkitDir
3312   if { ! [file exists $aToolkitDir] } {
3313     puts stderr "Error: Could not create project directory \"$aToolkitDir\""
3314     return
3315   }
3316
3317   set aUserDataDir "${aToolkitDir}/xcuserdata"
3318   wokUtils:FILES:mkdir $aUserDataDir
3319   if { ! [file exists $aUserDataDir] } {
3320     puts stderr "Error: Could not create xcuserdata directorty in \"$aToolkitDir\""
3321     return
3322   }
3323
3324   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3325   wokUtils:FILES:mkdir $aUserDataDir
3326   if { ! [file exists $aUserDataDir] } {
3327     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$aToolkitDir\"/xcuserdata"
3328     return
3329   }
3330
3331   set aSchemesDir "${aUserDataDir}/xcschemes"
3332   wokUtils:FILES:mkdir $aSchemesDir
3333   if { ! [file exists $aSchemesDir] } {
3334     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3335     return
3336   }
3337   # End of folders creation.
3338
3339   # Generating GUID for tookit.
3340   upvar $theGuidsMap aGuidsMap
3341   if { ! [info exists aGuidsMap($theToolKit)] } {
3342     set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
3343   }
3344
3345   # Creating xcscheme file for toolkit from template.
3346   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
3347   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
3348   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
3349   set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme"  "w"]
3350   puts $aXcschemeFile $aXcschemeTmpl
3351   close $aXcschemeFile
3352
3353   # Creating xcschememanagement.plist file for toolkit from template.
3354   set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
3355   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
3356   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
3357   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
3358   puts $aPlistFile $aPlistTmpl
3359   close $aPlistFile
3360
3361   # Creating project.pbxproj file for toolkit.
3362   set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
3363   puts $aPbxprojFile "// !\$*UTF8*\$!"
3364   puts $aPbxprojFile "\{"
3365   puts $aPbxprojFile "\tarchiveVersion = 1;"
3366   puts $aPbxprojFile "\tclasses = \{"
3367   puts $aPbxprojFile "\t\};"
3368   puts $aPbxprojFile "\tobjectVersion = 46;"
3369   puts $aPbxprojFile "\tobjects = \{\n"
3370
3371   # Begin PBXBuildFile section
3372   set aPackagesGuids ""
3373   set aGroupSection ""
3374   set aSrcFileRefSection ""
3375   set aSrcFileGuids ""
3376   set aDepsFileRefSection ""
3377   set aDepsGuids ""
3378   set aDepsRefGuids ""
3379   set anIncPaths [list "../../../inc"]
3380   set anLibPaths ""
3381
3382   if { [info exists ::env(CSF_OPT_INC)] } {
3383     set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
3384     foreach anIncCfgPath $anIncCfg {
3385       lappend anIncPaths $anIncCfgPath
3386     }
3387   }
3388   if { [info exists ::env(CSF_OPT_LIB64)] } {
3389     set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
3390     foreach anLibCfgPath $anLibCfg {
3391       lappend anLibPaths $anLibCfgPath
3392     }
3393   }
3394
3395   puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
3396   puts $aPbxprojFile [osutils:xcdtk:deps    $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $theIsStatic]
3397   # End PBXBuildFile section
3398
3399   # Begin PBXFileReference section
3400   set aToolkitLib "lib${theToolKit}.dylib"
3401   set aPath "$aToolkitLib"
3402   if { "$theTargetType" == "executable" } {
3403     set aPath "$theToolKit"
3404   } elseif { $theIsStatic == 1 } {
3405     set aToolkitLib "lib${theToolKit}.a"
3406   }
3407
3408   if { ! [info exists aGuidsMap($aToolkitLib)] } {
3409     set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
3410   }
3411
3412   puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
3413   puts $aPbxprojFile $aSrcFileRefSection
3414   puts $aPbxprojFile $aDepsFileRefSection
3415   # End PBXFileReference section
3416
3417
3418   # Begin PBXFrameworksBuildPhase section
3419   set aTkFrameworks "${theToolKit}_Frameworks"
3420   if { ! [info exists aGuidsMap($aTkFrameworks)] } {
3421     set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
3422   }
3423
3424   puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
3425   puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
3426   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3427   puts $aPbxprojFile "\t\t\tfiles = ("
3428   puts $aPbxprojFile $aDepsGuids
3429   puts $aPbxprojFile "\t\t\t);"
3430   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3431   puts $aPbxprojFile "\t\t\};\n"
3432   # End PBXFrameworksBuildPhase section
3433
3434   # Begin PBXGroup section
3435   set aTkPBXGroup "${theToolKit}_PBXGroup"
3436   if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
3437     set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
3438   }
3439
3440   set aTkSrcGroup "${theToolKit}_SrcGroup"
3441   if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
3442     set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
3443   }
3444
3445   puts $aPbxprojFile $aGroupSection
3446   puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
3447   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
3448   puts $aPbxprojFile "\t\t\tchildren = ("
3449   puts $aPbxprojFile $aDepsRefGuids
3450   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
3451   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
3452   puts $aPbxprojFile "\t\t\t);"
3453   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
3454   puts $aPbxprojFile "\t\t\};"
3455   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
3456   puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
3457   puts $aPbxprojFile "\t\t\tchildren = ("
3458   puts $aPbxprojFile $aPackagesGuids
3459   puts $aPbxprojFile "\t\t\t);"
3460   puts $aPbxprojFile "\t\t\tname = \"Source files\";"
3461   puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
3462   puts $aPbxprojFile "\t\t\};\n"
3463   # End PBXGroup section
3464
3465   # Begin PBXHeadersBuildPhase section
3466   set aTkHeaders "${theToolKit}_Headers"
3467   if { ! [info exists aGuidsMap($aTkHeaders)] } {
3468     set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
3469   }
3470
3471   puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
3472   puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
3473   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3474   puts $aPbxprojFile "\t\t\tfiles = ("
3475   puts $aPbxprojFile "\t\t\t);"
3476   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
3477   puts $aPbxprojFile "\t\t\};\n"
3478   # End PBXHeadersBuildPhase section
3479
3480   # Begin PBXNativeTarget section
3481   set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
3482   if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
3483     set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
3484   }
3485
3486   set aTkSources "${theToolKit}_Sources"
3487   if { ! [info exists aGuidsMap($aTkSources)] } {
3488     set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
3489   }
3490
3491   puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
3492   puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
3493   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
3494   puts $aPbxprojFile "\t\t\tbuildPhases = ("
3495   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
3496   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
3497   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
3498   puts $aPbxprojFile "\t\t\t);"
3499   puts $aPbxprojFile "\t\t\tbuildRules = ("
3500   puts $aPbxprojFile "\t\t\t);"
3501   puts $aPbxprojFile "\t\t\tdependencies = ("
3502   puts $aPbxprojFile "\t\t\t);"
3503   puts $aPbxprojFile "\t\t\tname = $theToolKit;"
3504   puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
3505   puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
3506   puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
3507   puts $aPbxprojFile "\t\t\};\n"
3508   # End PBXNativeTarget section
3509
3510   # Begin PBXProject section
3511   set aTkProjectObj "${theToolKit}_ProjectObj"
3512   if { ! [info exists aGuidsMap($aTkProjectObj)] } {
3513     set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
3514   }
3515
3516   set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
3517   if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
3518     set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
3519   }
3520
3521   puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
3522   puts $aPbxprojFile "\t\t\tisa = PBXProject;"
3523   puts $aPbxprojFile "\t\t\tattributes = \{"
3524   puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
3525   puts $aPbxprojFile "\t\t\t\};"
3526   puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
3527   puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
3528   puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
3529   puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
3530   puts $aPbxprojFile "\t\t\tknownRegions = ("
3531   puts $aPbxprojFile "\t\t\t\ten,"
3532   puts $aPbxprojFile "\t\t\t);"
3533   puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
3534   puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
3535   puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
3536   puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
3537   puts $aPbxprojFile "\t\t\ttargets = ("
3538   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
3539   puts $aPbxprojFile "\t\t\t);"
3540   puts $aPbxprojFile "\t\t\};\n"
3541   # End PBXProject section
3542
3543   # Begin PBXSourcesBuildPhase section
3544   puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
3545   puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
3546   puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3547   puts $aPbxprojFile "\t\t\tfiles = ("
3548   puts $aPbxprojFile $aSrcFileGuids
3549   puts $aPbxprojFile "\t\t\t);"
3550   puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3551   puts $aPbxprojFile "\t\t\};\n"
3552   # End PBXSourcesBuildPhase section
3553
3554   # Begin XCBuildConfiguration section
3555   set aTkDebugProject "${theToolKit}_DebugProject"
3556   if { ! [info exists aGuidsMap($aTkDebugProject)] } {
3557     set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
3558   }
3559
3560   set aTkReleaseProject "${theToolKit}_ReleaseProject"
3561   if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
3562     set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
3563   }
3564
3565   set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
3566   if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
3567     set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
3568   }
3569
3570   set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
3571   if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
3572     set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
3573   }
3574
3575   # Debug target
3576   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
3577   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3578   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3579
3580   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
3581   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3582   if { "$thePlatform" == "ios" } {
3583     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3584     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
3585     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3586     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3587     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3588   }
3589   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
3590   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
3591   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
3592   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3593   puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
3594   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3595   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
3596   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3597   puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
3598   puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
3599   puts $aPbxprojFile "\t\t\t\t);"
3600   puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
3601   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3602   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3603   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3604   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3605   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3606   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
3607   if { "$thePlatform" == "ios" } {
3608     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
3609     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3610   } else {
3611     puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
3612   }
3613   puts $aPbxprojFile "\t\t\t\};"
3614
3615   puts $aPbxprojFile "\t\t\tname = Debug;"
3616   puts $aPbxprojFile "\t\t\};"
3617
3618   # Release target
3619   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
3620   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3621   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3622
3623   puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
3624   puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3625   if { "$thePlatform" == "ios" } {
3626     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3627     puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
3628     puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3629     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3630     puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3631   }
3632   puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
3633   puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
3634   puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
3635   puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3636   puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3637   puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
3638   puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
3639   puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3640   puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3641   puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3642   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3643   puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3644   puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
3645   if { "$thePlatform" == "ios" } {
3646     puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
3647     puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3648   }
3649   puts $aPbxprojFile "\t\t\t\};"
3650   puts $aPbxprojFile "\t\t\tname = Release;"
3651   puts $aPbxprojFile "\t\t\};"
3652   puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
3653   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3654   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3655   puts $aPbxprojFile "${anExecExtension}"
3656   puts $aPbxprojFile "${anExecPrefix}"
3657   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3658   foreach aMacro $aTKDefines {
3659     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3660   }
3661   puts $aPbxprojFile "\t\t\t\t);"
3662
3663   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3664   foreach anIncPath $anIncPaths {
3665     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3666   }
3667   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3668   puts $aPbxprojFile "\t\t\t\t);"
3669
3670   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3671   foreach anLibPath $anLibPaths {
3672     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3673   }
3674   puts $aPbxprojFile "\t\t\t\t);"
3675
3676   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3677   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3678   puts $aPbxprojFile "\t\t\t\t);"
3679   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3680   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3681   puts $aPbxprojFile "\t\t\t\t);"
3682   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3683   set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
3684   foreach anIncPath $anIncPaths {
3685     append anUserHeaderSearchPath " ${anIncPath}"
3686   }
3687   append anUserHeaderSearchPath "\";"
3688   puts $aPbxprojFile $anUserHeaderSearchPath
3689   puts $aPbxprojFile "${aWrapperExtension}"
3690   puts $aPbxprojFile "\t\t\t\};"
3691   puts $aPbxprojFile "\t\t\tname = Debug;"
3692   puts $aPbxprojFile "\t\t\};"
3693   puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
3694   puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3695   puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3696   puts $aPbxprojFile "${anExecExtension}"
3697   puts $aPbxprojFile "${anExecPrefix}"
3698   puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3699   foreach aMacro $aTKDefines {
3700     puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3701   }
3702   puts $aPbxprojFile "\t\t\t\t);"
3703   puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3704   foreach anIncPath $anIncPaths {
3705     puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3706   }
3707   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3708   puts $aPbxprojFile "\t\t\t\t);"
3709
3710   puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3711   foreach anLibPath $anLibPaths {
3712     puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3713   }
3714   puts $aPbxprojFile "\t\t\t\t);"
3715
3716   puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3717   puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3718   puts $aPbxprojFile "\t\t\t\t);"
3719   puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3720   puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3721   puts $aPbxprojFile "\t\t\t\t);"
3722   puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3723   puts $aPbxprojFile $anUserHeaderSearchPath
3724   puts $aPbxprojFile "${aWrapperExtension}"
3725   puts $aPbxprojFile "\t\t\t\};"
3726   puts $aPbxprojFile "\t\t\tname = Release;"
3727   puts $aPbxprojFile "\t\t\};\n"
3728   # End XCBuildConfiguration section
3729
3730   # Begin XCConfigurationList section
3731   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
3732   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3733   puts $aPbxprojFile "\t\tbuildConfigurations = ("
3734   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
3735   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
3736   puts $aPbxprojFile "\t\t\t);"
3737   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3738   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3739   puts $aPbxprojFile "\t\t\};"
3740   puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
3741   puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3742   puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
3743   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
3744   puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
3745   puts $aPbxprojFile "\t\t\t);"
3746   puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3747   puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3748   puts $aPbxprojFile "\t\t\};\n"
3749   # End XCConfigurationList section
3750
3751   puts $aPbxprojFile "\t\};"
3752   puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3753   puts $aPbxprojFile "\}"
3754
3755   close $aPbxprojFile
3756 }
3757
3758 proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3759   set aUsername [exec whoami]
3760
3761   # Creating folders for Xcode project file.
3762   set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3763   wokUtils:FILES:mkdir $anExecutableDir
3764   if { ! [file exists $anExecutableDir] } {
3765     puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3766     return
3767   }
3768
3769   set aUserDataDir "${anExecutableDir}/xcuserdata"
3770   wokUtils:FILES:mkdir $aUserDataDir
3771   if { ! [file exists $aUserDataDir] } {
3772     puts stderr "Error: Could not create xcuserdata directorty in \"$anExecutableDir\""
3773     return
3774   }
3775
3776   set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3777   wokUtils:FILES:mkdir $aUserDataDir
3778   if { ! [file exists $aUserDataDir] } {
3779     puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$anExecutableDir\"/xcuserdata"
3780     return
3781   }
3782
3783   set aSchemesDir "${aUserDataDir}/xcschemes"
3784   wokUtils:FILES:mkdir $aSchemesDir
3785   if { ! [file exists $aSchemesDir] } {
3786     puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3787     return
3788   }
3789   # End folders creation.
3790
3791   # Generating GUID for tookit.
3792   upvar $theGuidsMap aGuidsMap
3793   if { ! [info exists aGuidsMap($theExecutable)] } {
3794     set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3795   }
3796
3797   # Creating xcscheme file for toolkit from template.
3798   set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3799   regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3800   regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3801   set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme"  "w"]
3802   puts $aXcschemeFile $aXcschemeTmpl
3803   close $aXcschemeFile
3804
3805   # Creating xcschememanagement.plist file for toolkit from template.
3806   set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3807   regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3808   regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3809   set aPlistFile [open "$aSchemesDir/xcschememanagement.plist"  "w"]
3810   puts $aPlistFile $aPlistTmpl
3811   close $aPlistFile
3812 }