Corrections for MacOS genproj.tcl (branch CR26866)
[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
5da3dfdf 819 set allHeaderFiles {}
5951a088 820 if { $aCopyType == "shortcut" } {
910970ab 821 # template preparation
e31a8e52 822 if { ![file exists $::THE_CASROOT/adm/templates/header.in] } {
823 puts "template file does not exist: $::THE_CASROOT/adm/templates/header.in"
910970ab 824 return
825 }
e31a8e52 826 set aHeaderTmpl [wokUtils:FILES:FileToString $::THE_CASROOT/adm/templates/header.in]
910970ab 827
828 # relative anIncPath in connection with aCasRoot/src
829 set aFromBuildIncToSrcPath [relativePath "$anIncPath" "$aCasRoot/src"]
830
831 # create and copy short-cut header files
832 foreach anUnit $anUnits {
5da3dfdf 833 osutils:checksrcfiles ${anUnit}
834
835 set aHFiles [_get_used_files ${anUnit} true false]
836 foreach aHeaderFile ${aHFiles} {
837 set aHeaderFileName [lindex ${aHeaderFile} 1]
838 lappend allHeaderFiles "${aHeaderFileName}"
910970ab 839
ee5befae 840 regsub -all -- {@OCCT_HEADER_FILE_CONTENT@} $aHeaderTmpl "#include \"$aFromBuildIncToSrcPath/$anUnit/$aHeaderFileName\"" aShortCutHeaderFileContent
910970ab 841
842 if {[file exists "$theIncPath/$aHeaderFileName"] && [file readable "$theIncPath/$aHeaderFileName"]} {
843 set fp [open "$theIncPath/$aHeaderFileName" r]
844 set aHeaderContent [read $fp]
845 close $fp
846
847 # minus eof
848 set aHeaderLenght [expr [string length $aHeaderContent] - 1]
849
850 if {$aHeaderLenght == [string length $aShortCutHeaderFileContent]} {
851 # remove eof from string
852 set aHeaderContent [string range $aHeaderContent 0 [expr $aHeaderLenght - 1]]
853
854 if {[string compare $aShortCutHeaderFileContent $aHeaderContent] == 0} {
855 continue
856 }
857 }
5951a088 858 file delete -force "$theIncPath/$aHeaderFileName"
910970ab 859 }
860
861 set aShortCutHeaderFile [open "$theIncPath/$aHeaderFileName" "w"]
862 fconfigure $aShortCutHeaderFile -translation lf
863 puts $aShortCutHeaderFile $aShortCutHeaderFileContent
864 close $aShortCutHeaderFile
865 }
5951a088 866 }
910970ab 867 } else {
868 set nbcopied 0
869 foreach anUnit $anUnits {
5da3dfdf 870 osutils:checksrcfiles ${anUnit}
871
872 set aHFiles [_get_used_files ${anUnit} true false]
873 foreach aHeaderFile ${aHFiles} {
874 set aHeaderFileName [lindex ${aHeaderFile} 1]
875 lappend allHeaderFiles "${aHeaderFileName}"
910970ab 876
877 # copy file only if target does not exist or is older than original
0fdbd10b 878 set torig [file mtime $aCasRoot/src/$anUnit/$aHeaderFileName]
5951a088 879 set tcopy 0
880 if { [file isfile $anIncPath/$aHeaderFileName] } {
910970ab 881 set tcopy [file mtime $anIncPath/$aHeaderFileName]
882 }
883 if { $tcopy < $torig } {
884 incr nbcopied
5951a088 885 if { $aCopyType == "hardlink" } {
886 if { $tcopy != 0 } {
887 file delete -force "$theIncPath/$aHeaderFileName"
888 }
0fdbd10b 889 file link -hard $anIncPath/$aHeaderFileName $aCasRoot/src/$anUnit/$aHeaderFileName
5951a088 890 } else {
0fdbd10b 891 file copy -force $aCasRoot/src/$anUnit/$aHeaderFileName $anIncPath/$aHeaderFileName
5951a088 892 }
910970ab 893 } elseif { $tcopy != $torig } {
0fdbd10b 894 puts "Warning: file $anIncPath/$aHeaderFileName is newer than $aCasRoot/src/$anUnit/$aHeaderFileName, not changed!"
910970ab 895 }
896 }
897 }
898 puts "Info: $nbcopied files updated"
899 }
5da3dfdf 900
901 # remove header files not listed in FILES
902 set anIncFiles [glob -tails -nocomplain -dir ${anIncPath} "*"]
903 foreach anIncFile ${anIncFiles} {
904 if { [lsearch -exact ${allHeaderFiles} ${anIncFile}] == -1 } {
905 puts "Warning: file ${anIncPath}/${anIncFile} is not presented in the sources and will be removed from ${theIncPath}!"
906 file delete -force "${theIncPath}/${anIncFile}"
907 }
908 }
910970ab 909}
910
911# Generate header for VS solution file
912proc osutils:vcsolution:header { vcversion } {
913 if { "$vcversion" == "vc7" } {
914 append var \
915 "Microsoft Visual Studio Solution File, Format Version 8.00\n"
916 } elseif { "$vcversion" == "vc8" } {
917 append var \
918 "Microsoft Visual Studio Solution File, Format Version 9.00\n" \
919 "# Visual Studio 2005\n"
920 } elseif { "$vcversion" == "vc9" } {
921 append var \
922 "Microsoft Visual Studio Solution File, Format Version 10.00\n" \
923 "# Visual Studio 2008\n"
924 } elseif { "$vcversion" == "vc10" } {
925 append var \
926 "Microsoft Visual Studio Solution File, Format Version 11.00\n" \
927 "# Visual Studio 2010\n"
928 } elseif { "$vcversion" == "vc11" } {
929 append var \
930 "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
931 "# Visual Studio 2012\n"
932 } elseif { "$vcversion" == "vc12" } {
933 append var \
934 "Microsoft Visual Studio Solution File, Format Version 13.00\n" \
935 "# Visual Studio 2013\n"
7fbac3c2 936 } elseif { "$vcversion" == "vc14" || "$vcversion" == "vc14-uwp"} {
39bff09c 937 append var \
938 "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
939 "# Visual Studio 14\n"
910970ab 940 } else {
941 puts stderr "Error: Visual Studio version $vcversion is not supported by this function!"
942 }
943 return $var
944}
945# Returns extension (without dot) for project files of given version of VC
946
947proc osutils:vcproj:ext { vcversion } {
948 if { "$vcversion" == "vc7" || "$vcversion" == "vc8" || "$vcversion" == "vc9" } {
949 return "vcproj"
910970ab 950 } else {
39bff09c 951 return "vcxproj"
910970ab 952 }
953}
954# Generate start of configuration section of VS solution file
955
956proc osutils:vcsolution:config:begin { vcversion } {
957 if { "$vcversion" == "vc7" } {
958 append var \
959 "Global\n" \
960 "\tGlobalSection(SolutionConfiguration) = preSolution\n" \
961 "\t\tDebug = Debug\n" \
962 "\t\tRelease = Release\n" \
963 "\tEndGlobalSection\n" \
964 "\tGlobalSection(ProjectConfiguration) = postSolution\n"
39bff09c 965 } else {
910970ab 966 append var \
967 "Global\n" \
968 "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" \
969 "\t\tDebug|Win32 = Debug|Win32\n" \
970 "\t\tRelease|Win32 = Release|Win32\n" \
971 "\t\tDebug|x64 = Debug|x64\n" \
972 "\t\tRelease|x64 = Release|x64\n" \
973 "\tEndGlobalSection\n" \
974 "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"
910970ab 975 }
976 return $var
977}
978# Generate part of configuration section of VS solution file describing one project
979
980proc osutils:vcsolution:config:project { vcversion guid } {
981 if { "$vcversion" == "vc7" } {
982 append var \
983 "\t\t$guid.Debug.ActiveCfg = Debug|Win32\n" \
984 "\t\t$guid.Debug.Build.0 = Debug|Win32\n" \
985 "\t\t$guid.Release.ActiveCfg = Release|Win32\n" \
986 "\t\t$guid.Release.Build.0 = Release|Win32\n"
39bff09c 987 } else {
910970ab 988 append var \
989 "\t\t$guid.Debug|Win32.ActiveCfg = Debug|Win32\n" \
990 "\t\t$guid.Debug|Win32.Build.0 = Debug|Win32\n" \
991 "\t\t$guid.Release|Win32.ActiveCfg = Release|Win32\n" \
992 "\t\t$guid.Release|Win32.Build.0 = Release|Win32\n" \
993 "\t\t$guid.Debug|x64.ActiveCfg = Debug|x64\n" \
994 "\t\t$guid.Debug|x64.Build.0 = Debug|x64\n" \
995 "\t\t$guid.Release|x64.ActiveCfg = Release|x64\n" \
996 "\t\t$guid.Release|x64.Build.0 = Release|x64\n"
910970ab 997 }
998 return $var
999}
1000# Generate start of configuration section of VS solution file
1001
1002proc osutils:vcsolution:config:end { vcversion } {
1003 if { "$vcversion" == "vc7" } {
1004 append var \
1005 "\tEndGlobalSection\n" \
1006 "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" \
1007 "\tEndGlobalSection\n" \
1008 "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" \
1009 "\tEndGlobalSection\n"
39bff09c 1010 } else {
910970ab 1011 append var \
1012 "\tEndGlobalSection\n" \
1013 "\tGlobalSection(SolutionProperties) = preSolution\n" \
1014 "\t\tHideSolutionNode = FALSE\n" \
1015 "\tEndGlobalSection\n"
910970ab 1016 }
1017 return $var
1018}
1019# generate Visual Studio solution file
1020# if module is empty, generates one solution for all known modules
1021
1022proc OS:vcsolution { theVcVer theSolName theModules theOutDir theGuidsMap } {
1023 global path
1024 upvar $theGuidsMap aGuidsMap
1025
1026 # collect list of projects to be created
1027 set aProjects {}
1028 set aDependencies {}
1029 foreach aModule $theModules {
1030 # toolkits
1031 foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
1032 lappend aProjects $aToolKit
1033 lappend aProjectsInModule($aModule) $aToolKit
1034 lappend aDependencies [LibToLink $aToolKit]
1035 }
1036 # executables, assume one project per cxx file...
1037 foreach aUnit [OS:executable ${aModule}] {
1038 set aUnitLoc $aUnit
1039 set src_files [_get_used_files $aUnit false]
1040 set aSrcFiles {}
1041 foreach s $src_files {
1042 regexp {source ([^\s]+)} $s dummy name
1043 lappend aSrcFiles $name
1044 }
1045 foreach aSrcFile $aSrcFiles {
1046 set aFileExtension [file extension $aSrcFile]
1047 if { $aFileExtension == ".cxx" } {
1048 set aPrjName [file rootname $aSrcFile]
1049 lappend aProjects $aPrjName
1050 lappend aProjectsInModule($aModule) $aPrjName
1051 if {[file isdirectory $path/src/$aUnitLoc]} {
1052 lappend aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
1053 } else {
1054 lappend aDependencies {}
1055 }
1056 }
1057 }
1058 }
1059 }
1060
1061# generate GUIDs for projects (unless already known)
1062 foreach aProject $aProjects {
1063 if { ! [info exists aGuidsMap($aProject)] } {
1064 set aGuidsMap($aProject) [OS:genGUID]
1065 }
1066 }
1067
1068 # generate solution file
1069# puts "Generating Visual Studio ($theVcVer) solution file for $theSolName ($aProjects)"
1070 append aFileBuff [osutils:vcsolution:header $theVcVer]
1071
1072 # GUID identifying group projects in Visual Studio
1073 set VC_GROUP_GUID "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"
1074
1075 # generate group projects -- one per module
1076 if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
1077 foreach aModule $theModules {
1078 if { ! [info exists aGuidsMap(_$aModule)] } {
1079 set aGuidsMap(_$aModule) [OS:genGUID]
1080 }
1081 set aGuid $aGuidsMap(_$aModule)
1082 append aFileBuff "Project(\"${VC_GROUP_GUID}\") = \"$aModule\", \"$aModule\", \"$aGuid\"\nEndProject\n"
1083 }
1084 }
1085
1086 # extension of project files
1087 set aProjExt [osutils:vcproj:ext $theVcVer]
1088
1089 # GUID identifying C++ projects in Visual Studio
1090 set VC_CPP_GUID "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
1091
1092 # generate normal projects
1093 set aProjsNb [llength $aProjects]
1094 for {set aProjId 0} {$aProjId < $aProjsNb} {incr aProjId} {
1095 set aProj [lindex $aProjects $aProjId]
1096 set aGuid $aGuidsMap($aProj)
1097 append aFileBuff "Project(\"${VC_CPP_GUID}\") = \"$aProj\", \"$aProj.${aProjExt}\", \"$aGuid\"\n"
1098 # write projects dependencies information (vc7 to vc9)
1099 set aDepGuids ""
1100 foreach aDepLib [lindex $aDependencies $aProjId] {
1101 if { $aDepLib != $aProj && [lsearch $aProjects $aDepLib] != "-1" } {
1102 set depGUID $aGuidsMap($aDepLib)
1103 append aDepGuids "\t\t$depGUID = $depGUID\n"
1104 }
1105 }
1106 if { "$aDepGuids" != "" } {
1107 append aFileBuff "\tProjectSection(ProjectDependencies) = postProject\n"
1108 append aFileBuff "$aDepGuids"
1109 append aFileBuff "\tEndProjectSection\n"
1110 }
1111 append aFileBuff "EndProject\n"
1112 }
1113
1114 # generate configuration section
1115 append aFileBuff [osutils:vcsolution:config:begin $theVcVer]
1116 foreach aProj $aProjects {
1117 append aFileBuff [osutils:vcsolution:config:project $theVcVer $aGuidsMap($aProj)]
1118 }
1119 append aFileBuff [osutils:vcsolution:config:end $theVcVer]
1120
1121 # write information of grouping of projects by module
1122 if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
1123 append aFileBuff " GlobalSection(NestedProjects) = preSolution\n"
1124 foreach aModule $theModules {
1125 if { ! [info exists aProjectsInModule($aModule)] } { continue }
1126 foreach aProject $aProjectsInModule($aModule) {
1127 append aFileBuff " $aGuidsMap($aProject) = $aGuidsMap(_$aModule)\n"
1128 }
1129 }
1130 append aFileBuff " EndGlobalSection\n"
1131 }
1132
1133 # final word (footer)
1134 append aFileBuff "EndGlobal"
1135
1136 # write solution
1137 set aFile [open [set fdsw [file join $theOutDir ${theSolName}.sln]] w]
1138 fconfigure $aFile -translation crlf
1139 puts $aFile $aFileBuff
1140 close $aFile
1141 return [file join $theOutDir ${theSolName}.sln]
1142}
1143# Generate Visual Studio projects for specified version
1144
1145proc OS:vcproj { theVcVer theModules theOutDir theGuidsMap } {
1146 upvar $theGuidsMap aGuidsMap
1147
1148 set aProjectFiles {}
1149
1150 foreach aModule $theModules {
1151 foreach aToolKit [${aModule}:toolkits] {
1152 lappend aProjectFiles [osutils:vcproj $theVcVer $theOutDir $aToolKit aGuidsMap]
1153 }
1154 foreach anExecutable [OS:executable ${aModule}] {
1155 lappend aProjectFiles [osutils:vcprojx $theVcVer $theOutDir $anExecutable aGuidsMap]
1156 }
1157 }
1158 return $aProjectFiles
1159}
1160# generate template name and load it for given version of Visual Studio and platform
1161
39bff09c 1162proc osutils:vcproj:readtemplate {theVcVer isexec} {
1163 set anExt $theVcVer
1164 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1165 set anExt vc10
1166 }
1167
1168 set what "$theVcVer"
1169 set aVerExt [string range $theVcVer 2 end]
1170 set aVerExt "v${aVerExt}0"
1171 set aCmpl32 ""
1172 set aCmpl64 ""
ad03c234 1173 set aCharSet "Unicode"
910970ab 1174 if { $isexec } {
39bff09c 1175 set anExt "${anExt}x"
910970ab 1176 set what "$what executable"
1177 }
39bff09c 1178 if { "$theVcVer" == "vc10" } {
1179 # SSE2 is enabled by default in vc11+, but not in vc10 for 32-bit target
7fbac3c2 1180 set aCmpl32 "<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>"
39bff09c 1181 }
1182 set aTmpl [osutils:readtemplate $anExt "MS VC++ project ($what)"]
7fbac3c2 1183
1184 if { $theVcVer == "vc14-uwp" } {
1185 set aVerExt "v140"
1186 set UwpWinRt "<CompileAsWinRT>false</CompileAsWinRT>"
1187 foreach bitness {32 64} {
1188 set indent ""
1189 if {"[set aCmpl${bitness}]" != ""} {
1190 set indent "\n "
1191 }
1192 set aCmpl${bitness} "[set aCmpl${bitness}]${indent}${UwpWinRt}"
1193 }
7fbac3c2 1194 }
1195
1196 foreach bitness {32 64} {
1197 set format_template ""
1198 if {"[set aCmpl${bitness}]" == ""} {
1199 set format_template "\[\\r\\n\\s\]*"
1200 }
1201 regsub -all -- "${format_template}__VCMPL${bitness}__" $aTmpl "[set aCmpl${bitness}]" aTmpl
1202 }
1203
1204 regsub -all -- {__VCVER__} $aTmpl $theVcVer aTmpl
1205 regsub -all -- {__VCVEREXT__} $aTmpl $aVerExt aTmpl
1206 regsub -all -- {__VCCHARSET__} $aTmpl $aCharSet aTmpl
39bff09c 1207 return $aTmpl
910970ab 1208}
1209
1210proc osutils:readtemplate {ext what} {
e31a8e52 1211 set loc "$::THE_CASROOT/adm/templates/template.$ext"
910970ab 1212 return [wokUtils:FILES:FileToString $loc]
1213}
1214# Read a file in a string as is.
1215
1216proc wokUtils:FILES:FileToString { fin } {
1217 if { [catch { set in [ open $fin r ] } errin] == 0 } {
1218 set strin [read $in [file size $fin]]
1219 close $in
1220 return $strin
1221 } else {
1222 return {}
1223 }
1224}
910970ab 1225
944d808c 1226# List extensions of compilable files in OCCT
1227proc osutils:compilable {thePlatform} {
1228 if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } {
910970ab 1229 return [list .c .cxx .cpp .mm]
1230 }
1231 return [list .c .cxx .cpp]
1232}
1233
1234proc osutils:commonUsedTK { theToolKit } {
910970ab 1235 set anUsedToolKits [list]
1236 set aDepToolkits [LibToLink $theToolKit]
1237 foreach tkx $aDepToolkits {
1238 if {[_get_type $tkx] == "t"} {
1239 lappend anUsedToolKits "${tkx}"
1240 }
1241 }
1242 return $anUsedToolKits
1243}
910970ab 1244
c7d774c5 1245# Return the list of name *CSF_ in a EXTERNLIB description of a toolkit
1246proc osutils:tk:csfInExternlib { EXTERNLIB } {
910970ab 1247 set l [wokUtils:FILES:FileToList $EXTERNLIB]
1248 set lret {STLPort}
1249 foreach str $l {
1250 if [regexp -- {(CSF_[^ ]*)} $str csf] {
1251 lappend lret $csf
1252 }
1253 }
1254 return $lret
1255}
1256
7c65581d 1257# Collect dependencies map depending on target OS (libraries for CSF_ codenames used in EXTERNLIB) .
1258# @param theOS - target OS
c7d774c5 1259# @param theCsfLibsMap - libraries map
1260# @param theCsfFrmsMap - frameworks map, OS X specific
1261proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
1262 upvar $theCsfLibsMap aLibsMap
1263 upvar $theCsfFrmsMap aFrmsMap
910970ab 1264
c7d774c5 1265 unset theCsfLibsMap
1266 unset theCsfFrmsMap
910970ab 1267
7c65581d 1268 set aLibsMap(CSF_FREETYPE) "freetype"
1269 set aLibsMap(CSF_TclLibs) "tcl8.6"
1270 set aLibsMap(CSF_TclTkLibs) "tk8.6"
1271 if { "$::HAVE_FREEIMAGE" == "true" } {
1272 if { "$theOS" == "wnt" } {
60273f77 1273 set aLibsMap(CSF_FreeImagePlus) "FreeImage"
7c65581d 1274 } else {
1275 set aLibsMap(CSF_FreeImagePlus) "freeimage"
1276 }
1277 }
e22105a9 1278 if { "$::HAVE_FFMPEG" == "true" } {
1279 set aLibsMap(CSF_FFmpeg) "avcodec avformat swscale avutil"
1280 }
7c65581d 1281 if { "$::HAVE_GL2PS" == "true" } {
1282 set aLibsMap(CSF_GL2PS) "gl2ps"
1283 }
1284 if { "$::HAVE_TBB" == "true" } {
1285 set aLibsMap(CSF_TBB) "tbb tbbmalloc"
1286 }
1287 if { "$::HAVE_VTK" == "true" } {
1288 if { "$theOS" == "wnt" } {
1289 set aLibsMap(CSF_VTK) [osutils:vtkCsf "wnt"]
1290 } else {
1291 set aLibsMap(CSF_VTK) [osutils:vtkCsf "unix"]
1292 }
1293 }
e22105a9 1294 if { "$::HAVE_ZLIB" == "true" } {
1295 set aLibsMap(CSF_ZLIB) "zlib"
1296 }
1297 if { "$::HAVE_LIBLZMA" == "true" } {
1298 set aLibsMap(CSF_LIBLZMA) "liblzma"
1299 }
7c65581d 1300
910970ab 1301 if { "$theOS" == "wnt" } {
c7d774c5 1302 # WinAPI libraries
7c65581d 1303 set aLibsMap(CSF_kernel32) "kernel32"
1304 set aLibsMap(CSF_advapi32) "advapi32"
1305 set aLibsMap(CSF_gdi32) "gdi32"
1306 set aLibsMap(CSF_user32) "user32 comdlg32"
1307 set aLibsMap(CSF_opengl32) "opengl32"
1308 set aLibsMap(CSF_wsock32) "wsock32"
1309 set aLibsMap(CSF_netapi32) "netapi32"
7c65581d 1310 set aLibsMap(CSF_OpenGlLibs) "opengl32"
1ce0716b 1311 if { "$::HAVE_GLES2" == "true" } {
1312 set aLibsMap(CSF_OpenGlLibs) "libEGL libGLESv2"
1313 }
7c65581d 1314 set aLibsMap(CSF_psapi) "Psapi"
1315 set aLibsMap(CSF_d3d9) "d3d9"
1316
1317 # the naming is different on Windows
1318 set aLibsMap(CSF_TclLibs) "tcl86"
1319 set aLibsMap(CSF_TclTkLibs) "tk86"
1320
1321 set aLibsMap(CSF_QT) "QtCore4 QtGui4"
1322
1323 # tbb headers define different pragma lib depending on debug/release
1324 set aLibsMap(CSF_TBB) ""
910970ab 1325 } else {
c7d774c5 1326 if { "$theOS" == "mac" } {
1327 set aLibsMap(CSF_objc) "objc"
1328 set aFrmsMap(CSF_Appkit) "Appkit"
1329 set aFrmsMap(CSF_IOKit) "IOKit"
1330 set aFrmsMap(CSF_OpenGlLibs) "OpenGL"
1331 set aFrmsMap(CSF_TclLibs) "Tcl"
7c65581d 1332 set aLibsMap(CSF_TclLibs) ""
c7d774c5 1333 set aFrmsMap(CSF_TclTkLibs) "Tk"
7c65581d 1334 set aLibsMap(CSF_TclTkLibs) ""
c7d774c5 1335 } else {
d8d01f6e 1336 if { "$theOS" == "qnx" } {
7c65581d 1337 # CSF_ThreadLibs - pthread API is part of libc on QNX
d8d01f6e 1338 set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
d8d01f6e 1339 } else {
1340 set aLibsMap(CSF_ThreadLibs) "pthread rt"
1341 set aLibsMap(CSF_OpenGlLibs) "GL"
d8d01f6e 1342 set aLibsMap(CSF_TclTkLibs) "X11 tk8.6"
1343 set aLibsMap(CSF_XwLibs) "X11 Xext Xmu Xi"
1344 set aLibsMap(CSF_MotifLibs) "X11"
1345 }
1ce0716b 1346
1347 if { "$::HAVE_GLES2" == "true" } {
1348 set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
1349 }
910970ab 1350 }
910970ab 1351 }
1352}
1353
1c29294e 1354# Returns string of library dependencies for generation of Visual Studio project or make lists.
1355proc osutils:vtkCsf {{theOS ""}} {
1356 set aVtkVer "6.1"
1357
1c29294e 1358 set aPathSplitter ":"
1c29294e 1359 if {"$theOS" == "wnt"} {
1360 set aPathSplitter ";"
1c29294e 1361 }
1362
1363 set anOptIncs [split $::env(CSF_OPT_INC) "$aPathSplitter"]
1364 foreach anIncItem $anOptIncs {
1365 if {[regexp -- "vtk-(.*)$" [file tail $anIncItem] dummy aFoundVtkVer]} {
1366 set aVtkVer $aFoundVtkVer
1367 }
1368 }
1369
1370 set aLibArray [list vtkCommonCore vtkCommonDataModel vtkCommonExecutionModel vtkCommonMath vtkCommonTransforms vtkRenderingCore \
1371 vtkRenderingOpenGL vtkFiltersGeneral vtkIOCore vtkIOImage vtkImagingCore vtkInteractionStyle]
1372
1373 # Additional suffices for the libraries
1374 set anIdx 0
1375 foreach anItem $aLibArray {
7c65581d 1376 lset aLibArray $anIdx $anItem-$aVtkVer
1c29294e 1377 incr anIdx
1378 }
1379
1380 return [join $aLibArray " "]
1381}
1382
c7d774c5 1383# @param theLibsList - dependencies (libraries list)
1384# @param theFrameworks - dependencies (frameworks list, OS X specific)
1385proc osutils:usedOsLibs { theToolKit theOS theLibsList theFrameworks } {
910970ab 1386 global path
c7d774c5 1387 upvar $theLibsList aLibsList
1388 upvar $theFrameworks aFrameworks
1389 set aLibsList [list]
1390 set aFrameworks [list]
910970ab 1391
c7d774c5 1392 osutils:csfList $theOS aLibsMap aFrmsMap
910970ab 1393
c7d774c5 1394 foreach aCsfElem [osutils:tk:csfInExternlib "$path/src/${theToolKit}/EXTERNLIB"] {
1395 if [info exists aLibsMap($aCsfElem)] {
1396 foreach aLib [split "$aLibsMap($aCsfElem)"] {
1397 if { [lsearch $aLibsList $aLib] == "-1" } {
1398 lappend aLibsList $aLib
1399 }
1400 }
910970ab 1401 }
c7d774c5 1402 if [info exists aFrmsMap($aCsfElem)] {
1403 foreach aFrm [split "$aFrmsMap($aCsfElem)"] {
1404 if { [lsearch $aFrameworks $aFrm] == "-1" } {
1405 lappend aFrameworks $aFrm
1406 }
910970ab 1407 }
1408 }
1409 }
910970ab 1410}
1411
1412# Returns liste of UD in a toolkit. tkloc is a full path wok.
1413proc osutils:tk:units { tkloc } {
1414 global path
1415 set l {}
1416 set PACKAGES "$path/src/$tkloc/PACKAGES"
1417 foreach u [wokUtils:FILES:FileToList $PACKAGES] {
1418 if {[file isdirectory "$path/src/$u"]} {
1419 lappend l $u
1420 }
1421 }
1422 if { $l == {} } {
1423 ;#puts stderr "Warning. No devunit included in $tkloc"
1424 }
1425 return $l
1426}
1427
1428proc osutils:justwnt { listloc } {
1429 # ImageUtility is required for support for old (<6.5.4) versions of OCCT
1430 set goaway [list Xdps Xw ImageUtility WOKUnix]
1431 return [osutils:juststation $goaway $listloc]
1432}
1433
1434# remove from listloc OpenCascade units indesirables on NT
1435proc osutils:juststation {goaway listloc} {
1436 global path
1437 set lret {}
1438 foreach u $listloc {
1439 if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1440 || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1441 lappend lret $u
1442 }
1443 }
1444 return $lret
1445}
1446
1447# intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1448# The first list is everything in the first list that wasn't in the second,
1449# the second list contains the intersection of the two lists, the third list contains everything
1450# in the second list that wasn't in the first.
1451proc osutils:intersect3 {list1 list2} {
1452 set la1(0) {} ; unset la1(0)
1453 set lai(0) {} ; unset lai(0)
1454 set la2(0) {} ; unset la2(0)
1455 foreach v $list1 {
1456 set la1($v) {}
1457 }
1458 foreach v $list2 {
1459 set la2($v) {}
1460 }
1461 foreach elem [concat $list1 $list2] {
1462 if {[info exists la1($elem)] && [info exists la2($elem)]} {
1463 unset la1($elem)
1464 unset la2($elem)
1465 set lai($elem) {}
1466 }
1467 }
1468 list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1469}
1470
1471# Prepare relative path
1472proc relativePath {thePathFrom thePathTo} {
1473 if { [file isdirectory "$thePathFrom"] == 0 } {
1474 return ""
1475 }
1476
1477 set aPathFrom [file normalize "$thePathFrom"]
1478 set aPathTo [file normalize "$thePathTo"]
1479
1480 set aCutedPathFrom "${aPathFrom}/dummy"
1481 set aRelatedDeepPath ""
1482
1483 while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1484 set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1485 # does aPathTo contain aCutedPathFrom?
1486 regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1487 if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1488 if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1489 set aPathTo ".${aPathTo}"
1490 } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1491 set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1492 }
1493 regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1494 regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1495 return $aPathToAfterCut
1496 }
1497 set aRelatedDeepPath "$aRelatedDeepPath../"
1498
1499 }
1500
1501 return $thePathTo
1502}
1503
1504proc wokUtils:EASY:bs1 { s } {
1505 regsub -all {/} $s {\\} r
1506 return $r
1507}
1508
1509# Returs for a full path the liste of n last directory part
1510# n = 1 => tail
1511# n = 2 => dir/file.c
1512# n = 3 => sdir/dir/file.c
1513# etc..
1514proc wokUtils:FILES:wtail { f n } {
1515 set ll [expr [llength [set lif [file split $f]]] -$n]
1516 return [join [lrange $lif $ll end] /]
1517}
1518
1519# Generate entry for one source file in Visual Studio 10 project file
1520proc osutils:vcxproj:file { vcversion file params } {
1521 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1522 if { $params != "" } {
1523 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
1524 }
1525
1526 if { $params != "" } {
1527 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
1528 }
1529
1530 if { $params != "" } {
1531 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
1532 }
1533
1534 if { $params != "" } {
1535 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
1536 }
1537
1538 append text " </ClCompile>\n"
1539 return $text
1540}
1541
1542# Generate Visual Studio 2010 project filters file
1543proc osutils:vcxproj:filters { dir proj theFilesMap } {
1544 upvar $theFilesMap aFilesMap
1545
1546 # header
1547 append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1548 append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1549
1550 # list of "filters" (units)
1551 append text " <ItemGroup>\n"
1552 append text " <Filter Include=\"Source files\">\n"
1553 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1554 append text " </Filter>\n"
1555 foreach unit $aFilesMap(units) {
1556 append text " <Filter Include=\"Source files\\${unit}\">\n"
1557 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1558 append text " </Filter>\n"
1559 }
1560 append text " </ItemGroup>\n"
1561
1562 # list of files
1563 append text " <ItemGroup>\n"
1564 foreach unit $aFilesMap(units) {
1565 foreach file $aFilesMap($unit) {
1566 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1567 append text " <Filter>Source files\\${unit}</Filter>\n"
1568 append text " </ClCompile>\n"
1569 }
1570 }
1571 append text " </ItemGroup>\n"
1572
1573 # end
1574 append text "</Project>"
1575
1576 # write file
1577 set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1578 fconfigure $fp -translation crlf
1579 puts $fp $text
1580 close $fp
1581
1582 return ${proj}.vcxproj.filters
1583}
1584
1585# Generate Visual Studio 2011 project filters file
1586proc osutils:vcx1proj:filters { dir proj theFilesMap } {
1587 upvar $theFilesMap aFilesMap
1588
1589 # header
1590 append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1591 append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1592
1593 # list of "filters" (units)
1594 append text " <ItemGroup>\n"
1595 append text " <Filter Include=\"Source files\">\n"
1596 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1597 append text " </Filter>\n"
1598 foreach unit $aFilesMap(units) {
1599 append text " <Filter Include=\"Source files\\${unit}\">\n"
1600 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1601 append text " </Filter>\n"
1602 }
1603 append text " </ItemGroup>\n"
1604
1605 # list of files
1606 append text " <ItemGroup>\n"
1607 foreach unit $aFilesMap(units) {
1608 foreach file $aFilesMap($unit) {
1609 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1610 append text " <Filter>Source files\\${unit}</Filter>\n"
1611 append text " </ClCompile>\n"
1612 }
1613 }
1614 append text " </ItemGroup>\n"
1615
1616 append text " <ItemGroup>\n"
1617 append text " <ResourceCompile Include=\"${proj}.rc\" />"
1618 append text " </ItemGroup>\n"
1619
1620 # end
1621 append text "</Project>"
1622
1623 # write file
1624 set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1625 fconfigure $fp -translation crlf
1626 puts $fp $text
1627 close $fp
1628
1629 return ${proj}.vcxproj.filters
1630}
1631
1632# Generate RC file content for ToolKit from template
1633proc osutils:readtemplate:rc {theOutDir theToolKit} {
e31a8e52 1634 set aLoc "$::THE_CASROOT/adm/templates/template_dll.rc"
910970ab 1635 set aBody [wokUtils:FILES:FileToString $aLoc]
1636 regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1637
1638 set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1639 fconfigure $aFile -translation lf
1640 puts $aFile $aBody
1641 close $aFile
1642 return "${theOutDir}/${theToolKit}.rc"
1643}
1644
1645# Generate Visual Studio project file for ToolKit
1646proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
1647 if { $theProjTmpl == {} } {set theProjTmpl [osutils:vcproj:readtemplate $theVcVer 0]}
1648
944d808c 1649 set l_compilable [osutils:compilable wnt]
910970ab 1650 regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1651
1652 upvar $theGuidsMap aGuidsMap
1653 if { ! [info exists aGuidsMap($theToolKit)] } {
1654 set aGuidsMap($theToolKit) [OS:genGUID]
1655 }
1656 regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1657
7fbac3c2 1658 set theProjTmpl [osutils:uwp:proj ${theVcVer} ${theProjTmpl}]
1659
7c65581d 1660 set aUsedLibs [list]
7fbac3c2 1661
1662 if { "$theVcVer" == "vc14-uwp" } {
1663 lappend aUsedLibs "WindowsApp.lib"
1664 }
1665
910970ab 1666 foreach tkx [osutils:commonUsedTK $theToolKit] {
7c65581d 1667 lappend aUsedLibs "${tkx}.lib"
910970ab 1668 }
1669
c7d774c5 1670 osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
7c65581d 1671 foreach aLibIter $aLibs {
1672 lappend aUsedLibs "${aLibIter}.lib"
1673 }
910970ab 1674
1675 # correct names of referred third-party libraries that are named with suffix
1676 # depending on VC version
7c65581d 1677 regsub -all -- {vc[0-9]+} $aUsedLibs $theVcVer aUsedLibs
910970ab 1678
1679 # and put this list to project file
7c65581d 1680 #puts "$theToolKit requires $aUsedLibs"
39bff09c 1681 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
7c65581d 1682 set aUsedLibs [join $aUsedLibs {;}]
910970ab 1683 }
7c65581d 1684 regsub -all -- {__TKDEP__} $theProjTmpl $aUsedLibs theProjTmpl
910970ab 1685
1686 set anIncPaths "..\\..\\..\\inc"
1687 set aTKDefines ""
1688 set aFilesSection ""
1689 set aVcFilesX(units) ""
1690 set listloc [osutils:tk:units $theToolKit]
1691 set resultloc [osutils:justwnt $listloc]
1692 if [array exists written] { unset written }
1693 #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1694 #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1695 #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1696 #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1697 set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1698 set fxloparamfc [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1699 set fxloparam ""
1700 foreach fxlo $resultloc {
1701 set xlo $fxlo
944d808c 1702 set aSrcFiles [osutils:tk:files $xlo wnt]
910970ab 1703 set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
1704 if {$fxlo_cmplrs_options_cxx == ""} {
1705 set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1706 }
1707 set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1708 if {$fxlo_cmplrs_options_c == ""} {
1709 set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1710 }
1711 set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1712 set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1713 #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1714 #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo CXX"
1715 #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1716 #puts "\t6 [wokparam -v %CMPLRS_C_Options $fxlo] $fxlo C"
1717 set needparam ""
1718 foreach partopt $fxloparam {
1719 if {[string first "-I" $partopt] == "0"} {
1720 # this is an additional includes search path
1721 continue
1722 }
1723 set needparam "$needparam $partopt"
1724 }
1725
39bff09c 1726 # Format of projects in vc10+ is different from vc7-9
1727 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
910970ab 1728 foreach aSrcFile [lsort $aSrcFiles] {
1729 if { ![info exists written([file tail $aSrcFile])] } {
1730 set written([file tail $aSrcFile]) 1
1731 append aFilesSection [osutils:vcxproj:file $theVcVer $aSrcFile $needparam]
1732 } else {
1733 puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1734 }
1735 if { ! [info exists aVcFilesX($xlo)] } { lappend aVcFilesX(units) $xlo }
1736 lappend aVcFilesX($xlo) $aSrcFile
1737 }
1738 } else {
1739 append aFilesSection "\t\t\t<Filter\n"
1740 append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1741 append aFilesSection "\t\t\t\t>\n"
1742 foreach aSrcFile [lsort $aSrcFiles] {
1743 if { ![info exists written([file tail $aSrcFile])] } {
1744 set written([file tail $aSrcFile]) 1
1745 append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1746 } else {
1747 puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1748 }
1749 }
1750 append aFilesSection "\t\t\t</Filter>\n"
1751 }
1752
1753 # macros
1754 append aTKDefines ";__${xlo}_DLL"
1755 # common includes
1756# append anIncPaths ";..\\..\\..\\src\\${xlo}"
1757 }
1758
1759 regsub -all -- {__TKINC__} $theProjTmpl $anIncPaths theProjTmpl
1760 regsub -all -- {__TKDEFS__} $theProjTmpl $aTKDefines theProjTmpl
1761 regsub -all -- {__FILES__} $theProjTmpl $aFilesSection theProjTmpl
1762
1763 # write file
1764 set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1765 fconfigure $aFile -translation crlf
1766 puts $aFile $theProjTmpl
1767 close $aFile
1768
39bff09c 1769 # write filters file for vc10+
1770 if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" || "$theVcVer" == "vc9" } {
1771 # nothing
1772 } elseif { "$theVcVer" == "vc10" } {
910970ab 1773 lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesX]
39bff09c 1774 } else {
910970ab 1775 lappend aVcFiles [osutils:vcx1proj:filters $theOutDir $theToolKit aVcFilesX]
1776 }
1777
1778 # write resource file
1779 lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1780
1781 return $aVcFiles
1782}
1783
1784# for a unit returns a map containing all its file in the current
1785# workbench
1786# local = 1 only local files
1787proc osutils:tk:loadunit { loc map } {
1788 #puts $loc
1789 upvar $map TLOC
1790 catch { unset TLOC }
1791 set lfiles [_get_used_files $loc]
1792 foreach f $lfiles {
1793 #puts "\t$f"
1794 set t [lindex $f 0]
1795 set p [lindex $f 2]
1796 if [info exists TLOC($t)] {
1797 set l $TLOC($t)
1798 lappend l $p
1799 set TLOC($t) $l
1800 } else {
1801 set TLOC($t) $p
1802 }
1803 }
1804 return
1805}
1806
1807# Returns the list of all compilable files name in a toolkit, or devunit of any type
910970ab 1808# Tfiles lists for each unit the type of file that can be compiled.
944d808c 1809proc osutils:tk:files { tkloc thePlatform } {
910970ab 1810 set Tfiles(source,nocdlpack) {source pubinclude}
1811 set Tfiles(source,toolkit) {}
1812 set Tfiles(source,executable) {source pubinclude}
1813 set listloc [concat [osutils:tk:units $tkloc] $tkloc]
1814 #puts " listloc = $listloc"
944d808c 1815
1816 set l_comp [osutils:compilable $thePlatform]
1817 set resultloc $listloc
910970ab 1818 set lret {}
1819 foreach loc $resultloc {
1820 set utyp [_get_type $loc]
1821 #puts "\"$utyp\" \"$loc\""
1822 switch $utyp {
1823 "t" { set utyp "toolkit" }
1824 "n" { set utyp "nocdlpack" }
1825 "x" { set utyp "executable" }
1826 }
1827 if [array exists map] { unset map }
1828 osutils:tk:loadunit $loc map
1829 #puts " loc = $loc === > [array names map]"
1830 set LType $Tfiles(source,${utyp})
1831 foreach typ [array names map] {
1832 if { [lsearch $LType $typ] == -1 } {
1833 unset map($typ)
1834 }
1835 }
1836 foreach type [array names map] {
1837 #puts $type
1838 foreach f $map($type) {
1839 #puts $f
1840 if { [lsearch $l_comp [file extension $f]] != -1 } {
944d808c 1841 lappend lret $f
910970ab 1842 }
1843 }
1844 }
1845 }
1846 return $lret
1847}
1848
1849# Generate Visual Studio project file for executable
1850proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
910970ab 1851 set aVcFiles {}
944d808c 1852 foreach f [osutils:tk:files $theToolKit wnt] {
910970ab 1853 if { $theProjTmpl == {} } {
1854 set aProjTmpl [osutils:vcproj:readtemplate $theVcVer 1]
1855 } else {
1856 set aProjTmpl $theProjTmpl
1857 }
1858 set aProjName [file rootname [file tail $f]]
944d808c 1859 set l_compilable [osutils:compilable wnt]
910970ab 1860 regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
1861
1862 upvar $theGuidsMap aGuidsMap
1863 if { ! [info exists aGuidsMap($aProjName)] } {
1864 set aGuidsMap($aProjName) [OS:genGUID]
1865 }
1866 regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
1867
7c65581d 1868 set aUsedLibs [list]
910970ab 1869 foreach tkx [osutils:commonUsedTK $theToolKit] {
7c65581d 1870 lappend aUsedLibs "${tkx}.lib"
910970ab 1871 }
1872
c7d774c5 1873 osutils:usedOsLibs $theToolKit "wnt" aLibs aFrameworks
7c65581d 1874 foreach aLibIter $aLibs {
1875 lappend aUsedLibs "${aLibIter}.lib"
1876 }
910970ab 1877
1878 # correct names of referred third-party libraries that are named with suffix
1879 # depending on VC version
7c65581d 1880 regsub -all -- {vc[0-9]+} $aUsedLibs $theVcVer aUsedLibs
910970ab 1881
7c65581d 1882# puts "$aProjName requires $aUsedLibs"
39bff09c 1883 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
7c65581d 1884 set aUsedLibs [join $aUsedLibs {;}]
910970ab 1885 }
7c65581d 1886 regsub -all -- {__TKDEP__} $aProjTmpl $aUsedLibs aProjTmpl
910970ab 1887
1888 set aFilesSection ""
1889 set aVcFilesX(units) ""
1890
1891 if { ![info exists written([file tail $f])] } {
1892 set written([file tail $f]) 1
1893
39bff09c 1894 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
910970ab 1895 append aFilesSection [osutils:vcxproj:file $theVcVer $f ""]
1896 if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
1897 lappend aVcFilesX($theToolKit) $f
1898 } else {
1899 append aFilesSection "\t\t\t<Filter\n"
1900 append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
1901 append aFilesSection "\t\t\t\t>\n"
1902 append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
1903 append aFilesSection "\t\t\t</Filter>"
1904 }
1905 } else {
1906 puts "Warning : in vcproj there are than one occurences for [file tail $f]"
1907 }
1908 #puts "$aProjTmpl $aFilesSection"
1909 set aTKDefines ";__${theToolKit}_DLL"
1910 set anIncPaths "..\\..\\..\\inc"
1911 regsub -all -- {__TKINC__} $aProjTmpl $anIncPaths aProjTmpl
1912 regsub -all -- {__TKDEFS__} $aProjTmpl $aTKDefines aProjTmpl
1913 regsub -all -- {__FILES__} $aProjTmpl $aFilesSection aProjTmpl
1c29294e 1914 regsub -all -- {__CONF__} $aProjTmpl Application aProjTmpl
1915
1916 regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
910970ab 1917
1918 set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
1919 fconfigure $aFile -translation crlf
1920 puts $aFile $aProjTmpl
1921 close $aFile
1922
1923 set aCommonSettingsFile "$aVcFilePath.user"
1924 lappend aVcFiles $aVcFilePath
1925
1926 # write filters file for vc10
39bff09c 1927 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
910970ab 1928 lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesX]
1929 }
1930
1931 set aCommonSettingsFileTmpl ""
39bff09c 1932 if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
1933 # nothing
1934 } elseif { "$theVcVer" == "vc9" } {
e31a8e52 1935 set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcproj.user.vc9x"]
39bff09c 1936 } else {
e31a8e52 1937 set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcxproj.user.vc10x"]
910970ab 1938 }
1939 if { "$aCommonSettingsFileTmpl" != "" } {
39bff09c 1940 regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $theVcVer aCommonSettingsFileTmpl
1941
1942 set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
1943 fconfigure $aFile -translation crlf
1944 puts $aFile $aCommonSettingsFileTmpl
1945 close $aFile
1946
910970ab 1947 lappend aVcFiles "$aCommonSettingsFile"
1948 }
1949 }
1950 return $aVcFiles
1951}
1952
1953# Generate entry for one source file in Visual Studio 7 - 9 project file
1954proc osutils:vcproj:file { theVcVer theFile theOptions } {
1955 append aText "\t\t\t\t<File\n"
1956 append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1957 if { $theOptions == "" } {
1958 append aText "\t\t\t\t</File>\n"
1959 return $aText
1960 }
1961
1962 append aText "\t\t\t\t\t<FileConfiguration\n"
1963 append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
1964 append aText "\t\t\t\t\t\t<Tool\n"
1965 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1966 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1967 foreach aParam $theOptions {
1968 append aText "$aParam "
1969 }
1970 append aText "\"\n"
1971 append aText "\t\t\t\t\t\t/>\n"
1972 append aText "\t\t\t\t\t</FileConfiguration>\n"
1973
1974 append aText "\t\t\t\t\t<FileConfiguration\n"
1975 append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
1976 append aText "\t\t\t\t\t\t<Tool\n"
1977 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1978 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1979 foreach aParam $theOptions {
1980 append aText "$aParam "
1981 }
1982 append aText "\"\n"
1983 append aText "\t\t\t\t\t\t/>\n"
1984 append aText "\t\t\t\t\t</FileConfiguration>\n"
1985 if { "$theVcVer" == "vc7" } {
1986 append aText "\t\t\t\t</File>\n"
1987 return $aText
1988 }
1989
1990 append aText "\t\t\t\t\t<FileConfiguration\n"
1991 append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
1992 append aText "\t\t\t\t\t\t<Tool\n"
1993 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
1994 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
1995 foreach aParam $theOptions {
1996 append aText "$aParam "
1997 }
1998 append aText "\"\n"
1999 append aText "\t\t\t\t\t\t/>\n"
2000 append aText "\t\t\t\t\t</FileConfiguration>\n"
2001
2002 append aText "\t\t\t\t\t<FileConfiguration\n"
2003 append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
2004 append aText "\t\t\t\t\t\t<Tool\n"
2005 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2006 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2007 foreach aParam $theOptions {
2008 append aText "$aParam "
2009 }
2010 append aText "\"\n"
2011 append aText "\t\t\t\t\t\t/>\n"
2012 append aText "\t\t\t\t\t</FileConfiguration>\n"
2013
2014 append aText "\t\t\t\t</File>\n"
2015 return $aText
2016}
2017
910970ab 2018proc wokUtils:FILES:mkdir { d } {
2019 global tcl_version
2020 regsub -all {\.[^.]*} $tcl_version "" major
2021 if { $major == 8 } {
2022 file mkdir $d
2023 } else {
2024 if ![file exists $d] {
2025 if { "[info command mkdir]" == "mkdir" } {
2026 mkdir -path $d
2027 } else {
2028 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
2029 }
2030 }
2031 }
2032 if [file exists $d] {
2033 return $d
2034 } else {
2035 return {}
2036 }
2037}
2038
910970ab 2039# remove from listloc OpenCascade units indesirables on Unix
2040proc osutils:justunix { listloc } {
c7d774c5 2041 if { "$::tcl_platform(os)" == "Darwin" } {
910970ab 2042 set goaway [list Xw WNT]
2043 } else {
2044 set goaway [list WNT]
2045 }
2046 return [osutils:juststation $goaway $listloc]
2047}
2048
910970ab 2049
2050####### CODEBLOCK ###################################################################
2051# Function to generate Code Blocks workspace and project files
944d808c 2052proc OS:MKCBP { theOutDir theModules theAllSolution thePlatform theCmpl } {
910970ab 2053 puts stderr "Generating project files for Code Blocks"
2054
2055 # Generate projects for toolkits and separate workspace for each module
2056 foreach aModule $theModules {
7c65581d 2057 OS:cworkspace $aModule $aModule $theOutDir
944d808c 2058 OS:cbp $theCmpl $aModule $theOutDir $thePlatform
910970ab 2059 }
2060
2061 # Generate single workspace "OCCT" containing projects from all modules
2062 if { "$theAllSolution" != "" } {
2063 OS:cworkspace $theAllSolution $theModules $theOutDir
2064 }
2065
2066 puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
2067}
2068
2069# Generate Code Blocks projects
944d808c 2070proc OS:cbp { theCmpl theModules theOutDir thePlatform } {
910970ab 2071 set aProjectFiles {}
2072 foreach aModule $theModules {
2073 foreach aToolKit [${aModule}:toolkits] {
944d808c 2074 lappend aProjectFiles [osutils:cbptk $theCmpl $theOutDir $aToolKit $thePlatform]
910970ab 2075 }
2076 foreach anExecutable [OS:executable ${aModule}] {
944d808c 2077 lappend aProjectFiles [osutils:cbpx $theCmpl $theOutDir $anExecutable $thePlatform]
910970ab 2078 }
2079 }
2080 return $aProjectFiles
2081}
2082
2083# Generate Code::Blocks project file for ToolKit
944d808c 2084proc osutils:cbptk { theCmpl theOutDir theToolKit thePlatform} {
7c65581d 2085 set aUsedLibs [list]
910970ab 2086 set aFrameworks [list]
2087 set anIncPaths [list]
2088 set aTKDefines [list]
2089 set aTKSrcFiles [list]
2090
7c65581d 2091 # collect list of referred libraries to link with
944d808c 2092 osutils:usedOsLibs $theToolKit $thePlatform aUsedLibs aFrameworks
7c65581d 2093 set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
2094 foreach tkx $aDepToolkits {
2095 lappend aUsedLibs "${tkx}"
2096 }
2097
2098 lappend anIncPaths "../../../inc"
2099 set listloc [osutils:tk:units $theToolKit]
2100
2101 if { [llength $listloc] == 0 } {
2102 set listloc $theToolKit
2103 }
2104
944d808c 2105 if { $thePlatform == "wnt" } {
7c65581d 2106 set resultloc [osutils:justwnt $listloc]
2107 } else {
2108 set resultloc [osutils:justunix $listloc]
2109 }
2110 if [array exists written] { unset written }
2111 foreach fxlo $resultloc {
2112 set xlo $fxlo
944d808c 2113 set aSrcFiles [osutils:tk:files $xlo $thePlatform]
7c65581d 2114 foreach aSrcFile [lsort $aSrcFiles] {
2115 if { ![info exists written([file tail $aSrcFile])] } {
2116 set written([file tail $aSrcFile]) 1
2117 lappend aTKSrcFiles "../../../[wokUtils:FILES:wtail $aSrcFile 3]"
2118 } else {
2119 puts "Warning : more than one occurences for [file tail $aSrcFile]"
2120 }
2121 }
2122
2123 # macros for correct DLL exports
944d808c 2124 if { $thePlatform == "wnt" } {
7c65581d 2125 lappend aTKDefines "__${xlo}_DLL"
2126 }
2127 }
910970ab 2128
944d808c 2129 return [osutils:cbp $theCmpl $theOutDir $theToolKit $thePlatform $aTKSrcFiles $aUsedLibs $aFrameworks $anIncPaths $aTKDefines]
910970ab 2130}
2131
2132# Generates Code Blocks workspace.
2133proc OS:cworkspace { theSolName theModules theOutDir } {
2134 global path
2135 set aWsFilePath "${theOutDir}/${theSolName}.workspace"
2136 set aFile [open $aWsFilePath "w"]
2137 set isActiveSet 0
2138 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2139 puts $aFile "<CodeBlocks_workspace_file>"
2140 puts $aFile "\t<Workspace title=\"${theSolName}\">"
2141
2142 # collect list of projects to be created
2143 foreach aModule $theModules {
2144 # toolkits
2145 foreach aToolKit [osutils:tk:sort [${aModule}:toolkits]] {
2146 set aDependencies [LibToLink $aToolKit]
2147 if { [llength $aDependencies] == 0 } {
2148 puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
2149 } else {
2150 puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
2151 foreach aDepTk $aDependencies {
2152 puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2153 }
2154 puts $aFile "\t\t</Project>"
2155 }
2156 }
2157
2158 # executables, assume one project per cxx file...
2159 foreach aUnit [OS:executable ${aModule}] {
2160 set aUnitLoc $aUnit
2161 set src_files [_get_used_files $aUnit false]
2162 set aSrcFiles {}
2163 foreach s $src_files {
2164 regexp {source ([^\s]+)} $s dummy name
2165 lappend aSrcFiles $name
2166 }
2167 foreach aSrcFile $aSrcFiles {
2168 set aFileExtension [file extension $aSrcFile]
2169 if { $aFileExtension == ".cxx" } {
2170 set aPrjName [file rootname $aSrcFile]
2171 set aDependencies [list]
2172 if {[file isdirectory $path/src/$aUnitLoc]} {
2173 set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile]]
2174 }
2175 set anActiveState ""
2176 if { $isActiveSet == 0 } {
2177 set anActiveState " active=\"1\""
2178 set isActiveSet 1
2179 }
2180 if { [llength $aDependencies] == 0 } {
2181 puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
2182 } else {
2183 puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
2184 foreach aDepTk $aDependencies {
2185 puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2186 }
2187 puts $aFile "\t\t</Project>"
2188 }
2189 }
2190 }
2191 }
2192 }
2193
2194 puts $aFile "\t</Workspace>"
2195 puts $aFile "</CodeBlocks_workspace_file>"
2196 close $aFile
2197
2198 return $aWsFilePath
2199}
2200
2201# Generate Code::Blocks project file for Executable
944d808c 2202proc osutils:cbpx { theCmpl theOutDir theToolKit thePlatform } {
2203 global path
910970ab 2204 set aWokArch "$::env(ARCH)"
2205
2206 set aCbpFiles {}
944d808c 2207 foreach aSrcFile [osutils:tk:files $theToolKit $thePlatform] {
910970ab 2208 # collect list of referred libraries to link with
7c65581d 2209 set aUsedLibs [list]
910970ab 2210 set aFrameworks [list]
2211 set anIncPaths [list]
2212 set aTKDefines [list]
2213 set aTKSrcFiles [list]
2214 set aProjName [file rootname [file tail $aSrcFile]]
2215
944d808c 2216 osutils:usedOsLibs $theToolKit $thePlatform aUsedLibs aFrameworks
7c65581d 2217
910970ab 2218 set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2219 foreach tkx $aDepToolkits {
2220 if {[_get_type $tkx] == "t"} {
7c65581d 2221 lappend aUsedLibs "${tkx}"
910970ab 2222 }
2223 if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
7c65581d 2224 lappend aUsedLibs "${tkx}"
910970ab 2225 }
2226 }
2227
910970ab 2228 set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
2229 if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
2230 set isExecutable "false"
2231 } else {
2232 set isExecutable "true"
2233 }
2234
2235 if { ![info exists written([file tail $aSrcFile])] } {
2236 set written([file tail $aSrcFile]) 1
7c65581d 2237 lappend aTKSrcFiles "../../../[wokUtils:FILES:wtail $aSrcFile 3]"
910970ab 2238 } else {
2239 puts "Warning : in cbp there are more than one occurences for [file tail $aSrcFile]"
2240 }
2241
2242 # macros for correct DLL exports
944d808c 2243 if { $thePlatform == "wnt" } {
910970ab 2244 lappend aTKDefines "__${theToolKit}_DLL"
2245 }
2246
2247 # common include paths
2248 lappend anIncPaths "../../../inc"
2249
944d808c 2250 lappend aCbpFiles [osutils:cbp $theCmpl $theOutDir $aProjName $thePlatform $aTKSrcFiles $aUsedLibs $aFrameworks $anIncPaths $aTKDefines $isExecutable]
910970ab 2251 }
2252
2253 return $aCbpFiles
2254}
2255
910970ab 2256# This function intended to generate Code::Blocks project file
7c65581d 2257# @param theCmpl - the compiler (gcc or msvc)
910970ab 2258# @param theOutDir - output directory to place project file
2259# @param theProjName - project name
2260# @param theSrcFiles - list of source files
2261# @param theLibsList - dependencies (libraries list)
2262# @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2263# @param theIncPaths - header search paths
2264# @param theDefines - compiler macro definitions
2265# @param theIsExe - flag to indicate executable / library target
944d808c 2266proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2267 set aWokStation $thePlatform
910970ab 2268 set aWokArch "$::env(ARCH)"
2269
7c65581d 2270 set aCmplCbp "gcc"
2271 set aCmplFlags [list]
2272 set aCmplFlagsRelease [list]
2273 set aCmplFlagsDebug [list]
2274 set toPassArgsByFile 0
2275 set aLibPrefix "lib"
2276 if { "$aWokStation" == "wnt" || "$aWokStation" == "qnx" } {
2277 set toPassArgsByFile 1
2278 }
2279 if { "$theCmpl" == "msvc" } {
2280 set aCmplCbp "msvc8"
2281 set aLibPrefix ""
2282 }
2283
2284 if { "$theCmpl" == "msvc" } {
2285 set aCmplFlags "-arch:SSE2 -EHsc -W4 -MP"
2286 set aCmplFlagsRelease "-MD -O2"
2287 set aCmplFlagsDebug "-MDd -Od -Zi"
2288 lappend aCmplFlags "-D_CRT_SECURE_NO_WARNINGS"
2289 lappend aCmplFlags "-D_CRT_NONSTDC_NO_DEPRECATE"
2290 } elseif { "$theCmpl" == "gcc" } {
2291 if { "$aWokStation" != "qnx" } {
2292 set aCmplFlags "-mmmx -msse -msse2 -mfpmath=sse"
2293 }
2294 set aCmplFlagsRelease "-O2"
2295 set aCmplFlagsDebug "-O0 -g"
2296 if { "$aWokStation" == "wnt" } {
2297 lappend aCmplFlags "-std=gnu++0x"
2298 lappend aCmplFlags "-D_WIN32_WINNT=0x0501"
2299 } else {
2300 lappend aCmplFlags "-std=c++0x"
2301 lappend aCmplFlags "-fPIC"
2302 lappend aCmplFlags "-DOCC_CONVERT_SIGNALS"
2303 }
2304 lappend aCmplFlags "-Wall"
2305 lappend aCmplFlags "-fexceptions"
2306 }
2307 lappend aCmplFlagsRelease "-DNDEBUG"
2308 lappend aCmplFlagsRelease "-DNo_Exception"
2309 lappend aCmplFlagsDebug "-D_DEBUG"
2310 if { "$aWokStation" == "qnx" } {
2311 lappend aCmplFlags "-D_QNX_SOURCE"
2312 }
2313
2314 set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2315 set aLnkFileName "${theProjName}_obj.link"
2316 set aLnkDebFileName "${theProjName}_objd.link"
2317 set aLnkFilePath "${theOutDir}/${aLnkFileName}"
2318 set aLnkDebFilePath "${theOutDir}/${aLnkDebFileName}"
910970ab 2319 set aFile [open $aCbpFilePath "w"]
2320 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2321 puts $aFile "<CodeBlocks_project_file>"
2322 puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2323 puts $aFile "\t<Project>"
2324 puts $aFile "\t\t<Option title=\"$theProjName\" />"
2325 puts $aFile "\t\t<Option pch_mode=\"2\" />"
7c65581d 2326 puts $aFile "\t\t<Option compiler=\"$aCmplCbp\" />"
910970ab 2327 puts $aFile "\t\t<Build>"
2328
2329 # Release target configuration
2330 puts $aFile "\t\t\t<Target title=\"Release\">"
2331 if { "$theIsExe" == "true" } {
d8d01f6e 2332 puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2333 puts $aFile "\t\t\t\t<Option type=\"1\" />"
2334 } else {
2335 if { "$aWokStation" == "wnt" } {
7c65581d 2336 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 2337 } else {
d8d01f6e 2338 puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2339 }
2340 puts $aFile "\t\t\t\t<Option type=\"3\" />"
2341 }
2342 puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
7c65581d 2343 puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
2344 puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
910970ab 2345 if { "$aWokStation" == "wnt" } {
7c65581d 2346 puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
910970ab 2347 } else {
7c65581d 2348 puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
910970ab 2349 }
910970ab 2350
2351 # compiler options per TARGET (including defines)
2352 puts $aFile "\t\t\t\t<Compiler>"
7c65581d 2353 foreach aFlagIter $aCmplFlagsRelease {
2354 puts $aFile "\t\t\t\t\t<Add option=\"$aFlagIter\" />"
910970ab 2355 }
2356 foreach aMacro $theDefines {
2357 puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2358 }
910970ab 2359 puts $aFile "\t\t\t\t</Compiler>"
2360
2361 puts $aFile "\t\t\t\t<Linker>"
7c65581d 2362 if { $toPassArgsByFile == 1 } {
2363 puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkFileName\" />"
2364 }
910970ab 2365 puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
7c65581d 2366 if { "$aWokStation" == "mac" } {
2367 if { [ lsearch $theLibsList X11 ] >= 0} {
2368 puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2369 }
910970ab 2370 }
2371 puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
55fb31da 2372 if { "$aWokStation" == "lin" } {
2373 puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aWokStation}/cbp/lib\" />"
2374 }
910970ab 2375 puts $aFile "\t\t\t\t</Linker>"
2376
2377 puts $aFile "\t\t\t</Target>"
2378
2379 # Debug target configuration
2380 puts $aFile "\t\t\t<Target title=\"Debug\">"
2381 if { "$theIsExe" == "true" } {
d8d01f6e 2382 puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2383 puts $aFile "\t\t\t\t<Option type=\"1\" />"
2384 } else {
2385 if { "$aWokStation" == "wnt" } {
7c65581d 2386 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 2387 } else {
d8d01f6e 2388 puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2389 }
2390 puts $aFile "\t\t\t\t<Option type=\"3\" />"
2391 }
2392 puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
7c65581d 2393 puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
2394 puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
910970ab 2395 if { "$aWokStation" == "wnt" } {
7c65581d 2396 puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
910970ab 2397 } else {
7c65581d 2398 puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
910970ab 2399 }
910970ab 2400
2401 # compiler options per TARGET (including defines)
2402 puts $aFile "\t\t\t\t<Compiler>"
7c65581d 2403 foreach aFlagIter $aCmplFlagsDebug {
2404 puts $aFile "\t\t\t\t\t<Add option=\"$aFlagIter\" />"
910970ab 2405 }
2406 foreach aMacro $theDefines {
2407 puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2408 }
910970ab 2409 puts $aFile "\t\t\t\t</Compiler>"
2410
2411 puts $aFile "\t\t\t\t<Linker>"
7c65581d 2412 if { $toPassArgsByFile == 1 } {
2413 puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkDebFileName\" />"
2414 }
910970ab 2415 puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
7c65581d 2416 if { "$aWokStation" == "mac" } {
2417 if { [ lsearch $theLibsList X11 ] >= 0} {
2418 puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2419 }
910970ab 2420 }
2421 puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
55fb31da 2422 if { "$aWokStation" == "lin" } {
2423 puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aWokStation}/cbp/libd\" />"
2424 }
910970ab 2425 puts $aFile "\t\t\t\t</Linker>"
2426
2427 puts $aFile "\t\t\t</Target>"
2428
2429 puts $aFile "\t\t</Build>"
2430
2431 # COMMON compiler options
2432 puts $aFile "\t\t<Compiler>"
7c65581d 2433 foreach aFlagIter $aCmplFlags {
2434 puts $aFile "\t\t\t<Add option=\"$aFlagIter\" />"
2435 }
910970ab 2436 puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2437 foreach anIncPath $theIncPaths {
2438 puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2439 }
2440 puts $aFile "\t\t</Compiler>"
2441
2442 # COMMON linker options
2443 puts $aFile "\t\t<Linker>"
7c65581d 2444 if { "$aWokStation" == "wnt" && "$theCmpl" == "gcc" } {
2445 puts $aFile "\t\t\t<Add option=\"-Wl,--export-all-symbols\" />"
2446 }
910970ab 2447 foreach aFrameworkName $theFrameworks {
2448 if { "$aFrameworkName" != "" } {
2449 puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2450 }
2451 }
2452 foreach aLibName $theLibsList {
2453 if { "$aLibName" != "" } {
7c65581d 2454 if { "$theCmpl" == "msvc" } {
2455 puts $aFile "\t\t\t<Add library=\"${aLibName}.lib\" />"
2456 } else {
2457 puts $aFile "\t\t\t<Add library=\"${aLibName}\" />"
2458 }
910970ab 2459 }
2460 }
2461 puts $aFile "\t\t</Linker>"
2462
2463 # list of sources
7c65581d 2464
2465 set aFileLnkObj ""
2466 set aFileLnkObjd ""
2467 set isFirstSrcFile 1
2468 if { $toPassArgsByFile == 1 } {
2469 set aFileLnkObj [open $aLnkFilePath "w"]
2470 set aFileLnkObjd [open $aLnkDebFilePath "w"]
2471 }
2472
910970ab 2473 foreach aSrcFile $theSrcFiles {
2474 if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2475 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2476 puts $aFile "\t\t\t<Option compile=\"1\" />"
2477 puts $aFile "\t\t\t<Option link=\"1\" />"
2478 puts $aFile "\t\t</Unit>"
2479 } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2480 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2481 puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2482 puts $aFile "\t\t</Unit>"
7c65581d 2483 } elseif { $toPassArgsByFile == 1 && $isFirstSrcFile == 0 && [string equal -nocase [file extension $aSrcFile] ".cxx" ] } {
2484 # pass at list single source file to Code::Blocks as is
2485 # and pack the list of other files into the dedicated file to workaround process arguments limits on systems like Windows
2486 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2487 puts $aFile "\t\t\t<Option link=\"0\" />"
2488 puts $aFile "\t\t</Unit>"
2489
2490 set aFileObj [string map {.cxx .o} [string map [list "/src/" "/$aWokStation/cbp/obj/src/"] $aSrcFile]]
2491 set aFileObjd [string map {.cxx .o} [string map [list "/src/" "/$aWokStation/cbp/objd/src/"] $aSrcFile]]
2492 puts -nonewline $aFileLnkObj "$aFileObj "
2493 puts -nonewline $aFileLnkObjd "$aFileObjd "
910970ab 2494 } else {
2495 puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
7c65581d 2496 set isFirstSrcFile 0
910970ab 2497 }
2498 }
2499
7c65581d 2500 if { "$aWokStation" == "wnt" } {
2501 close $aFileLnkObj
2502 close $aFileLnkObjd
2503 }
2504
910970ab 2505 puts $aFile "\t</Project>"
2506 puts $aFile "</CodeBlocks_project_file>"
2507 close $aFile
2508
2509 return $aCbpFilePath
2510}
2511
910970ab 2512# Define libraries to link using only EXTERNLIB file
2513proc LibToLinkX {thePackage theDummyName} {
2514 set aToolKits [LibToLink $thePackage]
2515 return $aToolKits
2516}
2517
c7d774c5 2518# Function to generate Xcode workspace and project files
2519proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
2520
2521 puts stderr "Generating project files for Xcode"
2522
2523 # Generate projects for toolkits and separate workspace for each module
2524 foreach aModule $theModules {
2525 OS:xcworkspace $aModule $aModule $theOutDir
2526 OS:xcodeproj $aModule $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
2527 }
2528
2529 # Generate single workspace "OCCT" containing projects from all modules
2530 if { "$theAllSolution" != "" } {
2531 OS:xcworkspace $theAllSolution $theModules $theOutDir
2532 }
2533}
2534
2535# Generates toolkits sections for Xcode workspace file.
2536proc OS:xcworkspace:toolkits { theModule } {
2537 set aBuff ""
2538
2539 # Adding toolkits for module in workspace.
2540 foreach aToolKit [osutils:tk:sort [${theModule}:toolkits]] {
2541 append aBuff " <FileRef\n"
2542 append aBuff " location = \"group:${aToolKit}.xcodeproj\">\n"
2543 append aBuff " </FileRef>\n"
2544 }
2545
2546 # Adding executables for module, assume one project per cxx file...
2547 foreach aUnit [OS:executable ${theModule}] {
2548 set aUnitLoc $aUnit
2549 set src_files [_get_used_files $aUnit false]
2550 set aSrcFiles {}
2551 foreach s $src_files {
2552 regexp {source ([^\s]+)} $s dummy name
2553 lappend aSrcFiles $name
2554 }
2555 foreach aSrcFile $aSrcFiles {
2556 set aFileExtension [file extension $aSrcFile]
2557 if { $aFileExtension == ".cxx" } {
2558 set aPrjName [file rootname $aSrcFile]
2559 append aBuff " <FileRef\n"
2560 append aBuff " location = \"group:${aPrjName}.xcodeproj\">\n"
2561 append aBuff " </FileRef>\n"
2562 }
2563 }
2564 }
2565
2566 # Removing unnecessary newline character from the end.
2567 set aBuff [string replace $aBuff end end]
2568 return $aBuff
2569}
2570
2571# Generates workspace files for Xcode.
2572proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
2573 # Creating workspace directory for Xcode.
2574 set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
2575 wokUtils:FILES:mkdir $aWorkspaceDir
2576 if { ! [file exists $aWorkspaceDir] } {
2577 puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
2578 return
2579 }
2580
2581 # Creating workspace file.
2582 set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
2583 set aFile [open $aWsFilePath "w"]
2584
2585 # Adding header and section for main Group.
2586 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2587 puts $aFile "<Workspace"
2588 puts $aFile " version = \"1.0\">"
2589 puts $aFile " <Group"
2590 puts $aFile " location = \"container:\""
2591 puts $aFile " name = \"${theWorkspaceName}\">"
2592
2593 # Adding modules.
2594 if { [llength "$theModules"] > 1 } {
2595 foreach aModule $theModules {
2596 puts $aFile " <Group"
2597 puts $aFile " location = \"container:\""
2598 puts $aFile " name = \"${aModule}\">"
2599 puts $aFile [OS:xcworkspace:toolkits $aModule]
2600 puts $aFile " </Group>"
2601 }
2602 } else {
2603 puts $aFile [OS:xcworkspace:toolkits $theModules]
2604 }
2605
2606 # Adding footer.
2607 puts $aFile " </Group>"
2608 puts $aFile "</Workspace>"
2609 close $aFile
2610}
2611
2612# Generates Xcode project files.
2613proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
2614 upvar $theGuidsMap aGuidsMap
2615
2616 set isStatic 0
2617 if { "$theLibType" == "static" } {
2618 set isStatic 1
2619 } elseif { "$thePlatform" == "ios" } {
2620 set isStatic 1
2621 }
2622
2623 set aProjectFiles {}
2624 foreach aModule $theModules {
2625 foreach aToolKit [${aModule}:toolkits] {
2626 lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit aGuidsMap $isStatic $thePlatform "dylib"]
2627 }
2628 foreach anExecutable [OS:executable ${aModule}] {
2629 lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
2630 }
2631 }
2632 return $aProjectFiles
2633}
2634
2635# Generates dependencies section for Xcode project files.
2636proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids theIsStatic} {
c7d774c5 2637 upvar $theGuidsMap aGuidsMap
2638 upvar $theFileRefSection aFileRefSection
2639 upvar $theDepsGuids aDepsGuids
2640 upvar $theDepsRefGuids aDepsRefGuids
2641
2642 set aBuildFileSection ""
7c65581d 2643 set aUsedLibs [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]]
c7d774c5 2644 set aDepToolkits [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]] $theToolKit]
2645
2646 if { "$theTargetType" == "executable" } {
944d808c 2647 set aFile [osutils:tk:files $theToolKit mac]
c7d774c5 2648 set aProjName [file rootname [file tail $aFile]]
2649 set aDepToolkits [LibToLinkX $theToolKit $aProjName]
2650 }
2651
2652 set aLibExt "dylib"
2653 if { $theIsStatic == 1 } {
2654 set aLibExt "a"
2655 if { "$theTargetType" != "executable" } {
2656 return $aBuildFileSection
2657 }
2658 }
2659
2660 osutils:usedOsLibs $theToolKit "mac" aLibs aFrameworks
7c65581d 2661 set aUsedLibs [concat $aUsedLibs $aLibs]
2662 set aUsedLibs [concat $aUsedLibs $aFrameworks]
2663 foreach tkx $aUsedLibs {
c7d774c5 2664 set aDepLib "${tkx}_Dep"
2665 set aDepLibRef "${tkx}_DepRef"
2666
2667 if { ! [info exists aGuidsMap($aDepLib)] } {
2668 set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
2669 }
2670 if { ! [info exists aGuidsMap($aDepLibRef)] } {
2671 set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
2672 }
2673
2674 append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
2675 if {[lsearch -nocase $aFrameworks $tkx] == -1} {
2676 append aFileRefSection "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
2677 } else {
2678 append aFileRefSection "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
2679 }
2680 append aDepsGuids "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
2681 append aDepsRefGuids "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
2682 }
2683
2684 return $aBuildFileSection
2685}
2686
2687# Generates PBXBuildFile and PBXGroup sections for project file.
2688proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
2689 upvar $theSrcFileRefSection aSrcFileRefSection
2690 upvar $theGroupSection aGroupSection
2691 upvar $thePackageGuids aPackagesGuids
2692 upvar $theSrcFileGuids aSrcFileGuids
2693 upvar $theGuidsMap aGuidsMap
2694 upvar $theIncPaths anIncPaths
2695
2696 set listloc [osutils:tk:units $theToolKit]
2697 set resultloc [osutils:justunix $listloc]
2698 set aBuildFileSection ""
2699 set aPackages [lsort -nocase $resultloc]
2700 if { "$theTargetType" == "executable" } {
2701 set aPackages [list "$theToolKit"]
2702 }
2703
2704 # Generating PBXBuildFile, PBXGroup sections and groups for each package.
2705 foreach fxlo $aPackages {
2706 set xlo $fxlo
2707 set aPackage "${xlo}_Package"
2708 set aSrcFileRefGuids ""
2709 if { ! [info exists aGuidsMap($aPackage)] } {
2710 set aGuidsMap($aPackage) [OS:genGUID "xcd"]
2711 }
2712
944d808c 2713 set aSrcFiles [osutils:tk:files $xlo mac]
c7d774c5 2714 foreach aSrcFile [lsort $aSrcFiles] {
2715 set aFileExt "sourcecode.cpp.cpp"
2716
2717 if { [file extension $aSrcFile] == ".c" } {
2718 set aFileExt "sourcecode.c.c"
2719 } elseif { [file extension $aSrcFile] == ".mm" } {
2720 set aFileExt "sourcecode.cpp.objcpp"
2721 }
2722
2723 if { ! [info exists aGuidsMap($aSrcFile)] } {
2724 set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
2725 }
2726 set aSrcFileRef "${aSrcFile}_Ref"
2727 if { ! [info exists aGuidsMap($aSrcFileRef)] } {
2728 set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
2729 }
2730 if { ! [info exists written([file tail $aSrcFile])] } {
2731 set written([file tail $aSrcFile]) 1
2732 append aBuildFileSection "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
2733 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"
2734 append aSrcFileGuids "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
2735 append aSrcFileRefGuids "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
2736 } else {
2737 puts "Warning : more than one occurences for [file tail $aSrcFile]"
2738 }
2739 }
2740
2741 append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
2742 append aGroupSection "\t\t\tisa = PBXGroup;\n"
2743 append aGroupSection "\t\t\tchildren = (\n"
2744 append aGroupSection $aSrcFileRefGuids
2745 append aGroupSection "\t\t\t);\n"
2746 append aGroupSection "\t\t\tname = $xlo;\n"
2747 append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
2748 append aGroupSection "\t\t\};\n"
2749
2750 # Storing packages IDs for adding them later as a child of toolkit
2751 append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
2752 }
2753
2754 # Removing unnecessary newline character from the end.
2755 set aPackagesGuids [string replace $aPackagesGuids end end]
2756
2757 return $aBuildFileSection
2758}
2759
2760# Creates folders structure and all necessary files for Xcode project.
2761proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
2762 set aPBXBuildPhase "Headers"
2763 set aRunOnlyForDeployment "0"
2764 set aProductType "library.dynamic"
2765 set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
2766 set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
2767 set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
050c18ac 2768 set aTKDefines [list "OCC_CONVERT_SIGNALS"]
d5265175 2769 if { $theIsStatic == 1 } {
2770 lappend aTKDefines "OCCT_NO_PLUGINS"
2771 }
c7d774c5 2772
2773 if { "$theTargetType" == "executable" } {
2774 set aPBXBuildPhase "CopyFiles"
2775 set aRunOnlyForDeployment "1"
2776 set aProductType "tool"
2777 set anExecExtension ""
2778 set anExecPrefix ""
2779 set aWrapperExtension ""
2780 } elseif { $theIsStatic == 1 } {
2781 set aProductType "library.static"
2782 set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
2783 set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
2784 }
2785
2786 set aUsername [exec whoami]
2787
2788 # Creation of folders for Xcode projectP.
2789 set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
2790 wokUtils:FILES:mkdir $aToolkitDir
2791 if { ! [file exists $aToolkitDir] } {
2792 puts stderr "Error: Could not create project directory \"$aToolkitDir\""
2793 return
2794 }
2795
2796 set aUserDataDir "${aToolkitDir}/xcuserdata"
2797 wokUtils:FILES:mkdir $aUserDataDir
2798 if { ! [file exists $aUserDataDir] } {
2799 puts stderr "Error: Could not create xcuserdata directorty in \"$aToolkitDir\""
2800 return
2801 }
2802
2803 set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
2804 wokUtils:FILES:mkdir $aUserDataDir
2805 if { ! [file exists $aUserDataDir] } {
2806 puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$aToolkitDir\"/xcuserdata"
2807 return
2808 }
2809
2810 set aSchemesDir "${aUserDataDir}/xcschemes"
2811 wokUtils:FILES:mkdir $aSchemesDir
2812 if { ! [file exists $aSchemesDir] } {
2813 puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
2814 return
2815 }
2816 # End of folders creation.
2817
2818 # Generating GUID for tookit.
2819 upvar $theGuidsMap aGuidsMap
2820 if { ! [info exists aGuidsMap($theToolKit)] } {
2821 set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
2822 }
2823
2824 # Creating xcscheme file for toolkit from template.
2825 set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
2826 regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
2827 regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
2828 set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme" "w"]
2829 puts $aXcschemeFile $aXcschemeTmpl
2830 close $aXcschemeFile
2831
2832 # Creating xcschememanagement.plist file for toolkit from template.
2833 set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
2834 regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
2835 regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
2836 set aPlistFile [open "$aSchemesDir/xcschememanagement.plist" "w"]
2837 puts $aPlistFile $aPlistTmpl
2838 close $aPlistFile
2839
2840 # Creating project.pbxproj file for toolkit.
2841 set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
2842 puts $aPbxprojFile "// !\$*UTF8*\$!"
2843 puts $aPbxprojFile "\{"
2844 puts $aPbxprojFile "\tarchiveVersion = 1;"
2845 puts $aPbxprojFile "\tclasses = \{"
2846 puts $aPbxprojFile "\t\};"
2847 puts $aPbxprojFile "\tobjectVersion = 46;"
2848 puts $aPbxprojFile "\tobjects = \{\n"
2849
2850 # Begin PBXBuildFile section
2851 set aPackagesGuids ""
2852 set aGroupSection ""
2853 set aSrcFileRefSection ""
2854 set aSrcFileGuids ""
2855 set aDepsFileRefSection ""
2856 set aDepsGuids ""
2857 set aDepsRefGuids ""
2858 set anIncPaths [list "../../../inc"]
2859 set anLibPaths ""
2860
2861 if { [info exists ::env(CSF_OPT_INC)] } {
2862 set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
2863 foreach anIncCfgPath $anIncCfg {
2864 lappend anIncPaths $anIncCfgPath
2865 }
2866 }
2867 if { [info exists ::env(CSF_OPT_LIB64)] } {
2868 set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
2869 foreach anLibCfgPath $anLibCfg {
2870 lappend anLibPaths $anLibCfgPath
2871 }
2872 }
2873
2874 puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
2875 puts $aPbxprojFile [osutils:xcdtk:deps $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $theIsStatic]
2876 # End PBXBuildFile section
2877
2878 # Begin PBXFileReference section
2879 set aToolkitLib "lib${theToolKit}.dylib"
2880 set aPath "$aToolkitLib"
2881 if { "$theTargetType" == "executable" } {
2882 set aPath "$theToolKit"
2883 } elseif { $theIsStatic == 1 } {
2884 set aToolkitLib "lib${theToolKit}.a"
2885 }
2886
2887 if { ! [info exists aGuidsMap($aToolkitLib)] } {
2888 set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
2889 }
2890
2891 puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
2892 puts $aPbxprojFile $aSrcFileRefSection
2893 puts $aPbxprojFile $aDepsFileRefSection
2894 # End PBXFileReference section
2895
2896
2897 # Begin PBXFrameworksBuildPhase section
2898 set aTkFrameworks "${theToolKit}_Frameworks"
2899 if { ! [info exists aGuidsMap($aTkFrameworks)] } {
2900 set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
2901 }
2902
2903 puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
2904 puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
2905 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2906 puts $aPbxprojFile "\t\t\tfiles = ("
2907 puts $aPbxprojFile $aDepsGuids
2908 puts $aPbxprojFile "\t\t\t);"
2909 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
2910 puts $aPbxprojFile "\t\t\};\n"
2911 # End PBXFrameworksBuildPhase section
2912
2913 # Begin PBXGroup section
2914 set aTkPBXGroup "${theToolKit}_PBXGroup"
2915 if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
2916 set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
2917 }
2918
2919 set aTkSrcGroup "${theToolKit}_SrcGroup"
2920 if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
2921 set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
2922 }
2923
2924 puts $aPbxprojFile $aGroupSection
2925 puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
2926 puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2927 puts $aPbxprojFile "\t\t\tchildren = ("
2928 puts $aPbxprojFile $aDepsRefGuids
2929 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
2930 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
2931 puts $aPbxprojFile "\t\t\t);"
2932 puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2933 puts $aPbxprojFile "\t\t\};"
2934 puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
2935 puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
2936 puts $aPbxprojFile "\t\t\tchildren = ("
2937 puts $aPbxprojFile $aPackagesGuids
2938 puts $aPbxprojFile "\t\t\t);"
2939 puts $aPbxprojFile "\t\t\tname = \"Source files\";"
2940 puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
2941 puts $aPbxprojFile "\t\t\};\n"
2942 # End PBXGroup section
2943
2944 # Begin PBXHeadersBuildPhase section
2945 set aTkHeaders "${theToolKit}_Headers"
2946 if { ! [info exists aGuidsMap($aTkHeaders)] } {
2947 set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
2948 }
2949
2950 puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
2951 puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
2952 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
2953 puts $aPbxprojFile "\t\t\tfiles = ("
2954 puts $aPbxprojFile "\t\t\t);"
2955 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
2956 puts $aPbxprojFile "\t\t\};\n"
2957 # End PBXHeadersBuildPhase section
2958
2959 # Begin PBXNativeTarget section
2960 set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
2961 if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
2962 set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
2963 }
2964
2965 set aTkSources "${theToolKit}_Sources"
2966 if { ! [info exists aGuidsMap($aTkSources)] } {
2967 set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
2968 }
2969
2970 puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
2971 puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
2972 puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
2973 puts $aPbxprojFile "\t\t\tbuildPhases = ("
2974 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
2975 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
2976 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
2977 puts $aPbxprojFile "\t\t\t);"
2978 puts $aPbxprojFile "\t\t\tbuildRules = ("
2979 puts $aPbxprojFile "\t\t\t);"
2980 puts $aPbxprojFile "\t\t\tdependencies = ("
2981 puts $aPbxprojFile "\t\t\t);"
2982 puts $aPbxprojFile "\t\t\tname = $theToolKit;"
2983 puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
2984 puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
2985 puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
2986 puts $aPbxprojFile "\t\t\};\n"
2987 # End PBXNativeTarget section
2988
2989 # Begin PBXProject section
2990 set aTkProjectObj "${theToolKit}_ProjectObj"
2991 if { ! [info exists aGuidsMap($aTkProjectObj)] } {
2992 set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
2993 }
2994
2995 set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
2996 if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
2997 set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
2998 }
2999
3000 puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
3001 puts $aPbxprojFile "\t\t\tisa = PBXProject;"
3002 puts $aPbxprojFile "\t\t\tattributes = \{"
3003 puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
3004 puts $aPbxprojFile "\t\t\t\};"
3005 puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
3006 puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
3007 puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
3008 puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
3009 puts $aPbxprojFile "\t\t\tknownRegions = ("
3010 puts $aPbxprojFile "\t\t\t\ten,"
3011 puts $aPbxprojFile "\t\t\t);"
3012 puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
3013 puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
3014 puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
3015 puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
3016 puts $aPbxprojFile "\t\t\ttargets = ("
3017 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
3018 puts $aPbxprojFile "\t\t\t);"
3019 puts $aPbxprojFile "\t\t\};\n"
3020 # End PBXProject section
3021
3022 # Begin PBXSourcesBuildPhase section
3023 puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
3024 puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
3025 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3026 puts $aPbxprojFile "\t\t\tfiles = ("
3027 puts $aPbxprojFile $aSrcFileGuids
3028 puts $aPbxprojFile "\t\t\t);"
3029 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3030 puts $aPbxprojFile "\t\t\};\n"
3031 # End PBXSourcesBuildPhase section
3032
3033 # Begin XCBuildConfiguration section
3034 set aTkDebugProject "${theToolKit}_DebugProject"
3035 if { ! [info exists aGuidsMap($aTkDebugProject)] } {
3036 set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
3037 }
3038
3039 set aTkReleaseProject "${theToolKit}_ReleaseProject"
3040 if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
3041 set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
3042 }
3043
3044 set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
3045 if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
3046 set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
3047 }
3048
3049 set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
3050 if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
3051 set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
3052 }
3053
3054 # Debug target
3055 puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
3056 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3057 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3058
3059 puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
3060 puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3061 if { "$thePlatform" == "ios" } {
3062 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3063 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
3064 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3065 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3066 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3067 }
3068 puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
3069 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
3070 puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
3071 puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3072 puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
3073 puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3074 puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
3075 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3076 puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
3077 puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
3078 puts $aPbxprojFile "\t\t\t\t);"
3079 puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
3080 puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3081 puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3082 puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3083 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3084 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3085 puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
3086 if { "$thePlatform" == "ios" } {
3087 puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
3088 puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3089 } else {
3090 puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
3091 }
3092 puts $aPbxprojFile "\t\t\t\};"
3093
3094 puts $aPbxprojFile "\t\t\tname = Debug;"
3095 puts $aPbxprojFile "\t\t\};"
3096
3097 # Release target
3098 puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
3099 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3100 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3101
3102 puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
3103 puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3104 if { "$thePlatform" == "ios" } {
3105 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3106 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
3107 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3108 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3109 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3110 }
3111 puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
3112 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";"
3113 puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
3114 puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3115 puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3116 puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
3117 puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
3118 puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3119 puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3120 puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3121 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3122 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3123 puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
3124 if { "$thePlatform" == "ios" } {
3125 puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
3126 puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3127 }
3128 puts $aPbxprojFile "\t\t\t\};"
3129 puts $aPbxprojFile "\t\t\tname = Release;"
3130 puts $aPbxprojFile "\t\t\};"
3131 puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
3132 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3133 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3134 puts $aPbxprojFile "${anExecExtension}"
3135 puts $aPbxprojFile "${anExecPrefix}"
3136 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3137 foreach aMacro $aTKDefines {
3138 puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3139 }
3140 puts $aPbxprojFile "\t\t\t\t);"
3141
3142 puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3143 foreach anIncPath $anIncPaths {
3144 puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3145 }
3146 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3147 puts $aPbxprojFile "\t\t\t\t);"
3148
3149 puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3150 foreach anLibPath $anLibPaths {
3151 puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3152 }
3153 puts $aPbxprojFile "\t\t\t\t);"
3154
3155 puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3156 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3157 puts $aPbxprojFile "\t\t\t\t);"
3158 puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3159 puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3160 puts $aPbxprojFile "\t\t\t\t);"
3161 puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3162 set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
3163 foreach anIncPath $anIncPaths {
3164 append anUserHeaderSearchPath " ${anIncPath}"
3165 }
3166 append anUserHeaderSearchPath "\";"
3167 puts $aPbxprojFile $anUserHeaderSearchPath
3168 puts $aPbxprojFile "${aWrapperExtension}"
3169 puts $aPbxprojFile "\t\t\t\};"
3170 puts $aPbxprojFile "\t\t\tname = Debug;"
3171 puts $aPbxprojFile "\t\t\};"
3172 puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
3173 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3174 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3175 puts $aPbxprojFile "${anExecExtension}"
3176 puts $aPbxprojFile "${anExecPrefix}"
3177 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3178 foreach aMacro $aTKDefines {
3179 puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3180 }
3181 puts $aPbxprojFile "\t\t\t\t);"
3182 puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3183 foreach anIncPath $anIncPaths {
3184 puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3185 }
3186 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3187 puts $aPbxprojFile "\t\t\t\t);"
3188
3189 puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3190 foreach anLibPath $anLibPaths {
3191 puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3192 }
3193 puts $aPbxprojFile "\t\t\t\t);"
3194
3195 puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3196 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3197 puts $aPbxprojFile "\t\t\t\t);"
3198 puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3199 puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3200 puts $aPbxprojFile "\t\t\t\t);"
3201 puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3202 puts $aPbxprojFile $anUserHeaderSearchPath
3203 puts $aPbxprojFile "${aWrapperExtension}"
3204 puts $aPbxprojFile "\t\t\t\};"
3205 puts $aPbxprojFile "\t\t\tname = Release;"
3206 puts $aPbxprojFile "\t\t\};\n"
3207 # End XCBuildConfiguration section
3208
3209 # Begin XCConfigurationList section
3210 puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
3211 puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3212 puts $aPbxprojFile "\t\tbuildConfigurations = ("
3213 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
3214 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
3215 puts $aPbxprojFile "\t\t\t);"
3216 puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3217 puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3218 puts $aPbxprojFile "\t\t\};"
3219 puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
3220 puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3221 puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
3222 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
3223 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
3224 puts $aPbxprojFile "\t\t\t);"
3225 puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3226 puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3227 puts $aPbxprojFile "\t\t\};\n"
3228 # End XCConfigurationList section
3229
3230 puts $aPbxprojFile "\t\};"
3231 puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3232 puts $aPbxprojFile "\}"
3233
3234 close $aPbxprojFile
3235}
3236
3237proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3238 set aUsername [exec whoami]
3239
3240 # Creating folders for Xcode project file.
3241 set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3242 wokUtils:FILES:mkdir $anExecutableDir
3243 if { ! [file exists $anExecutableDir] } {
3244 puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3245 return
3246 }
3247
3248 set aUserDataDir "${anExecutableDir}/xcuserdata"
3249 wokUtils:FILES:mkdir $aUserDataDir
3250 if { ! [file exists $aUserDataDir] } {
3251 puts stderr "Error: Could not create xcuserdata directorty in \"$anExecutableDir\""
3252 return
3253 }
3254
3255 set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3256 wokUtils:FILES:mkdir $aUserDataDir
3257 if { ! [file exists $aUserDataDir] } {
3258 puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$anExecutableDir\"/xcuserdata"
3259 return
3260 }
3261
3262 set aSchemesDir "${aUserDataDir}/xcschemes"
3263 wokUtils:FILES:mkdir $aSchemesDir
3264 if { ! [file exists $aSchemesDir] } {
3265 puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3266 return
3267 }
3268 # End folders creation.
3269
3270 # Generating GUID for tookit.
3271 upvar $theGuidsMap aGuidsMap
3272 if { ! [info exists aGuidsMap($theExecutable)] } {
3273 set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3274 }
3275
3276 # Creating xcscheme file for toolkit from template.
3277 set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3278 regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3279 regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3280 set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme" "w"]
3281 puts $aXcschemeFile $aXcschemeTmpl
3282 close $aXcschemeFile
3283
3284 # Creating xcschememanagement.plist file for toolkit from template.
3285 set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3286 regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3287 regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3288 set aPlistFile [open "$aSchemesDir/xcschememanagement.plist" "w"]
3289 puts $aPlistFile $aPlistTmpl
3290 close $aPlistFile
3291}
7fbac3c2 3292
3293# Returns available Windows SDKs versions
3294proc osutils:sdk { theSdkMajorVer {isQuietMode false} {theSdkDirectories {}} } {
3295 if { ![llength ${theSdkDirectories}] } {
3296 foreach anEnvVar { "ProgramFiles" "ProgramFiles\(x86\)" "ProgramW6432" } {
3297 if {[ info exists ::env(${anEnvVar}) ]} {
3298 lappend theSdkDirectories "$::env(${anEnvVar})/Windows Kits/${theSdkMajorVer}/Include"
3299 }
3300 }
3301 }
3302
3303 set sdk_versions {}
3304 foreach sdk_dir ${theSdkDirectories} {
3305 if { [file isdirectory ${sdk_dir}] } {
3306 lappend sdk_versions [glob -tails -directory "${sdk_dir}" -type d *]
3307 }
3308 }
3309
3310 if {![llength ${sdk_versions}] && !${isQuietMode}} {
3311 error "Error : Could not find Windows SDK ${theSdkMajorVer}"
3312 }
3313
3314 return [join [lsort -unique ${sdk_versions}] " "]
3315}
3316
3317# Generate global properties to Visual Studio project file for UWP solution
3318proc osutils:uwp:proj { theVcVer theProjTmpl } {
3319
3320 set uwp_properties ""
3321 set uwp_generate_metadata ""
3322 set uwp_app_container ""
3323
3324 set format_template ""
3325
3326 if { ${theVcVer} == "vc14-uwp" } {
3327 set sdk_versions [osutils:sdk 10]
3328 set sdk_max_ver [lindex ${sdk_versions} end]
3329
3330 set uwp_properties "<DefaultLanguage>en-US</DefaultLanguage>\n \
3331<ApplicationType>Windows Store</ApplicationType>\n \
3332<ApplicationTypeRevision>10.0</ApplicationTypeRevision>\n \
3333<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\n \
3334<AppContainerApplication>true</AppContainerApplication>\n \
3335<WindowsTargetPlatformVersion>${sdk_max_ver}</WindowsTargetPlatformVersion>\n \
3336<WindowsTargetPlatformMinVersion>${sdk_max_ver}</WindowsTargetPlatformMinVersion>"
3337
3338 set uwp_generate_metadata "<GenerateWindowsMetadata>false</GenerateWindowsMetadata>"
3339
3340 regsub -all -- {[\r\n\s]*<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>} ${theProjTmpl} "" theProjTmpl
3341 } else {
3342 set format_template "\[\\r\\n\\s\]*"
3343 }
3344
3345 regsub -all -- "${format_template}__UWP_PROPERTIES__" ${theProjTmpl} "${uwp_properties}" theProjTmpl
3346 regsub -all -- "${format_template}__UWP_GENERATE_METADATA__" ${theProjTmpl} "${uwp_generate_metadata}" theProjTmpl
3347
3348 return ${theProjTmpl}
3349}
5da3dfdf 3350
3351# Report all files found in package directory but not listed in FILES
3352proc osutils:checksrcfiles { theUnit } {
3353 global path
3354 set aCasRoot [file normalize ${path}]
3355
3356 if {![file isdirectory ${aCasRoot}]} {
3357 puts "OCCT directory is not defined correctly: ${aCasRoot}"
3358 return
3359 }
3360
3361 set anUnitAbsPath [file normalize "${aCasRoot}/src/${theUnit}"]
3362
3363 if {[file exists "${anUnitAbsPath}/FILES"]} {
3364 set aFilesFile [open "${anUnitAbsPath}/FILES" rb]
3365 set aFilesFileList [split [read ${aFilesFile}] "\n"]
3366 close ${aFilesFile}
3367
3368 set aFilesFileList [lsearch -inline -all -not -exact ${aFilesFileList} ""]
3369
3370 # report all files not listed in FILES
3371 set anAllFiles [glob -tails -nocomplain -dir ${anUnitAbsPath} "*"]
3372 foreach aFile ${anAllFiles} {
3373 if { "${aFile}" == "FILES" } {
3374 continue
3375 }
3376 if { [lsearch -exact ${aFilesFileList} ${aFile}] == -1 } {
3377 puts "Warning: file ${anUnitAbsPath}/${aFile} is not listed in ${anUnitAbsPath}/FILES!"
3378 }
3379 }
3380 }
3381}