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