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