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