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