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