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