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