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