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