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