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