0024786: Move functionality of WOK command wgenproj to OCCT tool genproj
[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   } else {
1070
1071     #-- Tcl/Tk configuration
1072     set aCsfMap(CSF_TclLibs)    "tcl8.6"
1073     set aCsfMap(CSF_TclTkLibs)  "X11 tk8.6"
1074
1075     if { "$theOS" == "lin" } {
1076       set aCsfMap(CSF_ThreadLibs) "pthread rt"
1077       set aCsfMap(CSF_OpenGlLibs) "GLU GL"
1078
1079     } elseif { "$theOS" == "mac" } {
1080       set aCsfMap(CSF_objc)     "objc"
1081
1082       # frameworks
1083       set aCsfMap(CSF_Appkit)     "Appkit"
1084       set aCsfMap(CSF_IOKit)      "IOKit"
1085       set aCsfMap(CSF_OpenGlLibs) "OpenGL"
1086       set aCsfMap(CSF_TclLibs)    "Tcl"
1087       set aCsfMap(CSF_TclTkLibs)  "Tk"
1088     }
1089
1090     set aCsfMap(CSF_XwLibs)     "X11 Xext Xmu Xi"
1091     set aCsfMap(CSF_MotifLibs)  "X11"
1092
1093     # variable is required for support for OCCT version that use fgtl
1094     #-- FTGL (font renderer for OpenGL)
1095     set aCsfMap(CSF_FTGL)       "ftgl"
1096
1097     #-- FreeType
1098     set aCsfMap(CSF_FREETYPE)   "freetype"
1099
1100     #-- optional 3rd-parties
1101     #-- TBB
1102     set aCsfMap(CSF_TBB)            "tbb tbbmalloc"
1103
1104     #-- FreeImage
1105     set aCsfMap(CSF_FreeImagePlus)  "freeimage"
1106
1107     #-- GL2PS
1108     set aCsfMap(CSF_GL2PS)          "gl2ps"
1109
1110     #-- VTK
1111     set aCsfMap(CSF_VTK)         "vtkCommonCore-6.1 vtkCommonDataModel-6.1 vtkCommonExecutionModel-6.1 vtkCommonMath-6.1 vtkCommonTransforms-6.1 vtkRenderingCore-6.1"
1112   }
1113 }
1114
1115 proc osutils:usedOsLibs { theToolKit theOS } {
1116   global path
1117   set aUsedLibs [list]
1118
1119   osutils:csfList $theOS anOsCsfList
1120
1121   foreach element [osutils:tk:hascsf "$path/src/${theToolKit}/EXTERNLIB"] {
1122     # test if variable is not setted - continue
1123     if ![info exists anOsCsfList($element)] {
1124       continue
1125     }
1126
1127     foreach aLib [split "$anOsCsfList($element)"] {
1128       if { [lsearch $aUsedLibs $aLib] == "-1"} {
1129         lappend aUsedLibs $aLib
1130       }
1131     }
1132   }
1133
1134   return $aUsedLibs
1135 }
1136
1137 # Returns liste of UD in a toolkit. tkloc is a full path wok.
1138 proc osutils:tk:units { tkloc } {
1139   global path
1140   set l {}
1141   set PACKAGES "$path/src/$tkloc/PACKAGES"
1142   foreach u [wokUtils:FILES:FileToList $PACKAGES] {
1143     if {[file isdirectory "$path/src/$u"]} {
1144       lappend l $u
1145     }
1146   }
1147   if { $l == {} } {
1148     ;#puts stderr "Warning. No devunit included in $tkloc"
1149   }
1150   return $l
1151 }
1152
1153 proc osutils:justwnt { listloc } {
1154   # ImageUtility is required for support for old (<6.5.4) versions of OCCT
1155   set goaway [list Xdps Xw  ImageUtility WOKUnix]
1156   return [osutils:juststation $goaway $listloc]
1157 }
1158
1159 # remove from listloc OpenCascade units indesirables on NT
1160 proc osutils:juststation {goaway listloc} {
1161   global path
1162   set lret {}
1163   foreach u $listloc {
1164     if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1165      || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1166       lappend lret $u
1167     }
1168   }
1169   return $lret
1170 }
1171
1172 # intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1173 # The first list is everything in the first list that wasn't in the second,
1174 # the second list contains the intersection of the two lists, the third list contains everything
1175 # in the second list that wasn't in the first.
1176 proc osutils:intersect3 {list1 list2} {
1177   set la1(0) {} ; unset la1(0)
1178   set lai(0) {} ; unset lai(0)
1179   set la2(0) {} ; unset la2(0)
1180   foreach v $list1 {
1181     set la1($v) {}
1182   }
1183   foreach v $list2 {
1184     set la2($v) {}
1185   }
1186   foreach elem [concat $list1 $list2] {
1187     if {[info exists la1($elem)] && [info exists la2($elem)]} {
1188       unset la1($elem)
1189       unset la2($elem)
1190       set lai($elem) {}
1191     }
1192   }
1193   list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1194 }
1195
1196 # Prepare relative path
1197 proc relativePath {thePathFrom thePathTo} {
1198   if { [file isdirectory "$thePathFrom"] == 0 } {
1199     return ""
1200   }
1201
1202   set aPathFrom [file normalize "$thePathFrom"]
1203   set aPathTo   [file normalize "$thePathTo"]
1204
1205   set aCutedPathFrom "${aPathFrom}/dummy"
1206   set aRelatedDeepPath ""
1207
1208   while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1209     set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1210     # does aPathTo contain aCutedPathFrom?
1211     regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1212     if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1213       if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1214         set aPathTo ".${aPathTo}"
1215       } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1216         set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1217       }
1218       regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1219       regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1220       return $aPathToAfterCut
1221     }
1222     set aRelatedDeepPath "$aRelatedDeepPath../"
1223
1224   }
1225
1226   return $thePathTo
1227 }
1228
1229 proc wokUtils:EASY:bs1 { s } {
1230     regsub -all {/} $s {\\} r
1231     return $r
1232 }
1233
1234 # Returs for a full path the liste of n last directory part
1235 # n = 1 => tail
1236 # n = 2 => dir/file.c
1237 # n = 3 => sdir/dir/file.c
1238 # etc..
1239 proc wokUtils:FILES:wtail { f n } {
1240     set ll [expr [llength [set lif [file split $f]]] -$n]
1241     return [join [lrange $lif $ll end] /]
1242 }
1243
1244 # Generate entry for one source file in Visual Studio 10 project file
1245 proc osutils:vcxproj:file { vcversion file params } {
1246   append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1247   if { $params != "" } {
1248     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1249   }
1250
1251   if { $params != "" } {
1252     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1253   }
1254
1255   if { $params != "" } {
1256     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1257   }
1258
1259   if { $params != "" } {
1260     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
1261   }
1262
1263   append text "    </ClCompile>\n"
1264   return $text
1265 }
1266
1267 # Generate Visual Studio 2010 project filters file
1268 proc osutils:vcxproj:filters { dir proj theFilesMap } {
1269   upvar $theFilesMap aFilesMap
1270
1271   # header
1272   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1273   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1274
1275   # list of "filters" (units)
1276   append text "  <ItemGroup>\n"
1277   append text "    <Filter Include=\"Source files\">\n"
1278   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1279   append text "    </Filter>\n"
1280   foreach unit $aFilesMap(units) {
1281     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1282     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1283     append text "    </Filter>\n"
1284   }
1285   append text "  </ItemGroup>\n"
1286
1287   # list of files
1288   append text "  <ItemGroup>\n"
1289   foreach unit $aFilesMap(units) {
1290     foreach file $aFilesMap($unit) {
1291       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1292       append text "      <Filter>Source files\\${unit}</Filter>\n"
1293       append text "    </ClCompile>\n"
1294     }
1295   }
1296   append text "  </ItemGroup>\n"
1297
1298   # end
1299   append text "</Project>"
1300
1301   # write file
1302   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1303   fconfigure $fp -translation crlf
1304   puts $fp $text
1305   close $fp
1306
1307   return ${proj}.vcxproj.filters
1308 }
1309
1310 # Generate Visual Studio 2011 project filters file
1311 proc osutils:vcx1proj:filters { dir proj theFilesMap } {
1312   upvar $theFilesMap aFilesMap
1313
1314   # header
1315   append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1316   append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1317
1318   # list of "filters" (units)
1319   append text "  <ItemGroup>\n"
1320   append text "    <Filter Include=\"Source files\">\n"
1321   append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1322   append text "    </Filter>\n"
1323   foreach unit $aFilesMap(units) {
1324     append text "    <Filter Include=\"Source files\\${unit}\">\n"
1325     append text "      <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1326     append text "    </Filter>\n"
1327   }
1328   append text "  </ItemGroup>\n"
1329
1330   # list of files
1331   append text "  <ItemGroup>\n"
1332   foreach unit $aFilesMap(units) {
1333     foreach file $aFilesMap($unit) {
1334       append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1335       append text "      <Filter>Source files\\${unit}</Filter>\n"
1336       append text "    </ClCompile>\n"
1337     }
1338   }
1339   append text "  </ItemGroup>\n"
1340
1341   append text "  <ItemGroup>\n"
1342   append text "    <ResourceCompile Include=\"${proj}.rc\" />"
1343   append text "  </ItemGroup>\n"
1344
1345   # end
1346   append text "</Project>"
1347
1348   # write file
1349   set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1350   fconfigure $fp -translation crlf
1351   puts $fp $text
1352   close $fp
1353
1354   return ${proj}.vcxproj.filters
1355 }
1356
1357 # Generate RC file content for ToolKit from template
1358 proc osutils:readtemplate:rc {theOutDir theToolKit} {
1359   global path
1360   set aLoc "$path/adm/templates/template_dll.rc"
1361   set aBody [wokUtils:FILES:FileToString $aLoc]
1362   regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1363
1364   set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1365   fconfigure $aFile -translation lf
1366   puts $aFile $aBody
1367   close $aFile
1368   return "${theOutDir}/${theToolKit}.rc"
1369 }
1370
1371 # Generate Visual Studio project file for ToolKit
1372 proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1373   if { $theProjTmpl == {} } {set theProjTmpl [osutils:vcproj:readtemplate $theVcVer 0]}
1374
1375   set l_compilable [osutils:compilable]
1376   regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1377
1378   upvar $theGuidsMap aGuidsMap
1379   if { ! [info exists aGuidsMap($theToolKit)] } {
1380     set aGuidsMap($theToolKit) [OS:genGUID]
1381   }
1382   regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1383
1384   set aCommonUsedTK [list]
1385   foreach tkx [osutils:commonUsedTK  $theToolKit] {
1386     lappend aCommonUsedTK "${tkx}.lib"
1387   }
1388
1389   set aUsedToolKits [concat $aCommonUsedTK [osutils:usedOsLibs $theToolKit "wnt"]]
1390
1391   # correct names of referred third-party libraries that are named with suffix
1392   # depending on VC version
1393   regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1394
1395   # and put this list to project file
1396   #puts "$theToolKit requires  $aUsedToolKits"
1397   if { "$theVcVer" == "vc10" || "$theVcVer" == "vc11" || "$theVcVer" == "vc12" } {
1398     set aUsedToolKits [join $aUsedToolKits {;}]
1399   }
1400   regsub -all -- {__TKDEP__} $theProjTmpl $aUsedToolKits theProjTmpl
1401
1402   set anIncPaths "..\\..\\..\\inc"
1403   set aTKDefines ""
1404   set aFilesSection ""
1405   set aVcFilesX(units) ""
1406   set listloc [osutils:tk:units $theToolKit]
1407   set resultloc [osutils:justwnt $listloc]
1408   if [array exists written] { unset written }
1409   #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1410   #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1411   #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1412   #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1413   set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1414   set fxloparamfc   [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1415   set fxloparam ""
1416   foreach fxlo $resultloc {
1417     set xlo $fxlo
1418     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
1419         set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
1420     if {$fxlo_cmplrs_options_cxx == ""} {
1421       set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1422     }
1423         set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1424     if {$fxlo_cmplrs_options_c == ""} {
1425       set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1426     }
1427     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1428     set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1429         #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1430         #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo  CXX"
1431         #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1432         #puts "\t6 [wokparam -v %CMPLRS_C_Options   $fxlo] $fxlo  C"
1433     set needparam ""
1434     foreach partopt $fxloparam {
1435       if {[string first "-I" $partopt] == "0"} {
1436         # this is an additional includes search path
1437         continue
1438       }
1439       set needparam "$needparam $partopt"
1440     }
1441
1442     # Format of projects in vc10 and vc11 is different from vc7-9
1443     if { "$theVcVer" == "vc10" || "$theVcVer" == "vc11" || "$theVcVer" == "vc12" } {
1444       foreach aSrcFile [lsort $aSrcFiles] {
1445         if { ![info exists written([file tail $aSrcFile])] } {
1446           set written([file tail $aSrcFile]) 1
1447           append aFilesSection [osutils:vcxproj:file $theVcVer $aSrcFile $needparam]
1448         } else {
1449           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1450         }
1451         if { ! [info exists aVcFilesX($xlo)] } { lappend aVcFilesX(units) $xlo }
1452         lappend aVcFilesX($xlo) $aSrcFile
1453       }
1454     } else {
1455       append aFilesSection "\t\t\t<Filter\n"
1456       append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1457       append aFilesSection "\t\t\t\t>\n"
1458       foreach aSrcFile [lsort $aSrcFiles] {
1459         if { ![info exists written([file tail $aSrcFile])] } {
1460           set written([file tail $aSrcFile]) 1
1461           append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1462         } else {
1463           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1464         }
1465       }
1466       append aFilesSection "\t\t\t</Filter>\n"
1467     }
1468
1469     # macros
1470     append aTKDefines ";__${xlo}_DLL"
1471     # common includes
1472 #    append anIncPaths ";..\\..\\..\\src\\${xlo}"
1473   }
1474
1475   regsub -all -- {__TKINC__}  $theProjTmpl $anIncPaths theProjTmpl
1476   regsub -all -- {__TKDEFS__} $theProjTmpl $aTKDefines theProjTmpl
1477   regsub -all -- {__FILES__}  $theProjTmpl $aFilesSection theProjTmpl
1478
1479   # write file
1480   set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1481   fconfigure $aFile -translation crlf
1482   puts $aFile $theProjTmpl
1483   close $aFile
1484
1485   # write filters file for vc10 and vc11
1486   if { "$theVcVer" == "vc10" } {
1487     lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesX]
1488   } elseif { "$theVcVer" == "vc11" || "$theVcVer" == "vc12" } {
1489     lappend aVcFiles [osutils:vcx1proj:filters $theOutDir $theToolKit aVcFilesX]
1490   }
1491
1492   # write resource file
1493   lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1494
1495   return $aVcFiles
1496 }
1497
1498 # for a unit returns a map containing all its file in the current
1499 # workbench
1500 # local = 1 only local files
1501 proc osutils:tk:loadunit { loc map } {
1502   #puts $loc
1503   upvar $map TLOC
1504   catch { unset TLOC }
1505   set lfiles [_get_used_files $loc]
1506   foreach f $lfiles {
1507     #puts "\t$f"
1508     set t [lindex $f 0]
1509     set p [lindex $f 2]
1510     if [info exists TLOC($t)] {
1511       set l $TLOC($t)
1512       lappend l $p
1513       set TLOC($t) $l
1514     } else {
1515       set TLOC($t) $p
1516     }
1517   }
1518   return
1519 }
1520
1521 # Returns the list of all compilable files name in a toolkit, or devunit of any type
1522 # Call unit filter on units name to accept or reject a unit
1523 # Tfiles lists for each unit the type of file that can be compiled.
1524 proc osutils:tk:files { tkloc  {l_compilable {} } {justail 1} {unitfilter {}} } {
1525   global path
1526   set Tfiles(source,nocdlpack)     {source pubinclude}
1527   set Tfiles(source,toolkit)       {}
1528   set Tfiles(source,executable)    {source pubinclude}
1529   set listloc [concat [osutils:tk:units $tkloc] $tkloc]
1530   #puts " listloc = $listloc"
1531   if { $l_compilable == {} } {
1532     set l_comp [list .c .cxx .cpp]
1533   } else {
1534     set l_comp [$l_compilable]
1535   }
1536   if { $unitfilter == {} } {
1537     set resultloc $listloc
1538   } else {
1539     set resultloc [$unitfilter $listloc]
1540   }
1541   set lret {}
1542   foreach loc $resultloc {
1543     set utyp [_get_type $loc]
1544     #puts "\"$utyp\" \"$loc\""
1545     switch $utyp {
1546          "t" { set utyp "toolkit" }
1547          "n" { set utyp "nocdlpack" }
1548          "x" { set utyp "executable" }
1549     }
1550     if [array exists map] { unset map }
1551     osutils:tk:loadunit $loc map
1552     #puts " loc = $loc === > [array names map]"
1553     set LType $Tfiles(source,${utyp})
1554     foreach typ [array names map] {
1555       if { [lsearch $LType $typ] == -1 } {
1556         unset map($typ)
1557       }
1558     }
1559     foreach type [array names map] {
1560       #puts $type
1561       foreach f $map($type) {
1562         #puts $f
1563         if { [lsearch $l_comp [file extension $f]] != -1 } {
1564           if { $justail == 1 } {
1565             if {$type == "source"} {
1566               if {[lsearch $lret "@top_srcdir@/src/$loc/[file tail $f]"] == -1} {
1567                 lappend lret @top_srcdir@/src/$loc/[file tail $f]
1568               }
1569             }
1570           } else {
1571             lappend lret $f
1572           }
1573         }
1574       }
1575     }
1576   }
1577   return $lret
1578 }
1579
1580 # Generate Visual Studio project file for executable
1581 proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1582   global path
1583   set aVcFiles {}
1584   foreach f [osutils:tk:files $theToolKit osutils:compilable 0] {
1585     if { $theProjTmpl == {} } {
1586       set aProjTmpl [osutils:vcproj:readtemplate $theVcVer 1]
1587     } else {
1588       set aProjTmpl $theProjTmpl
1589     }
1590     set aProjName [file rootname [file tail $f]]
1591     set l_compilable [osutils:compilable]
1592     regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
1593
1594     upvar $theGuidsMap aGuidsMap
1595     if { ! [info exists aGuidsMap($aProjName)] } {
1596       set aGuidsMap($aProjName) [OS:genGUID]
1597     }
1598     regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
1599
1600     set aCommonUsedTK [list]
1601     foreach tkx [osutils:commonUsedTK  $theToolKit] {
1602       lappend aCommonUsedTK "${tkx}.lib"
1603     }
1604
1605     set aUsedToolKits [concat $aCommonUsedTK [osutils:usedOsLibs $theToolKit "wnt"]]
1606         #puts "\t 7 $WOKSteps_exec_link($theToolKit)"
1607     if { [regexp {WOKStep_DLLink} [_get_options wnt WOKSteps_exec_link $theToolKit]] || [regexp {WOKStep_Libink} [_get_options wnt WOKSteps_exec_link $theToolKit]] } {
1608       set aUsedToolKits [concat $aUsedToolKits "\/dll"]
1609       set binext 2
1610     } else {
1611       set binext 1
1612     }
1613
1614     # correct names of referred third-party libraries that are named with suffix
1615     # depending on VC version
1616     regsub -all -- {vc[0-9]+} $aUsedToolKits $theVcVer aUsedToolKits
1617
1618 #    puts "$aProjName requires  $aUsedToolKits"
1619     if { "$theVcVer" == "vc10" || "$theVcVer" == "vc11" || "$theVcVer" == "vc12" } {
1620       set aUsedToolKits [join $aUsedToolKits {;}]
1621     }
1622     regsub -all -- {__TKDEP__} $aProjTmpl $aUsedToolKits aProjTmpl
1623
1624     set aFilesSection ""
1625     set aVcFilesX(units) ""
1626
1627     if { ![info exists written([file tail $f])] } {
1628       set written([file tail $f]) 1
1629
1630       if { "$theVcVer" == "vc10" || "$theVcVer" == "vc11" || "$theVcVer" == "vc12" } {
1631         append aFilesSection [osutils:vcxproj:file $theVcVer $f ""]
1632         if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
1633         lappend aVcFilesX($theToolKit) $f
1634       } else {
1635         append aFilesSection "\t\t\t<Filter\n"
1636         append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
1637         append aFilesSection "\t\t\t\t>\n"
1638         append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
1639         append aFilesSection "\t\t\t</Filter>"
1640       }
1641     } else {
1642       puts "Warning : in vcproj there are than one occurences for [file tail $f]"
1643     }
1644     #puts "$aProjTmpl $aFilesSection"
1645     set aTKDefines ";__${theToolKit}_DLL"
1646     set anIncPaths "..\\..\\..\\inc"
1647     regsub -all -- {__TKINC__}  $aProjTmpl $anIncPaths    aProjTmpl
1648     regsub -all -- {__TKDEFS__} $aProjTmpl $aTKDefines    aProjTmpl
1649     regsub -all -- {__FILES__}  $aProjTmpl $aFilesSection aProjTmpl
1650     regsub -all -- {__CONF__}   $aProjTmpl $binext        aProjTmpl
1651     if { $binext == 2 } {
1652       regsub -all -- {__XQTEXT__} $aProjTmpl "dll" aProjTmpl
1653     } else {
1654       regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
1655     }
1656
1657     set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
1658     fconfigure $aFile -translation crlf
1659     puts $aFile $aProjTmpl
1660     close $aFile
1661
1662     set aCommonSettingsFile "$aVcFilePath.user"
1663     lappend aVcFiles $aVcFilePath
1664
1665     # write filters file for vc10
1666     if { "$theVcVer" == "vc10" || "$theVcVer" == "vc11" || "$theVcVer" == "vc12" } {
1667       lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesX]
1668     }
1669
1670     set aCommonSettingsFileTmpl ""
1671     if { "$theVcVer" == "vc9" } {
1672       set aCommonSettingsFileTmpl "$path/adm/templates/vcproj.user.vc9x"
1673     } elseif { "$theVcVer" == "vc10" } {
1674       set aCommonSettingsFileTmpl "$path/adm/templates/vcxproj.user.vc10x"
1675     } elseif { "$theVcVer" == "vc11" } {
1676       set aCommonSettingsFileTmpl "$path/adm/templates/vcxproj.user.vc11x"
1677     } elseif { "$theVcVer" == "vc12" } {
1678       set aCommonSettingsFileTmpl "$path/adm/templates/vcxproj.user.vc12x"
1679     }
1680     if { "$aCommonSettingsFileTmpl" != "" } {
1681       file copy -force -- "$aCommonSettingsFileTmpl" "$aCommonSettingsFile"
1682       lappend aVcFiles "$aCommonSettingsFile"
1683     }
1684   }
1685   return $aVcFiles
1686 }
1687
1688 # Generate entry for one source file in Visual Studio 7 - 9 project file
1689 proc osutils:vcproj:file { theVcVer theFile theOptions } {
1690   append aText "\t\t\t\t<File\n"
1691   append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1692   if { $theOptions == "" } {
1693     append aText "\t\t\t\t</File>\n"
1694     return $aText
1695   }
1696
1697   append aText "\t\t\t\t\t<FileConfiguration\n"
1698   append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
1699   append aText "\t\t\t\t\t\t<Tool\n"
1700   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1701   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1702   foreach aParam $theOptions {
1703     append aText "$aParam "
1704   }
1705   append aText "\"\n"
1706   append aText "\t\t\t\t\t\t/>\n"
1707   append aText "\t\t\t\t\t</FileConfiguration>\n"
1708
1709   append aText "\t\t\t\t\t<FileConfiguration\n"
1710   append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
1711   append aText "\t\t\t\t\t\t<Tool\n"
1712   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1713   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1714   foreach aParam $theOptions {
1715     append aText "$aParam "
1716   }
1717   append aText "\"\n"
1718   append aText "\t\t\t\t\t\t/>\n"
1719   append aText "\t\t\t\t\t</FileConfiguration>\n"
1720   if { "$theVcVer" == "vc7" } {
1721     append aText "\t\t\t\t</File>\n"
1722     return $aText
1723   }
1724
1725   append aText "\t\t\t\t\t<FileConfiguration\n"
1726   append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
1727   append aText "\t\t\t\t\t\t<Tool\n"
1728   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1729   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1730   foreach aParam $theOptions {
1731     append aText "$aParam "
1732   }
1733   append aText "\"\n"
1734   append aText "\t\t\t\t\t\t/>\n"
1735   append aText "\t\t\t\t\t</FileConfiguration>\n"
1736
1737   append aText "\t\t\t\t\t<FileConfiguration\n"
1738   append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
1739   append aText "\t\t\t\t\t\t<Tool\n"
1740   append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1741   append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1742   foreach aParam $theOptions {
1743     append aText "$aParam "
1744   }
1745   append aText "\"\n"
1746   append aText "\t\t\t\t\t\t/>\n"
1747   append aText "\t\t\t\t\t</FileConfiguration>\n"
1748
1749   append aText "\t\t\t\t</File>\n"
1750   return $aText
1751 }
1752
1753 ### AUTOMAKE ###############################################################################
1754 proc OS:MKAMK { theOutDir {theModules {}} theSubPath} {
1755   global path
1756   wokUtils:FILES:mkdir $theOutDir
1757
1758   foreach aModule $theModules {
1759     foreach aToolKit [$aModule:toolkits] {
1760       puts " toolkit: $aToolKit ==> $path/src/$aToolKit/EXTERNLIB"
1761       wokUtils:FILES:rmdir $theOutDir/$aToolKit
1762       wokUtils:FILES:mkdir $theOutDir/$aToolKit
1763       osutils:tk:mkam $theOutDir/$aToolKit $aToolKit
1764     }
1765     foreach anExecutable [OS:executable $aModule] {
1766       wokUtils:FILES:rmdir $theOutDir/$anExecutable
1767       wokUtils:FILES:mkdir $theOutDir/$anExecutable
1768       osutils:tk:mkamx $theOutDir/$anExecutable $anExecutable
1769     }
1770   }
1771   osutils:am:adm $theOutDir $theModules
1772   osutils:am:root $path $theSubPath $theModules
1773
1774   puts "The automake files are stored in the $theOutDir directory"
1775 }
1776
1777 proc wokUtils:FILES:rmdir { d } {
1778     global env
1779     global tcl_platform tcl_version  
1780     regsub -all {\.[^.]*} $tcl_version "" major
1781     if { $major == 8 } {
1782         file delete -force $d
1783     } else {
1784         if { "$tcl_platform(platform)" == "unix" } {
1785             catch { exec rm -rf $d}
1786         } else {
1787             
1788         }
1789     }
1790     return 
1791 }
1792
1793 proc wokUtils:FILES:mkdir { d } {
1794     global tcl_version
1795     regsub -all {\.[^.]*} $tcl_version "" major
1796     if { $major == 8 } {
1797         file mkdir $d
1798     } else {
1799         if ![file exists $d] {
1800             if { "[info command mkdir]" == "mkdir" } {
1801                 mkdir -path $d
1802             } else {
1803                 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
1804             }
1805         }
1806     }
1807     if [file exists $d] {
1808         return $d
1809     } else {
1810         return {}
1811     }
1812 }
1813
1814 # "Nice letter: %s" { a b c } => {Nice letter: %a}  {Nice letter: %b} ..
1815 # as a string without backslash
1816 proc wokUtils:EASY:FmtSimple1 { fmt l {backslh 1} } {
1817     foreach e $l {
1818         if { $backslh } {
1819             append str [format $fmt $e] "\n"
1820         } else {
1821             append str [format $fmt $e]
1822         }
1823     }
1824     return $str
1825 }
1826
1827 # edit_last is performed ONCE fmt has been applied.
1828 proc wokUtils:EASY:FmtString2 { fmt l {yes_for_last 0} {edit_last {}} } {
1829     set ldeb [lrange $l 0 [expr [llength $l] -2]]
1830     set last [lrange $l end end]
1831     foreach e $ldeb {
1832         append str [format $fmt $e $e] " \\" "\n"
1833     }
1834
1835     if {$edit_last != {} } {
1836         set slast [$edit_last [format $fmt $last $last]]
1837     } else {
1838         set slast [format $fmt $last $last]
1839     }
1840
1841     if { $yes_for_last } {
1842         append str $slast " \\" "\n" 
1843     } else {
1844         append str $slast "\n"
1845     }
1846
1847     return $str
1848 }
1849
1850 # { a.x b.c c.v } => { a b c}
1851 proc wokUtils:LIST:sanspoint { l } {
1852     set rr {}
1853     foreach x $l {
1854         lappend rr [file root $x]
1855     }
1856     return $rr
1857 }
1858
1859 # remove from listloc OpenCascade units indesirables on Unix
1860 proc osutils:justunix { listloc } {
1861   if { "$::tcl_platform(os)" == "Darwin" && "$::MACOSX_USE_GLX" != "true" } {
1862     set goaway [list Xw WNT]
1863   } else {
1864     set goaway [list WNT]
1865   }
1866   return [osutils:juststation $goaway $listloc]
1867 }
1868
1869 # remove ":" from last item of dependencies list in target VPATH of Makefile.am
1870 proc osutils:am:__VPATH__lastoccur { str } {
1871   if { [regsub {:$} $str "" u] != 0 } {
1872     return $u
1873   }
1874 }
1875
1876 #  ((((((((((((( Formats in Makefile.am )))))))))))))
1877 # Used to replace the string __VPATH__ in Makefile.am
1878 # l is the list of the units in a toolkit.
1879 proc osutils:am:__VPATH__ { l } {
1880   set fmt "@top_srcdir@/src/%s:"
1881   return [wokUtils:EASY:FmtString2 $fmt $l 0 osutils:am:__VPATH__lastoccur]
1882 }
1883
1884 # Used to replace the string __INCLUDES__ in Makefile.am
1885 # l is the list of packages in a toolkit.
1886 proc osutils:am:__INCLUDES__ { l } {
1887   set fmt "-I@top_srcdir@/src/%s"
1888   return [wokUtils:EASY:FmtString2 $fmt $l]
1889 }
1890
1891 # Used to replace the string __LIBADD__ in Makefile.am
1892 # l is the toolkit closure list of a toolkit.
1893 proc osutils:am:__LIBADD__ { theIncToolkits {final 0} } {
1894   global path
1895   global fBranch
1896   set aFatherModules ""
1897   set aCurrentWorkBench [file tail $path]
1898   if { $fBranch != "" } {
1899     set fd [open $fBranch/adm/UDLIST rb]
1900     set fileContent [split [read $fd] "\n"]
1901     close $fd
1902     set ftoolkits [lsearch -all -inline $fileContent "t *"]
1903     foreach ft $ftoolkits {
1904       set aFatherModules "$aFatherModules [string range $ft 2 end]"
1905     }
1906   }
1907   set aLibString ""
1908   foreach aIncToolkit $theIncToolkits {
1909     if { [lsearch [split $aFatherModules " "] $aIncToolkit] != -1} {
1910       append aLibString " \\\n-l$aIncToolkit"
1911     } else {
1912       append aLibString " \\\n../$aIncToolkit/lib$aIncToolkit.la"
1913     }
1914   }
1915   return $aLibString
1916 }
1917
1918 # Used to replace the string __SOURCES__ in Makefile.am
1919 # l is the list of all compilable files in a toolkit.
1920 proc osutils:am:__SOURCES__ { l } {
1921   set fmt "%s"
1922   return [wokUtils:EASY:FmtString1 $fmt $l]
1923 }
1924
1925 proc osutils:am:__CXXFLAG__ { l } {
1926   set fmt "%s"
1927   return [wokUtils:EASY:FmtString1 $fmt [osutils:am:PkCXXOption $l]]
1928 }
1929
1930 proc osutils:am:PkCXXOption { ppk } {
1931   global path
1932   #puts "\t 1 [lindex [wokparam -e  %CMPLRS_CXX_Options [wokcd]] 0]"
1933   set CXXCOMMON [_get_options lin cmplrs_cxx b]
1934   #puts "\t 2 [wokparam -v %CMPLRS_CXX_Options [w_info -f]]"
1935   #puts "\t 3 [wokparam -v %CMPLRS_CXX_Options]"
1936   set FoundFlag "[lindex [osutils:intersect3 [split [_get_options lin cmplrs_cxx f]] [split [_get_options lin cmplrs_cxx b]] ] 2]"
1937   foreach pk $ppk {
1938     #puts $pk
1939         if {![file isdirectory $path/src/$pk]} {
1940           continue
1941         }
1942     set src_files [_get_used_files $pk false]
1943     set only_src_files {}
1944     foreach s $src_files { 
1945       regexp {source ([^\s]+)} $s dummy name
1946       lappend only_src_files $name
1947     }
1948     if {[lsearch $only_src_files ${pk}_CMPLRS.edl] != "-1"} {
1949       set pk_cmplrs_cxx [_get_options lin cmplrs_cxx $pk]
1950       if {$pk_cmplrs_cxx == ""} {
1951             set pk_cmplrs_cxx [_get_options lin cmplrs_cxx b]
1952           }
1953       set CXXStr  $pk_cmplrs_cxx
1954           #puts "\t 4 [wokparam -e %CMPLRS_CXX_Options [woklocate -u $pk]] $pk"
1955       set LastIndex [expr {[string length $CXXCOMMON ] - 1}]
1956       if {[string equal $CXXCOMMON [string range $CXXStr 0 $LastIndex]]} {
1957         set CXXOption " "
1958       } else {
1959         set CXXOption [string range $CXXStr 0 [expr {[string last $CXXCOMMON $CXXStr] - 1}]]
1960       }
1961       if {$CXXOption != " " && $CXXOption != "" && $CXXOption != "  " && $CXXOption != "   "} {
1962         set FoundList [split $CXXOption " "]
1963         foreach elem $FoundList {
1964           if {$elem != ""} {
1965             if {[string first "-I" $elem] == "-1"  } {
1966               if {[string first $elem $FoundFlag] == "-1"} {
1967                 set FoundFlag "$FoundFlag $elem"
1968               }
1969             }
1970           }
1971         }
1972       }
1973     }
1974   }
1975   return $FoundFlag
1976 }
1977
1978 # Create in dir the Makefile.am associated with toolkit tkloc.
1979 # Returns the full path of the created file.
1980 proc osutils:tk:mkam { dir tkloc } {
1981   global path
1982   set pkgs $path/src/${tkloc}/PACKAGES
1983   if { ![file exists $pkgs] } {
1984     puts stderr "osutils:tk:mkam : Error. File PACKAGES not found for toolkit $tkloc."
1985     return {}
1986   }
1987
1988   set tmplat [osutils:readtemplate mam "Makefile.am"]
1989   set lpkgs  [osutils:justunix [wokUtils:FILES:FileToList $pkgs]]
1990   set close  [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
1991   set lsrc   [lsort [osutils:tk:files $tkloc osutils:compilable 1 osutils:justunix]]
1992   set lobj   [wokUtils:LIST:sanspoint $lsrc]
1993
1994   set lcsf   [osutils:tk:hascsf $path/src/${tkloc}/EXTERNLIB]
1995
1996   set final 0
1997   set externinc ""
1998   set externlib ""
1999   if { $lcsf != {} } {
2000     set final 1
2001     set fmtinc "\$(%s_INCLUDES) "
2002     set fmtlib "\$(%s_LIB) "
2003     set externinc [wokUtils:EASY:FmtSimple1 $fmtinc $lcsf 0]
2004     set externlib [wokUtils:EASY:FmtSimple1 $fmtlib $lcsf 0]
2005   }
2006
2007   regsub -all -- {__TKNAM__} $tmplat $tkloc tmplat
2008   set vpath [osutils:am:__VPATH__ $lpkgs]
2009   regsub -all -- {__VPATH__} $tmplat $vpath tmplat
2010   set inclu [osutils:am:__INCLUDES__ $lpkgs]
2011   regsub -all -- {__INCLUDES__} $tmplat $inclu tmplat
2012   if { $close != {} } {
2013     set libadd [osutils:am:__LIBADD__ $close $final]
2014   } else {
2015     set libadd ""
2016   }
2017   regsub -all -- {__LIBADD__} $tmplat $libadd tmplat
2018   set source [osutils:am:__SOURCES__ $lsrc]
2019   regsub -all -- {__SOURCES__} $tmplat $source tmplat
2020   regsub -all -- {__EXTERNINC__} $tmplat $externinc tmplat
2021   set CXXFl [osutils:am:__CXXFLAG__ $lpkgs]
2022   regsub -all -- {__CXXFLAG__} $tmplat $CXXFl tmplat
2023   set CFl [osutils:am:__CFLAG__ $lpkgs]
2024   regsub -all -- {__CFLAG__} $tmplat $CFl tmplat
2025
2026   regsub -all -- {__EXTERNLIB__} $tmplat $externlib tmplat
2027
2028   wokUtils:FILES:StringToFile $tmplat [set fmam [file join $dir Makefile.am]]
2029   return [list $fmam]
2030 }
2031
2032 # Write a string in a file
2033 proc wokUtils:FILES:StringToFile { str path } {
2034     if { [catch { set out [ open $path w ] } errout] == 0 } {
2035         puts -nonewline $out $str
2036         close $out
2037         return 1
2038     } else {
2039         return {}
2040     }
2041 }
2042
2043 # Create in dir the Makefile.am associated with toolkit tkloc.
2044 # Returns the full path of the created file.
2045 proc osutils:tk:mkamx { dir tkloc } {
2046   global path
2047   set src_files [_get_used_files $tkloc false]
2048   set only_src_files {}
2049   foreach s $src_files { 
2050     regexp {source ([^\s]+)} $s dummy name
2051     lappend only_src_files $name
2052   }
2053   if { [lsearch $only_src_files ${tkloc}_WOKSteps.edl] != "-1"} {
2054     set pkgs "$path/src/${tkloc}/EXTERNLIB"
2055     if { $pkgs == {} } {
2056       puts stderr "osutils:tk:mkamx : Error. File EXTERNLIB not found for executable $tkloc."
2057       #return {}
2058     }
2059     set tmplat [osutils:readtemplate mamx "Makefile.am (executable)"]
2060     set close  [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
2061     set lsrc   [lsort [osutils:tk:files $tkloc osutils:compilable 1 osutils:justunix]]
2062     set lobj   [wokUtils:LIST:sanspoint $lsrc]
2063     set CXXList {}
2064     foreach SourceFile $only_src_files {
2065       if {[file extension $SourceFile] == ".cxx"} {
2066         lappend CXXList [file rootname $SourceFile]
2067       }
2068     }
2069     set pkgs [LibToLinkX $tkloc [lindex $CXXList 0]]
2070     set lpkgs  [osutils:justunix [wokUtils:FILES:FileToList $pkgs]]
2071     puts "pkgs $pkgs"
2072     #set lcsf   [osutils:tk:hascsf [woklocate -p ${tkloc}:source:EXTERNLIB [wokcd]]]
2073
2074     set lcsf {}
2075     foreach tk $pkgs {
2076       foreach element [osutils:tk:hascsf "$path/src/${tk}/EXTERNLIB"] {
2077         if {[lsearch $lcsf $element] == "-1"} {
2078           set lcsf [concat $lcsf $element]
2079         }
2080       }
2081     }
2082     set final 0
2083     set externinc ""
2084     set externlib ""
2085     if { $lcsf != {} } {
2086       set final 1
2087       set fmtinc "\$(%s_INCLUDES) "
2088       set fmtlib "\$(%s_LIB) "
2089       set externinc [wokUtils:EASY:FmtSimple1 $fmtinc $lcsf 0]
2090       set externlib [wokUtils:EASY:FmtSimple1 $fmtlib $lcsf 0]
2091     }
2092     regsub -all -- {__XQTNAM__} $tmplat $tkloc tmplat
2093     set tmplat "$tmplat \nlib_LTLIBRARIES="
2094     foreach entity $CXXList {
2095       set tmplat "$tmplat lib${entity}.la"
2096     }
2097     set tmplat "$tmplat\n"
2098     set inclu [osutils:am:__INCLUDES__ $lpkgs]
2099     regsub -all -- {__INCLUDES__} $tmplat $inclu tmplat
2100     if { $pkgs != {} } {
2101       set libadd [osutils:am:__LIBADD__ $pkgs $final]
2102     } else {
2103       set libadd ""
2104     }
2105     regsub -all -- {__LIBADD__} $tmplat $libadd tmplat
2106     set source [osutils:am:__SOURCES__ $CXXList]
2107     regsub -all -- {__SOURCES__} $tmplat $source tmplat
2108     regsub -all -- {__EXTERNINC__} $tmplat $externinc tmplat
2109     foreach entity $CXXList {
2110       set tmplat "$tmplat lib${entity}_la_SOURCES = @top_srcdir@/src/${tkloc}/${entity}.cxx \n"
2111     }
2112     foreach entity $CXXList {
2113       set tmplat "$tmplat lib${entity}_la_LIBADD = $libadd $externlib \n"
2114     }
2115     wokUtils:FILES:StringToFile $tmplat [set fmam [file join $dir Makefile.am]]
2116
2117     unset tmplat
2118
2119     return [list $fmam]
2120
2121   } else {
2122     set pkgs "$path/src/${tkloc}/EXTERNLIB"
2123     if { $pkgs == {} } {
2124       puts stderr "osutils:tk:mkamx : Error. File EXTERNLIB not found for executable $tkloc."
2125       #return {}
2126     }
2127     set tmplat [osutils:readtemplate mamx "Makefile.am (executable)"]
2128     set close  [wokUtils:LIST:Purge [osutils:tk:close $tkloc]]
2129     set lsrc   [lsort [osutils:tk:files $tkloc osutils:compilable 1 osutils:justunix]]
2130     set lobj   [wokUtils:LIST:sanspoint $lsrc]
2131     set CXXList {}
2132     foreach SourceFile $only_src_files {
2133       if {[file extension $SourceFile] == ".cxx"} {
2134         lappend CXXList [file rootname $SourceFile]
2135       }
2136     }
2137     set pkgs [LibToLinkX $tkloc [lindex $CXXList 0]]
2138     set lpkgs  [osutils:justunix [wokUtils:FILES:FileToList $pkgs]]
2139     set lcsf   [osutils:tk:hascsf "$path/src/${tkloc}/EXTERNLIB"]
2140
2141     set lcsf {}
2142     foreach tk $pkgs {
2143       foreach element [osutils:tk:hascsf "$path/src/${tk}/EXTERNLIB"] {
2144         if {[lsearch $lcsf $element] == "-1"} {
2145           set lcsf [concat $lcsf $element]
2146         }
2147       }
2148     }
2149     set final 0
2150     set externinc ""
2151     set externlib ""
2152     if { $lcsf != {} } {
2153       set final 1
2154       set fmtinc "\$(%s_INCLUDES) "
2155       set fmtlib "\$(%s_LIB) "
2156       set externinc [wokUtils:EASY:FmtSimple1 $fmtinc $lcsf 0]
2157       set externlib [wokUtils:EASY:FmtSimple1 $fmtlib $lcsf 0]
2158     }
2159     regsub -all -- {__XQTNAM__} $tmplat $tkloc tmplat
2160     set tmplat "$tmplat \nbin_PROGRAMS="
2161     foreach entity $CXXList {
2162       set tmplat "${tmplat} ${entity}"
2163     }
2164
2165     set tmplat "${tmplat}\n"
2166     set inclu [osutils:am:__INCLUDES__ $lpkgs]
2167     regsub -all -- {__INCLUDES__} $tmplat $inclu tmplat
2168     if { $pkgs != {} } {
2169       set libadd [osutils:am:__LIBADD__ $pkgs $final]
2170     } else {
2171       set libadd ""
2172     }
2173     set source [osutils:am:__SOURCES__ $CXXList]
2174     regsub -all -- {__SOURCES__} $tmplat $source tmplat
2175     regsub -all -- {__EXTERNINC__} $tmplat $externinc tmplat
2176     foreach entity $CXXList {
2177       set tmplat "$tmplat ${entity}_SOURCES = @top_srcdir@/src/${tkloc}/${entity}.cxx \n"
2178     }
2179     foreach entity $CXXList {
2180       set tmplat "$tmplat ${entity}_LDADD = $libadd $externlib \n"
2181     }
2182     wokUtils:FILES:StringToFile $tmplat [set fmam [file join $dir Makefile.am]]
2183
2184     return [list $fmam]
2185   }
2186 }
2187
2188 # Create in dir the Makefile.am in $dir directory.
2189 # Returns the full path of the created file.
2190 proc osutils:am:adm { dir {lesmodules {}} } {
2191   set amstring "srcdir = @srcdir@\n\n"
2192   set subdirs "SUBDIRS ="
2193   set vpath "VPATH = @srcdir@ ${dir}: "
2194   set make ""
2195   set phony ".PHONY:"
2196   foreach theModule $lesmodules {
2197     set units [osutils:tk:sort [$theModule:toolkits]]
2198     set units [concat $units [OS:executable $theModule]]
2199     append amstring "${theModule}_PKGS ="
2200     append vpath "\\\n"
2201     foreach unit $units {
2202       append amstring " ${unit}"
2203       append vpath "${dir}/${unit}: "
2204     }
2205     set up ${theModule}
2206     if { [info procs ${theModule}:alias] != "" } {
2207       set up [${theModule}:alias]
2208     }
2209     set up [string toupper ${up}]
2210     append amstring "\n\nif ENABLE_${up}\n"
2211     append amstring "  ${theModule}_DIRS = \$(${theModule}_PKGS)\n"
2212     append amstring "else\n"
2213     append amstring "  ${theModule}_DIRS = \n"
2214     append amstring "endif\n\n"
2215     append subdirs " \$(${theModule}_DIRS)"
2216     append make "${theModule}:\n"
2217     append make "\tfor d in \$(${theModule}_PKGS); do \\\n"
2218     append make "\t\tcd \$\$d; \$(MAKE) \$(AM_MAKEFLAGS) lib\$\$d.la; cd ..; \\\n"
2219     append make "\tdone\n\n"
2220     append phony " ${theModule}"
2221   }
2222   append amstring "$subdirs\n\n"
2223   append amstring "$vpath\n\n"
2224   append amstring $make
2225   append amstring $phony
2226   wokUtils:FILES:StringToFile $amstring [set fmam [file join $dir Makefile.am]]
2227   return [list $fmam]
2228 }
2229
2230 # retourne la liste de dependances de module.
2231 proc OS:lsdep { m } {
2232     set res {}
2233     set l [${m}:depends]
2234     if { $l != {} } {
2235         set res [concat $res $l]
2236         foreach h $l {
2237             set res [concat $res [OS:lsdep ${h}]]
2238         }
2239     }
2240     return $res
2241 }
2242
2243 # Create in dir the Makefile.am and configure.ac in CASROOT directory.
2244 # Returns the full path of the created file.
2245 proc osutils:am:root { dir theSubPath {lesmodules {}} } {
2246   global path
2247   set amstring "srcdir = @srcdir@\n\n"
2248   append amstring "SUBDIRS = ${theSubPath}\n\n"
2249   append amstring "VPATH = @srcdir@ @top_srcdir@/${theSubPath}: @top_srcdir@/${theSubPath}:\n\n"
2250
2251   set phony ".PHONY:"
2252
2253   set acstring [osutils:readtemplate ac "Makefile.am"]
2254   set enablestr ""
2255   set confstr ""
2256   set condstr ""
2257   set repstr ""
2258   set acconfstr ""
2259
2260   set exelocal "install-exec-local:\n"
2261   append exelocal "\t"
2262   append exelocal {$(INSTALL) -d $(prefix)/$(platform)}
2263   append exelocal "\n"
2264   foreach d {bin lib} {
2265     append exelocal "\t"
2266     append exelocal "if \[ -e \$(prefix)/${d} -a ! -e \$(prefix)/\$(platform)/${d} \]; then \\\n"
2267     append exelocal "\t\tcd \$(prefix)/\$(platform) && ln -s ../${d} ${d}; \\\n"
2268     append exelocal "\tfi\n"
2269   }
2270   append exelocal "\t"
2271   append exelocal {buildd=`pwd`; cd $(top_srcdir); sourced=`pwd`; cd $(prefix); installd=`pwd`; cd $$buildd;}
2272   append exelocal " \\\n"
2273   append exelocal "\t"
2274   append exelocal {if [ "$$installd" != "$$sourced" ]; then}
2275   append exelocal " \\\n"
2276   append exelocal "\t\t"
2277   append exelocal {$(INSTALL) -d $(prefix)/src;}
2278   append exelocal " \\\n"
2279   append exelocal "\t\t"
2280   append exelocal {cp -frL $(top_srcdir)/src $(prefix);}
2281   append exelocal " \\\n"
2282   append exelocal "\t\t"
2283   append exelocal {cp -frL $$buildd/config.h $(prefix);}
2284   append exelocal " \\\n"
2285   append exelocal "\t\tfor d in "
2286
2287   foreach theModule $lesmodules {
2288     append amstring "${theModule}_PKGS ="
2289     foreach r [${theModule}:ressources] {
2290       if { "[lindex $r 1]" == "r" } {
2291         append amstring " [lindex $r 2]"
2292       }
2293     }
2294     set up ${theModule}
2295     if { [info procs ${theModule}:alias] != "" } {
2296       set up [${theModule}:alias]
2297     }
2298     set up [string toupper ${up}]
2299     set lower ${theModule}
2300     if { [info procs ${theModule}:alias] != "" } {
2301       set lower [${theModule}:alias]
2302     }
2303     set lower [string tolower ${lower}]
2304
2305     append amstring "\n\nif ENABLE_${up}\n"
2306     append amstring "  ${theModule}_DIRS = \$(${theModule}_PKGS)\n"
2307     append amstring "else\n"
2308     append amstring "  ${theModule}_DIRS = \n"
2309     append amstring "endif\n\n"
2310     append amstring "${theModule}:\n"
2311     append amstring "\tcd \$(top_builddir)/${theSubPath} && \$(MAKE) \$(AM_MAKEFLAGS) ${theModule}\n\n"
2312     append phony " ${theModule}"
2313
2314     append exelocal " \$(${theModule}_DIRS)"
2315
2316     append enablestr "AC_ARG_ENABLE(\[${lower}\],\n"
2317     append enablestr "  \[AS_HELP_STRING(\[--disable-${lower}\],\[Disable ${theModule} components\])\],\n"
2318     append enablestr "  \[ENABLE_${up}=\${enableval}\],\[ENABLE_${up}=yes\])\n"
2319
2320     set deplist [OS:lsdep ${theModule}]
2321     set acdeplist {}
2322     if { [info procs ${theModule}:acdepends] != "" } {
2323       set acdeplist [${theModule}:acdepends]
2324     }
2325
2326     if { [llength $deplist] > 0 || [llength $acdeplist] > 0} {
2327       append confstr "if test \"xyes\" = \"x\$ENABLE_${up}\"; then\n"
2328     } else {
2329       append confstr "if test \"xyes\" != \"x\$ENABLE_${up}\"; then\n"
2330     }
2331     foreach dep $deplist {
2332       set dup ${dep}
2333       if { [info procs ${dep}:alias] != "" } {
2334         set dup [${dep}:alias]
2335       }
2336       set dup [string toupper ${dup}]
2337       append confstr "  if test \"xyes\" = \"x\$ENABLE_${up}\" -a \"xyes\" != \"x\$ENABLE_${dup}\"; then\n"
2338       append confstr "    AC_MSG_NOTICE(\[Disabling ${theModule}: not building ${dep} component\])\n"
2339       append confstr "    DISABLE_${up}_REASON=\"(${dep} component disabled)\"\n"
2340       append confstr "    ENABLE_${up}=no\n"
2341       append confstr "  fi\n"
2342     }
2343     foreach dep $acdeplist {
2344       append confstr "  if test \"xyes\" = \"x\$ENABLE_${up}\" -a \"xyes\" != \"x\$HAVE_${dep}\"; then\n"
2345       append confstr "    AC_MSG_NOTICE(\[Disabling ${theModule}: ${dep} not found\])\n"
2346       append confstr "    DISABLE_${up}_REASON=\"(${dep} not found)\"\n"
2347       append confstr "    ENABLE_${up}=no\n"
2348       append confstr "  fi\n"
2349     }
2350     if { [llength $deplist] > 0 || [llength $acdeplist] > 0 } {
2351       append confstr "else\n"
2352     }
2353     append confstr "  DISABLE_${up}_REASON=\"(Disabled)\"\n"
2354     append confstr "fi\n"
2355
2356     append condstr "AM_CONDITIONAL(\[ENABLE_${up}\], \[test \"xyes\" = \"x\$ENABLE_${up}\"\])\n"
2357     append repstr [format "echo \"%-*s  \$ENABLE_${up} \$DISABLE_${up}_REASON\"" 26 ${theModule}]
2358     append repstr "\n"
2359
2360     set units [$theModule:toolkits]
2361     set units [concat $units [OS:executable $theModule]]
2362     foreach unit $units {
2363       append acconfstr "${theSubPath}/${unit}/Makefile \\\n"
2364     }
2365   }
2366
2367   append exelocal "; do \\\n"
2368   append exelocal "\t\t\t"
2369   append exelocal {$(INSTALL) -d $(prefix)/src/$$d;}
2370   append exelocal " \\\n"
2371   append exelocal "\t\t\t"
2372   append exelocal {cp -frL $(top_srcdir)/src/$$d $(prefix)/src;}
2373   append exelocal " \\\n"
2374   append exelocal "\t\tdone; \\\n"
2375   append exelocal "\tfi\n"
2376   append exelocal "\t"
2377   append exelocal {if [ -e $(prefix)/src/config.h ]; then}
2378   append exelocal " \\\n"
2379   append exelocal "\t\t"
2380   append exelocal {unlink $(prefix)/src/config.h;}
2381   append exelocal " \\\n"
2382   append exelocal "\tfi\n"
2383   append exelocal "\t"
2384   append exelocal {cd $(prefix)/src && ln -s ../config.h config.h}
2385   append exelocal "\n"
2386   append exelocal "\t"
2387   append exelocal {cd $(top_srcdir) && cp *.sh $(prefix)}
2388   append exelocal "\n"
2389   append exelocal "\n"
2390
2391   append amstring $exelocal
2392   append amstring $phony
2393
2394   regsub -all -- {__ENABLEMODULES__} $acstring $enablestr acstring
2395   regsub -all -- {__CONFMODULES__} $acstring $confstr acstring
2396   regsub -all -- {__CONDMODULES__} $acstring $condstr acstring
2397   regsub -all -- {__REPMODULES__} $acstring $repstr acstring
2398   regsub -all -- {__ACCONFMODULES__} $acstring $acconfstr acstring
2399
2400   wokUtils:FILES:StringToFile $amstring [set fmam [file join $dir Makefile.am]]
2401   wokUtils:FILES:StringToFile $acstring [set fmam [file join $dir configure.ac]]
2402   file copy -force -- [file join $path/adm/templates build_configure] [file join $dir build_configure]
2403   file copy -force -- [file join $path/adm/templates acinclude.m4] [file join $dir acinclude.m4]
2404   file copy -force -- [file join $path/adm/templates custom.sh.in] [file join $dir custom.sh.in]
2405   return [list $fmam]
2406 }
2407
2408 proc wokUtils:EASY:FmtString1 { fmt l {yes_for_last 0} {edit_last {}} } {
2409     set ldeb [lrange $l 0 [expr [llength $l] -2]]
2410     set last [lrange $l end end]
2411     foreach e $ldeb {
2412         append str [format $fmt $e] " \\" "\n"
2413     }
2414
2415     if {$edit_last != {} } {
2416         set slast [$edit_last [format $fmt $last]]
2417     } else {
2418         set slast [format $fmt $last]
2419     }
2420
2421     if { $yes_for_last } {
2422         append str $slast " \\" "\n" 
2423     } else {
2424         append str $slast "\n"
2425     }
2426     return $str
2427 }
2428
2429 # Used to replace the string __CFLAG__ in Makefile.am
2430 # l is the list of all compilable files in a toolkit.
2431 proc osutils:am:__CFLAG__ { l } {
2432   set fmt "%s"
2433   return [wokUtils:EASY:FmtString1 $fmt [osutils:am:PkCOption $l]]
2434 }
2435
2436 proc osutils:am:PkCOption { ppk } {
2437   global path
2438   #puts "\t\t $ppk"
2439   #puts "\t 5 [lindex [wokparam -e  %CMPLRS_C_Options [wokcd]] 0]"
2440   set CCOMMON [_get_options lin cmplrs_c b]
2441   #puts "\t 6 [lindex [wokparam -v %CMPLRS_C_Options [w_info -f]] 0]"
2442   set FoundFlag "[lindex [osutils:intersect3 [split [_get_options lin cmplrs_c f]] [split [_get_options lin cmplrs_c b]]] 2]"
2443   foreach pk $ppk {
2444     if {![file isdirectory $path/src/$pk]} {
2445           continue
2446         }
2447         set src_files [_get_used_files $pk false]
2448     set only_src_files {}
2449     foreach s $src_files {
2450       regexp {source ([^\s]+)} $s dummy name
2451       lappend only_src_files $name
2452     }
2453     if {[lsearch $src_files ${pk}_CMPLRS.edl] != "-1"} {
2454           #puts "\t 7 [lindex [wokparam -e %CMPLRS_C_Options [woklocate -u $pk]] 0] $pk"
2455       set aPkList   [split "[_get_options lin cmplrs_c $pk]" " "]
2456       set aCcomList [split "$CCOMMON" " "]
2457
2458       foreach aPkItem $aPkList {
2459         if { [lsearch aCcomList $aPkItem] != -1 } {
2460           if {[string first "-I" $aPkItem] == "-1"  } {
2461             set FoundFlag "$FoundFlag $aPkItem"
2462           }
2463         }
2464       }
2465     }
2466   }
2467   return $FoundFlag
2468 }
2469
2470 proc osutils:tksrcfiles { theUnits  theRelatedPath {theCompatible {}} } {
2471   set aTKSrcFiles [list]
2472
2473   if [array exists written] { unset written }
2474   foreach anUnit $theUnits {
2475     set xlo       $anUnit
2476     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
2477
2478     if { $theCompatible != {} } {
2479       set aSrcFiles [osutils:tk:files $xlo $theCompatible 0]
2480     }
2481
2482     foreach aSrcFile [lsort $aSrcFiles] {
2483       if { ![info exists written([file tail $aSrcFile])] } {
2484         set written([file tail $aSrcFile]) 1
2485         lappend aTKSrcFiles "${theRelatedPath}/[wokUtils:FILES:wtail $aSrcFile 3]"
2486       } else {
2487         puts "Warning : more than one occurences for [file tail $aSrcFile]"
2488       }
2489     }
2490   }
2491
2492   return $aTKSrcFiles
2493 }
2494
2495 proc osutils:mm_compilable { } {
2496   return [list .mm]
2497 }
2498
2499 proc osutils:tkdefs { theUnits } {
2500   set aTKDefines [list]
2501
2502   foreach anUnit $theUnits {
2503     lappend aTKDefines "__${anUnit}_DLL"
2504   }
2505
2506   return $aTKDefines
2507 }
2508
2509 proc osutils:fileGroupName { theSrcFile } {
2510   set path [file dirname [file normalize ${theSrcFile}]]
2511   regsub -all [file normalize "${path}/.."] ${path} "" aGroupName
2512
2513   return $aGroupName
2514 }
2515
2516
2517 ####### CODEBLOCK ###################################################################
2518 # Function to generate Code Blocks workspace and project files
2519 proc OS:MKCBP { theOutDir {theModules {}} {theAllSolution ""} } {
2520   puts stderr "Generating project files for Code Blocks"
2521
2522   # Generate projects for toolkits and separate workspace for each module
2523   foreach aModule $theModules {
2524     OS:cworkspace $aModule $aModule $theOutDir
2525     OS:cbp        $aModule          $theOutDir
2526   }
2527
2528   # Generate single workspace "OCCT" containing projects from all modules
2529   if { "$theAllSolution" != "" } {
2530     OS:cworkspace $theAllSolution $theModules $theOutDir
2531   }
2532
2533   puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
2534 }
2535
2536 # Generate Code Blocks projects
2537 proc OS:cbp { theModules theOutDir } {
2538   set aProjectFiles {}
2539   foreach aModule $theModules {
2540     foreach aToolKit [${aModule}:toolkits] {
2541       lappend aProjectFiles [osutils:cbptk $theOutDir $aToolKit ]
2542     }
2543     foreach anExecutable [OS:executable ${aModule}] {
2544       lappend aProjectFiles [osutils:cbpx  $theOutDir $anExecutable]
2545     }
2546   }
2547   return $aProjectFiles
2548 }
2549
2550 # Generate Code::Blocks project file for ToolKit
2551 proc osutils:cbptk { theOutDir theToolKit } {
2552   set aUsedToolKits [list]
2553   set aFrameworks   [list]
2554   set anIncPaths    [list]
2555   set aTKDefines    [list]
2556   set aTKSrcFiles   [list]
2557
2558   osutils:tkinfo "../../.." $theToolKit aUsedToolKits aFrameworks anIncPaths aTKDefines aTKSrcFiles
2559
2560   return [osutils:cbp $theOutDir $theToolKit $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines]
2561 }
2562
2563 # Generates Code Blocks workspace.
2564 proc OS:cworkspace { theSolName theModules theOutDir } {
2565   global path
2566   set aWsFilePath "${theOutDir}/${theSolName}.workspace"
2567   set aFile [open $aWsFilePath "w"]
2568   set isActiveSet 0
2569   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2570   puts $aFile "<CodeBlocks_workspace_file>"
2571   puts $aFile "\t<Workspace title=\"${theSolName}\">"
2572
2573   # collect list of projects to be created
2574   foreach aModule $theModules {
2575     # toolkits
2576     foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
2577       set aDependencies [LibToLink $aToolKit]
2578       if { [llength $aDependencies] == 0 } {
2579         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
2580       } else {
2581         puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
2582         foreach aDepTk $aDependencies {
2583           puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2584         }
2585         puts $aFile "\t\t</Project>"
2586       }
2587     }
2588
2589     # executables, assume one project per cxx file...
2590     foreach aUnit [OS:executable ${aModule}] {
2591       set aUnitLoc $aUnit
2592       set src_files [_get_used_files $aUnit false]
2593       set aSrcFiles {}
2594       foreach s $src_files { 
2595         regexp {source ([^\s]+)} $s dummy name
2596         lappend aSrcFiles $name
2597       }
2598       foreach aSrcFile $aSrcFiles {
2599         set aFileExtension [file extension $aSrcFile]
2600         if { $aFileExtension == ".cxx" } {
2601           set aPrjName [file rootname $aSrcFile]
2602           set aDependencies [list]
2603           if {[file isdirectory $path/src/$aUnitLoc]} {
2604             set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
2605           }
2606           set anActiveState ""
2607           if { $isActiveSet == 0 } {
2608             set anActiveState " active=\"1\""
2609             set isActiveSet 1
2610           }
2611           if { [llength $aDependencies] == 0 } {
2612             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
2613           } else {
2614             puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
2615             foreach aDepTk $aDependencies {
2616               puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2617             }
2618             puts $aFile "\t\t</Project>"
2619           }
2620         }
2621       }
2622     }
2623   }
2624
2625   puts $aFile "\t</Workspace>"
2626   puts $aFile "</CodeBlocks_workspace_file>"
2627   close $aFile
2628
2629   return $aWsFilePath
2630 }
2631
2632 # Generate Code::Blocks project file for Executable
2633 proc osutils:cbpx { theOutDir theToolKit } {
2634   global path targetStation
2635   set aWokStation "$targetStation"
2636   set aWokArch    "$::env(ARCH)"
2637
2638   set aCbpFiles {}
2639   foreach aSrcFile [osutils:tk:files $theToolKit osutils:compilable 0] {
2640     # collect list of referred libraries to link with
2641     set aUsedToolKits [list]
2642     set aFrameworks   [list]
2643     set anIncPaths    [list]
2644     set aTKDefines    [list]
2645     set aTKSrcFiles   [list]
2646     set aProjName [file rootname [file tail $aSrcFile]]
2647
2648     set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2649     foreach tkx $aDepToolkits {
2650       if {[_get_type $tkx] == "t"} {
2651         lappend aUsedToolKits "${tkx}"
2652       }
2653       if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
2654         lappend aUsedToolKits "${tkx}"
2655       }
2656     }
2657
2658     #wokparam -l CSF
2659
2660     foreach tk $aDepToolkits {
2661       foreach element [osutils:tk:hascsf $path/src/${tk}/EXTERNLIB] {
2662         if {[_get_options lin csf $element] == ""} {
2663           continue
2664         }
2665         set isFrameworkNext 0
2666         foreach fl [split [_get_options lin csf $element]] {
2667           if {[string first "-libpath" $fl] != "-1"} {
2668             # this is library search path, not the library name
2669             continue
2670           } elseif {[string first "-framework" $fl] != "-1"} {
2671             set isFrameworkNext 1
2672             continue
2673           }
2674
2675           set felem [file tail $fl]
2676           if {$isFrameworkNext == 1} {
2677             if {[lsearch $aFrameworks $felem] == "-1"} {
2678               lappend aFrameworks "${felem}"
2679             }
2680             set isFrameworkNext 0
2681           } elseif {[lsearch $aUsedToolKits $felem] == "-1"} {
2682             if {$felem != "\{\}" & $felem != "lib"} {
2683               if {[lsearch -nocase [osutils:optinal_libs] $felem] == -1} {
2684                 lappend aUsedToolKits [string trimleft "${felem}" "-l"]
2685               }
2686             }
2687           }
2688         }
2689       }
2690     }
2691
2692     set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
2693     if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
2694       set isExecutable "false"
2695     } else {
2696       set isExecutable "true"
2697     }
2698
2699     if { ![info exists written([file tail $aSrcFile])] } {
2700       set written([file tail $aSrcFile]) 1
2701       lappend aTKSrcFiles $aSrcFile
2702     } else {
2703       puts "Warning : in cbp there are more than one occurences for [file tail $aSrcFile]"
2704     }
2705
2706     # macros for correct DLL exports
2707     if { "$aWokStation" == "wnt" } {
2708       lappend aTKDefines "__${theToolKit}_DLL"
2709     }
2710
2711     # common include paths
2712     lappend anIncPaths "../../../inc"
2713
2714     # macros for UNIX to use config.h file
2715     lappend aTKDefines "CSFDB"
2716     if { "$aWokStation" == "wnt" } {
2717       lappend aTKDefines "WNT"
2718       lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
2719     } else {
2720       lappend aTKDefines "HAVE_WOK_CONFIG_H"
2721       lappend aTKDefines "HAVE_CONFIG_H"
2722       if { "$aWokStation" == "lin" } {
2723         lappend aTKDefines "LIN"
2724       }
2725       lappend aTKDefines "OCC_CONVERT_SIGNALS"
2726       #lappend aTKDefines "_GNU_SOURCE=1"
2727     }
2728
2729     lappend aCbpFiles [osutils:cbp $theOutDir $aProjName $aTKSrcFiles $aUsedToolKits $aFrameworks $anIncPaths $aTKDefines $isExecutable]
2730   }
2731
2732   return $aCbpFiles
2733 }
2734
2735 proc osutils:optinal_libs { } {
2736   return [list tbb.lib tbbmalloc.lib FreeImage.lib FreeImagePlus.lib gl2ps.lib]
2737 }
2738
2739 # This function intended to generate Code::Blocks project file
2740 # @param theOutDir     - output directory to place project file
2741 # @param theProjName   - project name
2742 # @param theSrcFiles   - list of source files
2743 # @param theLibsList   - dependencies (libraries  list)
2744 # @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2745 # @param theIncPaths   - header search paths
2746 # @param theDefines    - compiler macro definitions
2747 # @param theIsExe      - flag to indicate executable / library target
2748 proc osutils:cbp { theOutDir theProjName theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2749   global targetStation
2750   set aWokStation "$targetStation"
2751   set aWokArch    "$::env(ARCH)"
2752
2753   set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2754   set aFile [open $aCbpFilePath "w"]
2755   puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2756   puts $aFile "<CodeBlocks_project_file>"
2757   puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2758   puts $aFile "\t<Project>"
2759   puts $aFile "\t\t<Option title=\"$theProjName\" />"
2760   puts $aFile "\t\t<Option pch_mode=\"2\" />"
2761   if { "$aWokStation" == "wnt" } {
2762     puts $aFile "\t\t<Option compiler=\"msvc8\" />"
2763   } else {
2764     puts $aFile "\t\t<Option compiler=\"gcc\" />"
2765   }
2766   puts $aFile "\t\t<Build>"
2767
2768   # Release target configuration
2769   puts $aFile "\t\t\t<Target title=\"Release\">"
2770   if { "$theIsExe" == "true" } {
2771     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2772     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2773   } else {
2774     if { "$aWokStation" == "wnt" } {
2775       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2776     } else {
2777       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2778     }
2779     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2780   }
2781   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
2782   if { "$aWokStation" == "wnt" } {
2783     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2784   } else {
2785     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2786   }
2787   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2788   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2789
2790   # compiler options per TARGET (including defines)
2791   puts $aFile "\t\t\t\t<Compiler>"
2792   if { "$aWokStation" == "wnt" } {
2793     puts $aFile "\t\t\t\t\t<Add option=\"-MD\" />"
2794     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2795     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2796     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2797     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2798     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2799   } else {
2800     puts $aFile "\t\t\t\t\t<Add option=\"-O2\" />"
2801     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2802     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2803     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2804     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2805   }
2806   foreach aMacro $theDefines {
2807     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2808   }
2809   puts $aFile "\t\t\t\t\t<Add option=\"-DNDEBUG\" />"
2810   puts $aFile "\t\t\t\t\t<Add option=\"-DNo_Exception\" />"
2811
2812   puts $aFile "\t\t\t\t</Compiler>"
2813
2814   puts $aFile "\t\t\t\t<Linker>"
2815   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
2816   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2817     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2818   }
2819   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
2820   puts $aFile "\t\t\t\t</Linker>"
2821
2822   puts $aFile "\t\t\t</Target>"
2823
2824   # Debug target configuration
2825   puts $aFile "\t\t\t<Target title=\"Debug\">"
2826   if { "$theIsExe" == "true" } {
2827     puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2828     puts $aFile "\t\t\t\t<Option type=\"1\" />"
2829   } else {
2830     if { "$aWokStation" == "wnt" } {
2831       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2832     } else {
2833       puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}\" prefix_auto=\"1\" extension_auto=\"1\" />"
2834     }
2835     puts $aFile "\t\t\t\t<Option type=\"3\" />"
2836   }
2837   puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
2838   if { "$aWokStation" == "wnt" } {
2839     puts $aFile "\t\t\t\t<Option compiler=\"msvc8\" />"
2840   } else {
2841     puts $aFile "\t\t\t\t<Option compiler=\"gcc\" />"
2842   }
2843   puts $aFile "\t\t\t\t<Option createDefFile=\"1\" />"
2844   puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2845
2846   # compiler options per TARGET (including defines)
2847   puts $aFile "\t\t\t\t<Compiler>"
2848   if { "$aWokStation" == "wnt" } {
2849     puts $aFile "\t\t\t\t\t<Add option=\"-MDd\" />"
2850     puts $aFile "\t\t\t\t\t<Add option=\"-arch:SSE2\" />"
2851     puts $aFile "\t\t\t\t\t<Add option=\"-EHsc\" />"
2852     puts $aFile "\t\t\t\t\t<Add option=\"-Od\" />"
2853     puts $aFile "\t\t\t\t\t<Add option=\"-Zi\" />"
2854     puts $aFile "\t\t\t\t\t<Add option=\"-W4\" />"
2855     puts $aFile "\t\t\t\t\t<Add option=\"-MP\" />"
2856   } else {
2857     puts $aFile "\t\t\t\t\t<Add option=\"-O0\" />"
2858     puts $aFile "\t\t\t\t\t<Add option=\"-g\" />"
2859     puts $aFile "\t\t\t\t\t<Add option=\"-mmmx\" />"
2860     puts $aFile "\t\t\t\t\t<Add option=\"-msse\" />"
2861     puts $aFile "\t\t\t\t\t<Add option=\"-msse2\" />"
2862     puts $aFile "\t\t\t\t\t<Add option=\"-mfpmath=sse\" />"
2863   }
2864   foreach aMacro $theDefines {
2865     puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2866   }
2867   puts $aFile "\t\t\t\t\t<Add option=\"-D_DEBUG\" />"
2868   puts $aFile "\t\t\t\t\t<Add option=\"-DDEB\" />"
2869   puts $aFile "\t\t\t\t</Compiler>"
2870
2871   puts $aFile "\t\t\t\t<Linker>"
2872   puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
2873   if { "$aWokStation" == "mac" && [ lsearch $theLibsList X11 ] >= 0} {
2874     puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2875   }
2876   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
2877   puts $aFile "\t\t\t\t</Linker>"
2878
2879   puts $aFile "\t\t\t</Target>"
2880
2881   puts $aFile "\t\t</Build>"
2882
2883   # COMMON compiler options
2884   puts $aFile "\t\t<Compiler>"
2885   puts $aFile "\t\t\t<Add option=\"-Wall\" />"
2886   puts $aFile "\t\t\t<Add option=\"-fexceptions\" />"
2887   puts $aFile "\t\t\t<Add option=\"-fPIC\" />"
2888   puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2889   foreach anIncPath $theIncPaths {
2890     puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2891   }
2892   puts $aFile "\t\t</Compiler>"
2893
2894   # COMMON linker options
2895   puts $aFile "\t\t<Linker>"
2896   foreach aFrameworkName $theFrameworks {
2897     if { "$aFrameworkName" != "" } {
2898       puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2899     }
2900   }
2901   foreach aLibName $theLibsList {
2902     if { "$aLibName" != "" } {
2903       puts $aFile "\t\t\t<Add library=\"$aLibName\" />"
2904     }
2905   }
2906   puts $aFile "\t\t</Linker>"
2907
2908   # list of sources
2909   foreach aSrcFile $theSrcFiles {
2910     if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2911       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2912       puts $aFile "\t\t\t<Option compile=\"1\" />"
2913       puts $aFile "\t\t\t<Option link=\"1\" />"
2914       puts $aFile "\t\t</Unit>"
2915     } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2916       puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2917       puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2918       puts $aFile "\t\t</Unit>"
2919     } else {
2920       puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
2921     }
2922   }
2923
2924   puts $aFile "\t</Project>"
2925   puts $aFile "</CodeBlocks_project_file>"
2926   close $aFile
2927
2928   return $aCbpFilePath
2929 }
2930
2931 # Auxiliary function to achieve complete information to build Toolkit
2932 # @param theRelativePath - relative path to CASROOT
2933 # @param theToolKit      - Toolkit name
2934 # @param theUsedLib      - dependencies (libraries  list)
2935 # @param theFrameworks   - dependencies (frameworks list, Mac OS X specific)
2936 # @param theIncPaths     - header search paths
2937 # @param theTKDefines    - compiler macro definitions
2938 # @param theTKSrcFiles   - list of source files
2939 proc osutils:tkinfo { theRelativePath theToolKit theUsedLib theFrameworks theIncPaths theTKDefines theTKSrcFiles } {
2940   global path targetStation
2941   set aWokStation "$targetStation"
2942
2943   # collect list of referred libraries to link with
2944   upvar $theUsedLib    aUsedLibs
2945   upvar $theFrameworks aFrameworks
2946   upvar $theIncPaths   anIncPaths
2947   upvar $theTKDefines  aTKDefines
2948   upvar $theTKSrcFiles aTKSrcFiles
2949
2950   set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2951   foreach tkx $aDepToolkits {
2952     lappend aUsedLibs "${tkx}"
2953   }
2954
2955  # wokparam -l CSF
2956
2957   foreach tk [lappend aDepToolkits $theToolKit] {
2958     foreach element [osutils:tk:hascsf $path/src/${tk}/EXTERNLIB] {
2959       if {[_get_options lin csf $element] == ""} {
2960         continue
2961       }
2962       set isFrameworkNext 0
2963       foreach fl [split [_get_options lin csf $element]] {
2964         if {[string first "-libpath" $fl] != "-1"} {
2965           # this is library search path, not the library name
2966           continue
2967         } elseif {[string first "-framework" $fl] != "-1"} {
2968           set isFrameworkNext 1
2969           continue
2970         }
2971
2972         set felem [file tail $fl]
2973         if {$isFrameworkNext == 1} {
2974           if {[lsearch $aFrameworks $felem] == "-1"} {
2975             lappend aFrameworks "${felem}"
2976           }
2977           set isFrameworkNext 0
2978         } elseif {[lsearch $aUsedLibs $felem] == "-1"} {
2979           if {$felem != "\{\}" & $felem != "lib"} {
2980             if {[lsearch -nocase [osutils:optinal_libs] $felem] == -1} {
2981               lappend aUsedLibs [string trimleft "${felem}" "-l"]
2982             }
2983           }
2984         }
2985       }
2986     }
2987   }
2988
2989   lappend anIncPaths "$theRelativePath/inc"
2990   set listloc [osutils:tk:units $theToolKit]
2991
2992   if { [llength $listloc] == 0 } {
2993     set listloc $theToolKit
2994   }
2995
2996   if { "$aWokStation" == "wnt" } {
2997     set resultloc [osutils:justwnt  $listloc]
2998   } else {
2999     set resultloc [osutils:justunix $listloc]
3000   }
3001   if [array exists written] { unset written }
3002   foreach fxlo $resultloc {
3003     set xlo       $fxlo
3004     set aSrcFiles [osutils:tk:files $xlo osutils:compilable 0]
3005     foreach aSrcFile [lsort $aSrcFiles] {
3006       if { ![info exists written([file tail $aSrcFile])] } {
3007         set written([file tail $aSrcFile]) 1
3008         lappend aTKSrcFiles "${theRelativePath}/[wokUtils:FILES:wtail $aSrcFile 3]"
3009       } else {
3010         puts "Warning : more than one occurences for [file tail $aSrcFile]"
3011       }
3012     }
3013
3014     # macros for correct DLL exports
3015     if { "$aWokStation" == "wnt" } {
3016       lappend aTKDefines "__${xlo}_DLL"
3017     }
3018
3019     # common include paths
3020 #    lappend anIncPaths "${theRelativePath}/src/${xlo}"
3021   }
3022
3023   # macros for UNIX to use config.h file
3024   lappend aTKDefines "CSFDB"
3025   if { "$aWokStation" == "wnt" } {
3026     lappend aTKDefines "WNT"
3027     lappend aTKDefines "_CRT_SECURE_NO_DEPRECATE"
3028   } else {
3029     lappend aTKDefines "HAVE_WOK_CONFIG_H"
3030     lappend aTKDefines "HAVE_CONFIG_H"
3031     if { "$aWokStation" == "lin" } {
3032       lappend aTKDefines "LIN"
3033     }
3034     lappend aTKDefines "OCC_CONVERT_SIGNALS"
3035     #lappend aTKDefines "_GNU_SOURCE=1"
3036   }
3037 }
3038
3039 # Define libraries to link using only EXTERNLIB file
3040 proc LibToLinkX {thePackage theDummyName} {
3041   set aToolKits [LibToLink $thePackage]
3042   return $aToolKits
3043 }
3044
3045 # launch generation
3046 genproj {*}$::argv