0031471: Confuguration, genproj - unable to build OCC Products
[occt.git] / adm / genproj.tcl
CommitLineData
910970ab 1# =======================================================================
d1a67b9d 2# Created on: 2014-07-24
3# Created by: SKI
4# Copyright (c) 2014 OPEN CASCADE SAS
5#
6# This file is part of Open CASCADE Technology software library.
7#
8# This library is free software; you can redistribute it and/or modify it under
9# the terms of the GNU Lesser General Public License version 2.1 as published
10# by the Free Software Foundation, with special exception defined in the file
11# OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12# distribution for complete text of the license and disclaimer of any warranty.
13#
14# Alternatively, this file may be used under the terms of Open CASCADE
15# commercial license or contractual agreement.
16
17# =======================================================================
18# This script defines Tcl command genproj generating project files for
944d808c 19# different IDEs and platforms. Run it with -help to get synopsis.
910970ab 20# =======================================================================
21
d1a67b9d 22source [file join [file dirname [info script]] genconfdeps.tcl]
23
944d808c 24# the script is assumed to be run from CASROOT (or dependent Products root)
25set path [file normalize .]
e31a8e52 26set THE_CASROOT ""
910970ab 27set fBranch ""
e31a8e52 28if { [info exists ::env(CASROOT)] } {
471a2ca0 29 set THE_CASROOT [file normalize "$::env(CASROOT)"]
e31a8e52 30}
c7d774c5 31
910970ab 32proc _get_options { platform type branch } {
910970ab 33 set res ""
e31a8e52 34 if {[file exists "$::THE_CASROOT/adm/CMPLRS"]} {
35 set fd [open "$::THE_CASROOT/adm/CMPLRS" rb]
910970ab 36 set opts [split [read $fd] "\n"]
37 close $fd
38 foreach line $opts {
39 if {[regexp "^${platform} ${type} ${branch} (.+)$" $line dummy res]} {
40 while {[regexp {\(([^\(\)]+) ([^\(\)]+) ([^\(\)]+)\)(.+)} $res dummy p t b oldres]} {
41 set res "[_get_options $p $t $b] $oldres"
42 }
43 }
44 }
45 }
46 return $res
47}
48
49proc _get_type { name } {
e31a8e52 50 set UDLIST {}
51 if {[file exists "$::path/adm/UDLIST"]} {
52 set fd [open "$::path/adm/UDLIST" rb]
53 set UDLIST [concat $UDLIST [split [read $fd] "\n"]]
910970ab 54 close $fd
e31a8e52 55 }
56 if { "$::path/adm/UDLIST" != "$::THE_CASROOT/adm/UDLIST" && [file exists "$::THE_CASROOT/adm/UDLIST"] } {
57 set fd [open "$::THE_CASROOT/adm/UDLIST" rb]
58 set UDLIST [concat $UDLIST [split [read $fd] "\n"]]
59 close $fd
60 }
61
62 foreach uitem $UDLIST {
63 set line [split $uitem]
64 if {[lindex $line 1] == "$name"} {
65 return [lindex $line 0]
910970ab 66 }
67 }
68 return ""
69}
70
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 }
27bd52b5 1443 if { "$::HAVE_E57" == "true" && "$theOS" != "wnt" } {
1444 # exclude wnt, as there are different pragma lib depending on debug/release
1445 set aLibsMap(CSF_E57) "E57RefImpl"
1446 set aLibsMap(CSF_xerces) "xerces-c"
1447 }
7c65581d 1448
910970ab 1449 if { "$theOS" == "wnt" } {
c7d774c5 1450 # WinAPI libraries
7c65581d 1451 set aLibsMap(CSF_kernel32) "kernel32"
1452 set aLibsMap(CSF_advapi32) "advapi32"
1453 set aLibsMap(CSF_gdi32) "gdi32"
1454 set aLibsMap(CSF_user32) "user32 comdlg32"
f4d20b00 1455 set aLibsMap(CSF_shell32) "shell32"
7c65581d 1456 set aLibsMap(CSF_opengl32) "opengl32"
1457 set aLibsMap(CSF_wsock32) "wsock32"
1458 set aLibsMap(CSF_netapi32) "netapi32"
98e6c6d1 1459 set aLibsMap(CSF_winmm) "winmm"
7c65581d 1460 set aLibsMap(CSF_OpenGlLibs) "opengl32"
1ce0716b 1461 if { "$::HAVE_GLES2" == "true" } {
1462 set aLibsMap(CSF_OpenGlLibs) "libEGL libGLESv2"
1463 }
7c65581d 1464 set aLibsMap(CSF_psapi) "Psapi"
1465 set aLibsMap(CSF_d3d9) "d3d9"
1466
1467 # the naming is different on Windows
1468 set aLibsMap(CSF_TclLibs) "tcl86"
1469 set aLibsMap(CSF_TclTkLibs) "tk86"
f6d8ca74 1470 if { "$theRelease" == "true" } {
1471 set aLibsMap(CSF_QT) "Qt5Gui Qt5Widgets Qt5Xml Qt5Core"
1472 } else {
1473 set aLibsMap(CSF_QT) "Qt5Guid Qt5Widgetsd Qt5Xmld Qt5Cored"
1474 }
7c65581d 1475
1476 # tbb headers define different pragma lib depending on debug/release
1477 set aLibsMap(CSF_TBB) ""
6a56fe92 1478
1479 if { "$::HAVE_ZLIB" == "true" } {
1480 set aLibsMap(CSF_ZLIB) "zlib"
1481 }
910970ab 1482 } else {
41f97958 1483 set aLibsMap(CSF_dl) "dl"
48ba1811 1484 if { "$theOS" == "mac" || "$theOS" == "ios" } {
c7d774c5 1485 set aLibsMap(CSF_objc) "objc"
48ba1811 1486 if { "$theOS" == "ios" } {
1487 set aFrmsMap(CSF_Appkit) "UIKit"
1488 set aFrmsMap(CSF_OpenGlLibs) "OpenGLES"
1489 } else {
1490 set aFrmsMap(CSF_Appkit) "AppKit"
1491 set aFrmsMap(CSF_OpenGlLibs) "OpenGL"
1492 }
c7d774c5 1493 set aFrmsMap(CSF_IOKit) "IOKit"
c7d774c5 1494 set aFrmsMap(CSF_TclLibs) "Tcl"
7c65581d 1495 set aLibsMap(CSF_TclLibs) ""
c7d774c5 1496 set aFrmsMap(CSF_TclTkLibs) "Tk"
7c65581d 1497 set aLibsMap(CSF_TclTkLibs) ""
14bbbdcb 1498 set aLibsMap(CSF_QT) "QtCore QtGui"
a6a66c3a 1499 } elseif { "$theOS" == "android" } {
1500 set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
1501 set aLibsMap(CSF_androidlog) "log"
c7d774c5 1502 } else {
c9983ee8 1503 set aLibsMap(CSF_fontconfig) "fontconfig"
d8d01f6e 1504 if { "$theOS" == "qnx" } {
7c65581d 1505 # CSF_ThreadLibs - pthread API is part of libc on QNX
d8d01f6e 1506 set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
d8d01f6e 1507 } else {
1508 set aLibsMap(CSF_ThreadLibs) "pthread rt"
1509 set aLibsMap(CSF_OpenGlLibs) "GL"
d8d01f6e 1510 set aLibsMap(CSF_TclTkLibs) "X11 tk8.6"
1511 set aLibsMap(CSF_XwLibs) "X11 Xext Xmu Xi"
1512 set aLibsMap(CSF_MotifLibs) "X11"
1513 }
1ce0716b 1514
1515 if { "$::HAVE_GLES2" == "true" } {
1516 set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
1517 }
910970ab 1518 }
910970ab 1519 }
1520}
1521
1c29294e 1522# Returns string of library dependencies for generation of Visual Studio project or make lists.
1523proc osutils:vtkCsf {{theOS ""}} {
1524 set aVtkVer "6.1"
1525
1c29294e 1526 set aPathSplitter ":"
1c29294e 1527 if {"$theOS" == "wnt"} {
1528 set aPathSplitter ";"
1c29294e 1529 }
1530
1531 set anOptIncs [split $::env(CSF_OPT_INC) "$aPathSplitter"]
1532 foreach anIncItem $anOptIncs {
1533 if {[regexp -- "vtk-(.*)$" [file tail $anIncItem] dummy aFoundVtkVer]} {
1534 set aVtkVer $aFoundVtkVer
1535 }
1536 }
1537
1538 set aLibArray [list vtkCommonCore vtkCommonDataModel vtkCommonExecutionModel vtkCommonMath vtkCommonTransforms vtkRenderingCore \
1539 vtkRenderingOpenGL vtkFiltersGeneral vtkIOCore vtkIOImage vtkImagingCore vtkInteractionStyle]
1540
1541 # Additional suffices for the libraries
1542 set anIdx 0
1543 foreach anItem $aLibArray {
7c65581d 1544 lset aLibArray $anIdx $anItem-$aVtkVer
1c29294e 1545 incr anIdx
1546 }
1547
1548 return [join $aLibArray " "]
1549}
1550
c7d774c5 1551# @param theLibsList - dependencies (libraries list)
1552# @param theFrameworks - dependencies (frameworks list, OS X specific)
f6d8ca74 1553proc osutils:usedOsLibs { theToolKit theOS theLibsList theFrameworks theSrcDir { theRelease true } } {
910970ab 1554 global path
c7d774c5 1555 upvar $theLibsList aLibsList
1556 upvar $theFrameworks aFrameworks
1557 set aLibsList [list]
1558 set aFrameworks [list]
910970ab 1559
f6d8ca74 1560 osutils:csfList $theOS aLibsMap aFrmsMap $theRelease
910970ab 1561
f6d8ca74 1562 foreach aCsfElem [osutils:tk:csfInExternlib "$path/$theSrcDir/${theToolKit}/EXTERNLIB"] {
c7d774c5 1563 if [info exists aLibsMap($aCsfElem)] {
1564 foreach aLib [split "$aLibsMap($aCsfElem)"] {
1565 if { [lsearch $aLibsList $aLib] == "-1" } {
1566 lappend aLibsList $aLib
1567 }
1568 }
910970ab 1569 }
c7d774c5 1570 if [info exists aFrmsMap($aCsfElem)] {
1571 foreach aFrm [split "$aFrmsMap($aCsfElem)"] {
1572 if { [lsearch $aFrameworks $aFrm] == "-1" } {
1573 lappend aFrameworks $aFrm
1574 }
910970ab 1575 }
1576 }
1577 }
910970ab 1578}
1579
1580# Returns liste of UD in a toolkit. tkloc is a full path wok.
f6d8ca74 1581proc osutils:tk:units { tkloc theSrcDir } {
910970ab 1582 global path
1583 set l {}
f6d8ca74 1584 set PACKAGES "$path/$theSrcDir/$tkloc/PACKAGES"
910970ab 1585 foreach u [wokUtils:FILES:FileToList $PACKAGES] {
f6d8ca74 1586 if {[file isdirectory "$path/$theSrcDir/$u"]} {
910970ab 1587 lappend l $u
1588 }
1589 }
1590 if { $l == {} } {
1591 ;#puts stderr "Warning. No devunit included in $tkloc"
1592 }
1593 return $l
1594}
1595
1596proc osutils:justwnt { listloc } {
cf4bee7c 1597 set goaway [list Xw]
910970ab 1598 return [osutils:juststation $goaway $listloc]
1599}
1600
1601# remove from listloc OpenCascade units indesirables on NT
1602proc osutils:juststation {goaway listloc} {
1603 global path
1604 set lret {}
1605 foreach u $listloc {
1606 if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1607 || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1608 lappend lret $u
1609 }
1610 }
1611 return $lret
1612}
1613
1614# intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1615# The first list is everything in the first list that wasn't in the second,
1616# the second list contains the intersection of the two lists, the third list contains everything
1617# in the second list that wasn't in the first.
1618proc osutils:intersect3 {list1 list2} {
1619 set la1(0) {} ; unset la1(0)
1620 set lai(0) {} ; unset lai(0)
1621 set la2(0) {} ; unset la2(0)
1622 foreach v $list1 {
1623 set la1($v) {}
1624 }
1625 foreach v $list2 {
1626 set la2($v) {}
1627 }
1628 foreach elem [concat $list1 $list2] {
1629 if {[info exists la1($elem)] && [info exists la2($elem)]} {
1630 unset la1($elem)
1631 unset la2($elem)
1632 set lai($elem) {}
1633 }
1634 }
1635 list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1636}
1637
1638# Prepare relative path
1639proc relativePath {thePathFrom thePathTo} {
1640 if { [file isdirectory "$thePathFrom"] == 0 } {
1641 return ""
1642 }
1643
1644 set aPathFrom [file normalize "$thePathFrom"]
1645 set aPathTo [file normalize "$thePathTo"]
1646
1647 set aCutedPathFrom "${aPathFrom}/dummy"
1648 set aRelatedDeepPath ""
1649
1650 while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1651 set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1652 # does aPathTo contain aCutedPathFrom?
1653 regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1654 if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1655 if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1656 set aPathTo ".${aPathTo}"
1657 } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1658 set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1659 }
1660 regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1661 regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1662 return $aPathToAfterCut
1663 }
1664 set aRelatedDeepPath "$aRelatedDeepPath../"
1665
1666 }
1667
1668 return $thePathTo
1669}
1670
1671proc wokUtils:EASY:bs1 { s } {
1672 regsub -all {/} $s {\\} r
1673 return $r
1674}
1675
1676# Returs for a full path the liste of n last directory part
1677# n = 1 => tail
1678# n = 2 => dir/file.c
1679# n = 3 => sdir/dir/file.c
1680# etc..
1681proc wokUtils:FILES:wtail { f n } {
1682 set ll [expr [llength [set lif [file split $f]]] -$n]
1683 return [join [lrange $lif $ll end] /]
1684}
1685
1686# Generate entry for one source file in Visual Studio 10 project file
f6d8ca74 1687proc osutils:vcxproj:cxxfile { theFile theParams theSrcFileLevel } {
cf4bee7c 1688 if { $theParams == "" } {
f6d8ca74 1689 return " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile $theSrcFileLevel]]\" />\n"
910970ab 1690 }
1691
cf4bee7c 1692 set aParams [string trim ${theParams}]
1693 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1694 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1695 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1696 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1697 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
910970ab 1698 append text " </ClCompile>\n"
1699 return $text
1700}
1701
cf4bee7c 1702# Generate entry for one header file in Visual Studio 10 project file
1703proc osutils:vcxproj:hxxfile { theFile } { return " <ClInclude Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\" />\n" }
1704
910970ab 1705# Generate Visual Studio 2010 project filters file
cf4bee7c 1706proc osutils:vcxproj:filters { dir proj theCxxFilesMap theHxxFilesMap } {
1707 upvar $theCxxFilesMap aCxxFilesMap
1708 upvar $theHxxFilesMap aHxxFilesMap
910970ab 1709
1710 # header
1711 append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1712 append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1713
1714 # list of "filters" (units)
1715 append text " <ItemGroup>\n"
1716 append text " <Filter Include=\"Source files\">\n"
1717 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1718 append text " </Filter>\n"
cf4bee7c 1719 append text " <Filter Include=\"Header files\">\n"
1720 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1721 append text " </Filter>\n"
1722 foreach unit $aCxxFilesMap(units) {
910970ab 1723 append text " <Filter Include=\"Source files\\${unit}\">\n"
1724 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1725 append text " </Filter>\n"
1726 }
cf4bee7c 1727 foreach unit $aHxxFilesMap(units) {
1728 append text " <Filter Include=\"Header files\\${unit}\">\n"
1729 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1730 append text " </Filter>\n"
1731 }
910970ab 1732 append text " </ItemGroup>\n"
1733
cf4bee7c 1734 # list of cxx files
910970ab 1735 append text " <ItemGroup>\n"
cf4bee7c 1736 foreach unit $aCxxFilesMap(units) {
1737 foreach file $aCxxFilesMap($unit) {
910970ab 1738 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1739 append text " <Filter>Source files\\${unit}</Filter>\n"
1740 append text " </ClCompile>\n"
1741 }
1742 }
1743 append text " </ItemGroup>\n"
1744
cf4bee7c 1745 # list of hxx files
910970ab 1746 append text " <ItemGroup>\n"
cf4bee7c 1747 foreach unit $aHxxFilesMap(units) {
1748 foreach file $aHxxFilesMap($unit) {
1749 append text " <ClInclude Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1750 append text " <Filter>Header files\\${unit}</Filter>\n"
1751 append text " </ClInclude>\n"
910970ab 1752 }
1753 }
1754 append text " </ItemGroup>\n"
1755
1756 append text " <ItemGroup>\n"
cf4bee7c 1757 append text " <ResourceCompile Include=\"${proj}.rc\" />\n"
910970ab 1758 append text " </ItemGroup>\n"
1759
1760 # end
1761 append text "</Project>"
1762
1763 # write file
1764 set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1765 fconfigure $fp -translation crlf
1766 puts $fp $text
1767 close $fp
1768
1769 return ${proj}.vcxproj.filters
1770}
1771
1772# Generate RC file content for ToolKit from template
1773proc osutils:readtemplate:rc {theOutDir theToolKit} {
e31a8e52 1774 set aLoc "$::THE_CASROOT/adm/templates/template_dll.rc"
910970ab 1775 set aBody [wokUtils:FILES:FileToString $aLoc]
1776 regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1777
1778 set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1779 fconfigure $aFile -translation lf
1780 puts $aFile $aBody
1781 close $aFile
1782 return "${theOutDir}/${theToolKit}.rc"
1783}
1784
1785# Generate Visual Studio project file for ToolKit
f6d8ca74 1786proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap theSrcDir theSourceDirOther } {
1787 global path
1788
1789 set aHasQtDep "false"
1790 foreach aCsfElem [osutils:tk:csfInExternlib "$path/$theSrcDir/${theToolKit}/EXTERNLIB"] {
1791 if { "$aCsfElem" == "CSF_QT" } {
1792 set aHasQtDep "true"
1793 }
1794 }
d6cda17a 1795 set theProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 0]
910970ab 1796
944d808c 1797 set l_compilable [osutils:compilable wnt]
910970ab 1798 regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1799
1800 upvar $theGuidsMap aGuidsMap
1801 if { ! [info exists aGuidsMap($theToolKit)] } {
1802 set aGuidsMap($theToolKit) [OS:genGUID]
1803 }
1804 regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1805
d6cda17a 1806 set theProjTmpl [osutils:uwp:proj $isUWP ${theProjTmpl}]
7fbac3c2 1807
7c65581d 1808 set aUsedLibs [list]
7fbac3c2 1809
d6cda17a 1810 if { $isUWP } {
7fbac3c2 1811 lappend aUsedLibs "WindowsApp.lib"
1812 }
1813
f6d8ca74 1814 foreach tkx [osutils:commonUsedTK $theToolKit $theSrcDir $theSourceDirOther] {
7c65581d 1815 lappend aUsedLibs "${tkx}.lib"
910970ab 1816 }
1817
f6d8ca74 1818 set anOsReleaseLibs {}
1819 set anOsDebugLibs {}
1820 osutils:usedOsLibs $theToolKit "wnt" anOsReleaseLibs aFrameworks $theSrcDir true
1821 osutils:usedOsLibs $theToolKit "wnt" anOsDebugLibs aFrameworks $theSrcDir false
910970ab 1822
1823 # correct names of referred third-party libraries that are named with suffix
1824 # depending on VC version
f6d8ca74 1825 regsub -all -- {__TKDEP__} $theProjTmpl [osutils:depLibraries $aUsedLibs $anOsReleaseLibs $theVcVer] theProjTmpl
1826 regsub -all -- {__TKDEP_DEBUG__} $theProjTmpl [osutils:depLibraries $aUsedLibs $anOsDebugLibs $theVcVer] theProjTmpl
910970ab 1827
1828 set anIncPaths "..\\..\\..\\inc"
68df8478 1829# set aTKDefines ""
910970ab 1830 set aFilesSection ""
cf4bee7c 1831 set aVcFilesCxx(units) ""
1832 set aVcFilesHxx(units) ""
f6d8ca74 1833 set listloc [osutils:tk:units $theToolKit $theSrcDir]
910970ab 1834 if [array exists written] { unset written }
1835 #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1836 #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1837 #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1838 #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1839 set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1840 set fxloparamfc [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1841 set fxloparam ""
cf4bee7c 1842 foreach fxlo $listloc {
910970ab 1843 set xlo $fxlo
f6d8ca74 1844 set aSrcFiles [osutils:tk:cxxfiles $xlo wnt $theSrcDir]
1845 set aHxxFiles [osutils:tk:hxxfiles $xlo wnt $theSrcDir]
1846
1847 # prepare Qt moc files, appears only in Inspector - directory tools
1848 set aGeneratedFiles {}
1849 if { "$aHasQtDep" == "true" } {
1850 set aMocResFiles [osutils:tk:mocfiles $aHxxFiles $theOutDir]
1851 set aGeneratedFiles [osutils:tk:execfiles $aMocResFiles $theOutDir moc${::SYS_EXE_SUFFIX} moc cpp]
1852
1853 set aQrcResFiles [osutils:tk:qrcfiles $xlo wnt $theSrcDir]
1854 set aQrcFiles [osutils:tk:execfiles $aQrcResFiles $theOutDir rcc${::SYS_EXE_SUFFIX} rcc cpp]
1855 foreach resFile $aQrcFiles {
1856 lappend aGeneratedFiles $resFile
1857 }
1858 }
1859
1860 set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
910970ab 1861 if {$fxlo_cmplrs_options_cxx == ""} {
1862 set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1863 }
1864 set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1865 if {$fxlo_cmplrs_options_c == ""} {
1866 set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1867 }
1868 set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1869 set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1870 #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1871 #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo CXX"
1872 #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1873 #puts "\t6 [wokparam -v %CMPLRS_C_Options $fxlo] $fxlo C"
1874 set needparam ""
1875 foreach partopt $fxloparam {
1876 if {[string first "-I" $partopt] == "0"} {
1877 # this is an additional includes search path
1878 continue
1879 }
1880 set needparam "$needparam $partopt"
1881 }
1882
39bff09c 1883 # Format of projects in vc10+ is different from vc7-9
1884 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
910970ab 1885 foreach aSrcFile [lsort $aSrcFiles] {
1886 if { ![info exists written([file tail $aSrcFile])] } {
1887 set written([file tail $aSrcFile]) 1
f6d8ca74 1888 append aFilesSection [osutils:vcxproj:cxxfile $aSrcFile $needparam 3]
910970ab 1889 } else {
1890 puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1891 }
cf4bee7c 1892 if { ! [info exists aVcFilesCxx($xlo)] } { lappend aVcFilesCxx(units) $xlo }
1893 lappend aVcFilesCxx($xlo) $aSrcFile
1894 }
1895 foreach aHxxFile [lsort $aHxxFiles] {
1896 if { ![info exists written([file tail $aHxxFile])] } {
1897 set written([file tail $aHxxFile]) 1
1898 append aFilesSection [osutils:vcxproj:hxxfile $aHxxFile]
1899 } else {
1900 puts "Warning : in vcproj more than one occurences for [file tail $aHxxFile]"
1901 }
1902 if { ! [info exists aVcFilesHxx($xlo)] } { lappend aVcFilesHxx(units) $xlo }
1903 lappend aVcFilesHxx($xlo) $aHxxFile
910970ab 1904 }
f6d8ca74 1905 foreach aGenFile [lsort $aGeneratedFiles] {
1906 if { ![info exists written([file tail $aGenFile])] } {
1907 set written([file tail $aGenFile]) 1
1908 append aFilesSection [osutils:vcxproj:cxxfile $aGenFile $needparam 5]
1909 } else {
1910 puts "Warning : in vcproj more than one occurences for [file tail $aGenFile]"
1911 }
1912 if { ! [info exists aVcFilesCxx($xlo)] } { lappend aVcFilesCxx(units) $xlo }
1913 lappend aVcFilesCxx($xlo) $aGenFile
1914 }
910970ab 1915 } else {
1916 append aFilesSection "\t\t\t<Filter\n"
1917 append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1918 append aFilesSection "\t\t\t\t>\n"
1919 foreach aSrcFile [lsort $aSrcFiles] {
1920 if { ![info exists written([file tail $aSrcFile])] } {
1921 set written([file tail $aSrcFile]) 1
1922 append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1923 } else {
1924 puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
1925 }
1926 }
1927 append aFilesSection "\t\t\t</Filter>\n"
1928 }
910970ab 1929 }
1930
1931 regsub -all -- {__TKINC__} $theProjTmpl $anIncPaths theProjTmpl
910970ab 1932 regsub -all -- {__FILES__} $theProjTmpl $aFilesSection theProjTmpl
1933
1934 # write file
1935 set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1936 fconfigure $aFile -translation crlf
1937 puts $aFile $theProjTmpl
1938 close $aFile
1939
39bff09c 1940 # write filters file for vc10+
cf4bee7c 1941 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1942 lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesCxx aVcFilesHxx]
910970ab 1943 }
1944
1945 # write resource file
1946 lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1947
1948 return $aVcFiles
1949}
1950
f6d8ca74 1951# Appends OS libraries into the list of used libraries.
1952# Corrects list of referred third-party libraries that are named with suffix
1953# depending on VC version
1954# Unites list of used libraries into a variable with separator for VStudio older than vc9
1955# @param theUsedLibs List of libraries, to be changed
1956# @param theOsLibs List of Os library names, before using an extension should be added
1957# @param theVcVer version of VStudio
1958
1959proc osutils:depLibraries { theUsedLibs theOsLibs theVcVer } {
1960 foreach aLibIter $theOsLibs {
1961 lappend theUsedLibs "${aLibIter}.${::SYS_LIB_SUFFIX}"
1962 }
1963
1964 # correct names of referred third-party libraries that are named with suffix
1965 # depending on VC version
1966 set aVCRTVer [string range $theVcVer 0 3]
1967 regsub -all -- {vc[0-9]+} $theUsedLibs $aVCRTVer theUsedLibs
1968
1969 # and put this list to project file
1970 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1971 set theUsedLibs [join $theUsedLibs {;}]
1972 }
1973
1974 return $theUsedLibs
1975}
1976
910970ab 1977# for a unit returns a map containing all its file in the current
1978# workbench
1979# local = 1 only local files
f6d8ca74 1980proc osutils:tk:loadunit { loc map theSrcDir} {
910970ab 1981 #puts $loc
1982 upvar $map TLOC
1983 catch { unset TLOC }
f6d8ca74 1984 set lfiles [_get_used_files $loc $theSrcDir]
910970ab 1985 foreach f $lfiles {
1986 #puts "\t$f"
1987 set t [lindex $f 0]
1988 set p [lindex $f 2]
1989 if [info exists TLOC($t)] {
1990 set l $TLOC($t)
1991 lappend l $p
1992 set TLOC($t) $l
1993 } else {
1994 set TLOC($t) $p
1995 }
1996 }
1997 return
1998}
1999
cf4bee7c 2000# Returns the list of all files name in a toolkit within specified list of file extensions.
f6d8ca74 2001proc osutils:tk:files { tkloc theExtensions theSrcDir } {
910970ab 2002 set Tfiles(source,nocdlpack) {source pubinclude}
2003 set Tfiles(source,toolkit) {}
2004 set Tfiles(source,executable) {source pubinclude}
f6d8ca74 2005 set listloc [concat [osutils:tk:units $tkloc $theSrcDir] $tkloc ]
910970ab 2006 #puts " listloc = $listloc"
944d808c 2007
944d808c 2008 set resultloc $listloc
910970ab 2009 set lret {}
2010 foreach loc $resultloc {
2011 set utyp [_get_type $loc]
2012 #puts "\"$utyp\" \"$loc\""
2013 switch $utyp {
2014 "t" { set utyp "toolkit" }
2015 "n" { set utyp "nocdlpack" }
2016 "x" { set utyp "executable" }
8c7fab9b 2017 default { error "Error: Cannot determine type of unit $loc, check adm/UDLIST!" }
910970ab 2018 }
2019 if [array exists map] { unset map }
f6d8ca74 2020 osutils:tk:loadunit $loc map $theSrcDir
910970ab 2021 #puts " loc = $loc === > [array names map]"
2022 set LType $Tfiles(source,${utyp})
2023 foreach typ [array names map] {
2024 if { [lsearch $LType $typ] == -1 } {
2025 unset map($typ)
2026 }
2027 }
2028 foreach type [array names map] {
2029 #puts $type
2030 foreach f $map($type) {
2031 #puts $f
cf4bee7c 2032 if { [lsearch $theExtensions [file extension $f]] != -1 } {
944d808c 2033 lappend lret $f
910970ab 2034 }
2035 }
2036 }
2037 }
2038 return $lret
2039}
2040
cf4bee7c 2041# Returns the list of all compilable files name in a toolkit.
f6d8ca74 2042proc osutils:tk:cxxfiles { tkloc thePlatform theSrcDir } { return [osutils:tk:files $tkloc [osutils:compilable $thePlatform] $theSrcDir] }
cf4bee7c 2043
2044# Returns the list of all header files name in a toolkit.
f6d8ca74 2045proc osutils:tk:hxxfiles { tkloc thePlatform theSrcDir } { return [osutils:tk:files $tkloc [osutils:fileExtensionsHeaders $thePlatform] $theSrcDir] }
2046
2047# Returns the list of all resource (qrc) files name in a toolkit.
2048proc osutils:tk:qrcfiles { tkloc thePlatform theSourceDir } { return [osutils:tk:files $tkloc [osutils:fileExtensionsResources $thePlatform] $theSourceDir] }
2049
2050# Returns the list of all header files name in a toolkit.
2051proc osutils:tk:mocfiles { HxxFiles theOutDir } {
2052 set lret {}
2053 foreach file $HxxFiles {
2054 # processing only files where Q_OBJECT exists
2055 set fd [open "$file" rb]
2056 set FILES [split [read $fd] "\n"]
2057 close $fd
2058
2059 set isQObject [expr [regexp "Q_OBJECT" $FILES]]
2060 if { ! $isQObject } {
2061 continue;
2062 }
2063 lappend lret $file
2064 }
2065 return $lret
2066}
2067
2068# Returns the list of all header files name in a toolkit.
2069proc osutils:tk:execfiles { theFiles theOutDir theCommand thePrefix theExtension} {
2070 set lret {}
2071 set anOutDir $theOutDir/$thePrefix
2072 file mkdir $anOutDir
2073
2074 foreach file $theFiles {
2075 set aResourceName [file tail $file]
2076 set anOutFile $anOutDir/${thePrefix}_[file rootname $aResourceName].$theExtension
2077
2078 exec $theCommand $file -o $anOutFile
2079 lappend lret $anOutFile
2080 }
2081 return $lret
2082}
cf4bee7c 2083
910970ab 2084# Generate Visual Studio project file for executable
f6d8ca74 2085proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap theSrcDir theSourceDirOther } {
910970ab 2086 set aVcFiles {}
f6d8ca74 2087 foreach f [osutils:tk:cxxfiles $theToolKit wnt $theSrcDir] {
d6cda17a 2088 set aProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 1]
2089
910970ab 2090 set aProjName [file rootname [file tail $f]]
944d808c 2091 set l_compilable [osutils:compilable wnt]
910970ab 2092 regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
2093
2094 upvar $theGuidsMap aGuidsMap
2095 if { ! [info exists aGuidsMap($aProjName)] } {
2096 set aGuidsMap($aProjName) [OS:genGUID]
2097 }
2098 regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
2099
7c65581d 2100 set aUsedLibs [list]
f6d8ca74 2101 foreach tkx [osutils:commonUsedTK $theToolKit $theSrcDir $theSourceDirOther] {
7c65581d 2102 lappend aUsedLibs "${tkx}.lib"
910970ab 2103 }
2104
f6d8ca74 2105 set anOsReleaseLibs {}
2106 set anOsDebugLibs {}
2107 osutils:usedOsLibs $theToolKit "wnt" anOsReleaseLibs aFrameworks $theSrcDir true
2108 osutils:usedOsLibs $theToolKit "wnt" anOsDebugLibs aFrameworks $theSrcDir false
910970ab 2109
d6cda17a 2110 set aVCRTVer [string range $theVcVer 0 3]
f6d8ca74 2111 regsub -all -- {__TKDEP__} $aProjTmpl [osutils:depLibraries $aUsedLibs $anOsReleaseLibs $theVcVer] aProjTmpl
2112 regsub -all -- {__TKDEP_DEBUG__} $aProjTmpl [osutils:depLibraries $aUsedLibs $anOsDebugLibs $theVcVer] aProjTmpl
910970ab 2113
2114 set aFilesSection ""
cf4bee7c 2115 set aVcFilesCxx(units) ""
2116 set aVcFilesHxx(units) ""
910970ab 2117
2118 if { ![info exists written([file tail $f])] } {
2119 set written([file tail $f]) 1
2120
39bff09c 2121 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
f6d8ca74 2122 append aFilesSection [osutils:vcxproj:cxxfile $f "" 3]
cf4bee7c 2123 if { ! [info exists aVcFilesCxx($theToolKit)] } { lappend aVcFilesCxx(units) $theToolKit }
2124 lappend aVcFilesCxx($theToolKit) $f
910970ab 2125 } else {
2126 append aFilesSection "\t\t\t<Filter\n"
2127 append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
2128 append aFilesSection "\t\t\t\t>\n"
2129 append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
2130 append aFilesSection "\t\t\t</Filter>"
2131 }
2132 } else {
f6d8ca74 2133 puts "Warning : in vcproj there are more than one occurences for [file tail $f]"
910970ab 2134 }
2135 #puts "$aProjTmpl $aFilesSection"
910970ab 2136 set anIncPaths "..\\..\\..\\inc"
2137 regsub -all -- {__TKINC__} $aProjTmpl $anIncPaths aProjTmpl
910970ab 2138 regsub -all -- {__FILES__} $aProjTmpl $aFilesSection aProjTmpl
1c29294e 2139 regsub -all -- {__CONF__} $aProjTmpl Application aProjTmpl
2140
2141 regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
910970ab 2142
2143 set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
2144 fconfigure $aFile -translation crlf
2145 puts $aFile $aProjTmpl
2146 close $aFile
2147
2148 set aCommonSettingsFile "$aVcFilePath.user"
2149 lappend aVcFiles $aVcFilePath
2150
2151 # write filters file for vc10
39bff09c 2152 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
cf4bee7c 2153 lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesCxx aVcFilesHxx]
910970ab 2154 }
2155
cf4bee7c 2156 # write resource file
2157 lappend aVcFiles [osutils:readtemplate:rc $theOutDir $aProjName]
2158
910970ab 2159 set aCommonSettingsFileTmpl ""
39bff09c 2160 if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
2161 # nothing
2162 } elseif { "$theVcVer" == "vc9" } {
e31a8e52 2163 set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcproj.user.vc9x"]
39bff09c 2164 } else {
e31a8e52 2165 set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcxproj.user.vc10x"]
910970ab 2166 }
2167 if { "$aCommonSettingsFileTmpl" != "" } {
d6cda17a 2168 regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $aVCRTVer aCommonSettingsFileTmpl
39bff09c 2169
2170 set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
2171 fconfigure $aFile -translation crlf
2172 puts $aFile $aCommonSettingsFileTmpl
2173 close $aFile
2174
910970ab 2175 lappend aVcFiles "$aCommonSettingsFile"
2176 }
2177 }
2178 return $aVcFiles
2179}
2180
2181# Generate entry for one source file in Visual Studio 7 - 9 project file
2182proc osutils:vcproj:file { theVcVer theFile theOptions } {
2183 append aText "\t\t\t\t<File\n"
2184 append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
2185 if { $theOptions == "" } {
2186 append aText "\t\t\t\t</File>\n"
2187 return $aText
2188 }
2189
2190 append aText "\t\t\t\t\t<FileConfiguration\n"
2191 append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
2192 append aText "\t\t\t\t\t\t<Tool\n"
2193 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2194 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2195 foreach aParam $theOptions {
2196 append aText "$aParam "
2197 }
2198 append aText "\"\n"
2199 append aText "\t\t\t\t\t\t/>\n"
2200 append aText "\t\t\t\t\t</FileConfiguration>\n"
2201
2202 append aText "\t\t\t\t\t<FileConfiguration\n"
2203 append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
2204 append aText "\t\t\t\t\t\t<Tool\n"
2205 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2206 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2207 foreach aParam $theOptions {
2208 append aText "$aParam "
2209 }
2210 append aText "\"\n"
2211 append aText "\t\t\t\t\t\t/>\n"
2212 append aText "\t\t\t\t\t</FileConfiguration>\n"
2213 if { "$theVcVer" == "vc7" } {
2214 append aText "\t\t\t\t</File>\n"
2215 return $aText
2216 }
2217
2218 append aText "\t\t\t\t\t<FileConfiguration\n"
2219 append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
2220 append aText "\t\t\t\t\t\t<Tool\n"
2221 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2222 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2223 foreach aParam $theOptions {
2224 append aText "$aParam "
2225 }
2226 append aText "\"\n"
2227 append aText "\t\t\t\t\t\t/>\n"
2228 append aText "\t\t\t\t\t</FileConfiguration>\n"
2229
2230 append aText "\t\t\t\t\t<FileConfiguration\n"
2231 append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
2232 append aText "\t\t\t\t\t\t<Tool\n"
2233 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2234 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2235 foreach aParam $theOptions {
2236 append aText "$aParam "
2237 }
2238 append aText "\"\n"
2239 append aText "\t\t\t\t\t\t/>\n"
2240 append aText "\t\t\t\t\t</FileConfiguration>\n"
2241
2242 append aText "\t\t\t\t</File>\n"
2243 return $aText
2244}
2245
910970ab 2246proc wokUtils:FILES:mkdir { d } {
2247 global tcl_version
2248 regsub -all {\.[^.]*} $tcl_version "" major
2249 if { $major == 8 } {
2250 file mkdir $d
2251 } else {
2252 if ![file exists $d] {
2253 if { "[info command mkdir]" == "mkdir" } {
2254 mkdir -path $d
2255 } else {
2256 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
2257 }
2258 }
2259 }
2260 if [file exists $d] {
2261 return $d
2262 } else {
2263 return {}
2264 }
2265}
2266
910970ab 2267# remove from listloc OpenCascade units indesirables on Unix
2268proc osutils:justunix { listloc } {
c7d774c5 2269 if { "$::tcl_platform(os)" == "Darwin" } {
910970ab 2270 set goaway [list Xw WNT]
2271 } else {
2272 set goaway [list WNT]
2273 }
2274 return [osutils:juststation $goaway $listloc]
2275}
2276
910970ab 2277
2278####### CODEBLOCK ###################################################################
2279# Function to generate Code Blocks workspace and project files
944d808c 2280proc OS:MKCBP { theOutDir theModules theAllSolution thePlatform theCmpl } {
910970ab 2281 puts stderr "Generating project files for Code Blocks"
2282
2283 # Generate projects for toolkits and separate workspace for each module
2284 foreach aModule $theModules {
7c65581d 2285 OS:cworkspace $aModule $aModule $theOutDir
944d808c 2286 OS:cbp $theCmpl $aModule $theOutDir $thePlatform
910970ab 2287 }
2288
2289 # Generate single workspace "OCCT" containing projects from all modules
2290 if { "$theAllSolution" != "" } {
2291 OS:cworkspace $theAllSolution $theModules $theOutDir
2292 }
2293
2294 puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
2295}
2296
2297# Generate Code Blocks projects
944d808c 2298proc OS:cbp { theCmpl theModules theOutDir thePlatform } {
910970ab 2299 set aProjectFiles {}
2300 foreach aModule $theModules {
2301 foreach aToolKit [${aModule}:toolkits] {
944d808c 2302 lappend aProjectFiles [osutils:cbptk $theCmpl $theOutDir $aToolKit $thePlatform]
910970ab 2303 }
2304 foreach anExecutable [OS:executable ${aModule}] {
944d808c 2305 lappend aProjectFiles [osutils:cbpx $theCmpl $theOutDir $anExecutable $thePlatform]
910970ab 2306 }
2307 }
2308 return $aProjectFiles
2309}
2310
2311# Generate Code::Blocks project file for ToolKit
944d808c 2312proc osutils:cbptk { theCmpl theOutDir theToolKit thePlatform} {
7c65581d 2313 set aUsedLibs [list]
910970ab 2314 set aFrameworks [list]
2315 set anIncPaths [list]
2316 set aTKDefines [list]
2317 set aTKSrcFiles [list]
2318
7c65581d 2319 # collect list of referred libraries to link with
f6d8ca74 2320 osutils:usedOsLibs $theToolKit $thePlatform aUsedLibs aFrameworks "src"
2321 set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit "src" ""]]
7c65581d 2322 foreach tkx $aDepToolkits {
2323 lappend aUsedLibs "${tkx}"
2324 }
2325
2326 lappend anIncPaths "../../../inc"
f6d8ca74 2327 set listloc [osutils:tk:units $theToolKit "src"]
7c65581d 2328
2329 if { [llength $listloc] == 0 } {
2330 set listloc $theToolKit
2331 }
2332
d6cda17a 2333 if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
7c65581d 2334 set resultloc [osutils:justwnt $listloc]
2335 } else {
2336 set resultloc [osutils:justunix $listloc]
2337 }
2338 if [array exists written] { unset written }
2339 foreach fxlo $resultloc {
2340 set xlo $fxlo
f6d8ca74 2341 set aSrcFiles [osutils:tk:cxxfiles $xlo $thePlatform "src"]
7c65581d 2342 foreach aSrcFile [lsort $aSrcFiles] {
2343 if { ![info exists written([file tail $aSrcFile])] } {
2344 set written([file tail $aSrcFile]) 1
2345 lappend aTKSrcFiles "../../../[wokUtils:FILES:wtail $aSrcFile 3]"
2346 } else {
2347 puts "Warning : more than one occurences for [file tail $aSrcFile]"
2348 }
2349 }
2350
2351 # macros for correct DLL exports
68df8478 2352# if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
2353# lappend aTKDefines "__${xlo}_DLL"
2354# }
7c65581d 2355 }
910970ab 2356
944d808c 2357 return [osutils:cbp $theCmpl $theOutDir $theToolKit $thePlatform $aTKSrcFiles $aUsedLibs $aFrameworks $anIncPaths $aTKDefines]
910970ab 2358}
2359
2360# Generates Code Blocks workspace.
2361proc OS:cworkspace { theSolName theModules theOutDir } {
2362 global path
2363 set aWsFilePath "${theOutDir}/${theSolName}.workspace"
2364 set aFile [open $aWsFilePath "w"]
2365 set isActiveSet 0
2366 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2367 puts $aFile "<CodeBlocks_workspace_file>"
2368 puts $aFile "\t<Workspace title=\"${theSolName}\">"
2369
2370 # collect list of projects to be created
2371 foreach aModule $theModules {
2372 # toolkits
f6d8ca74 2373 foreach aToolKit [osutils:tk:sort [${aModule}:toolkits] "src" ""] {
2374 set aDependencies [LibToLink $aToolKit "src" ""]
910970ab 2375 if { [llength $aDependencies] == 0 } {
2376 puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
2377 } else {
2378 puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
2379 foreach aDepTk $aDependencies {
2380 puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2381 }
2382 puts $aFile "\t\t</Project>"
2383 }
2384 }
2385
2386 # executables, assume one project per cxx file...
2387 foreach aUnit [OS:executable ${aModule}] {
2388 set aUnitLoc $aUnit
f6d8ca74 2389 set src_files [_get_used_files $aUnit "src" false]
910970ab 2390 set aSrcFiles {}
2391 foreach s $src_files {
2392 regexp {source ([^\s]+)} $s dummy name
2393 lappend aSrcFiles $name
2394 }
2395 foreach aSrcFile $aSrcFiles {
2396 set aFileExtension [file extension $aSrcFile]
2397 if { $aFileExtension == ".cxx" } {
2398 set aPrjName [file rootname $aSrcFile]
2399 set aDependencies [list]
2400 if {[file isdirectory $path/src/$aUnitLoc]} {
f6d8ca74 2401 set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile] "src" ""]
910970ab 2402 }
2403 set anActiveState ""
2404 if { $isActiveSet == 0 } {
2405 set anActiveState " active=\"1\""
2406 set isActiveSet 1
2407 }
2408 if { [llength $aDependencies] == 0 } {
2409 puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
2410 } else {
2411 puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
2412 foreach aDepTk $aDependencies {
2413 puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2414 }
2415 puts $aFile "\t\t</Project>"
2416 }
2417 }
2418 }
2419 }
2420 }
2421
2422 puts $aFile "\t</Workspace>"
2423 puts $aFile "</CodeBlocks_workspace_file>"
2424 close $aFile
2425
2426 return $aWsFilePath
2427}
2428
2429# Generate Code::Blocks project file for Executable
944d808c 2430proc osutils:cbpx { theCmpl theOutDir theToolKit thePlatform } {
2431 global path
910970ab 2432 set aWokArch "$::env(ARCH)"
2433
2434 set aCbpFiles {}
f6d8ca74 2435 foreach aSrcFile [osutils:tk:cxxfiles $theToolKit $thePlatform "src"] {
910970ab 2436 # collect list of referred libraries to link with
7c65581d 2437 set aUsedLibs [list]
910970ab 2438 set aFrameworks [list]
2439 set anIncPaths [list]
2440 set aTKDefines [list]
2441 set aTKSrcFiles [list]
2442 set aProjName [file rootname [file tail $aSrcFile]]
2443
f6d8ca74 2444 osutils:usedOsLibs $theToolKit $thePlatform aUsedLibs aFrameworks "src"
7c65581d 2445
f6d8ca74 2446 set aDepToolkits [LibToLinkX $theToolKit $aProjName "src" ""]
910970ab 2447 foreach tkx $aDepToolkits {
2448 if {[_get_type $tkx] == "t"} {
7c65581d 2449 lappend aUsedLibs "${tkx}"
910970ab 2450 }
2451 if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
7c65581d 2452 lappend aUsedLibs "${tkx}"
910970ab 2453 }
2454 }
2455
910970ab 2456 set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
2457 if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
2458 set isExecutable "false"
2459 } else {
2460 set isExecutable "true"
2461 }
2462
2463 if { ![info exists written([file tail $aSrcFile])] } {
2464 set written([file tail $aSrcFile]) 1
7c65581d 2465 lappend aTKSrcFiles "../../../[wokUtils:FILES:wtail $aSrcFile 3]"
910970ab 2466 } else {
2467 puts "Warning : in cbp there are more than one occurences for [file tail $aSrcFile]"
2468 }
2469
2470 # macros for correct DLL exports
68df8478 2471# if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
2472# lappend aTKDefines "__${theToolKit}_DLL"
2473# }
910970ab 2474
2475 # common include paths
2476 lappend anIncPaths "../../../inc"
2477
944d808c 2478 lappend aCbpFiles [osutils:cbp $theCmpl $theOutDir $aProjName $thePlatform $aTKSrcFiles $aUsedLibs $aFrameworks $anIncPaths $aTKDefines $isExecutable]
910970ab 2479 }
2480
2481 return $aCbpFiles
2482}
2483
910970ab 2484# This function intended to generate Code::Blocks project file
7c65581d 2485# @param theCmpl - the compiler (gcc or msvc)
910970ab 2486# @param theOutDir - output directory to place project file
2487# @param theProjName - project name
2488# @param theSrcFiles - list of source files
2489# @param theLibsList - dependencies (libraries list)
2490# @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2491# @param theIncPaths - header search paths
2492# @param theDefines - compiler macro definitions
2493# @param theIsExe - flag to indicate executable / library target
944d808c 2494proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
910970ab 2495 set aWokArch "$::env(ARCH)"
2496
7c65581d 2497 set aCmplCbp "gcc"
2498 set aCmplFlags [list]
2499 set aCmplFlagsRelease [list]
2500 set aCmplFlagsDebug [list]
2501 set toPassArgsByFile 0
2502 set aLibPrefix "lib"
aafe169f 2503 set aPlatformAndCompiler "${thePlatform}/gcc"
2504 if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } {
2505 set aPlatformAndCompiler "${thePlatform}/clang"
2506 }
d6cda17a 2507 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" || "$thePlatform" == "qnx" } {
7c65581d 2508 set toPassArgsByFile 1
2509 }
2510 if { "$theCmpl" == "msvc" } {
2511 set aCmplCbp "msvc8"
2512 set aLibPrefix ""
2513 }
2514
2515 if { "$theCmpl" == "msvc" } {
2516 set aCmplFlags "-arch:SSE2 -EHsc -W4 -MP"
2517 set aCmplFlagsRelease "-MD -O2"
2518 set aCmplFlagsDebug "-MDd -Od -Zi"
2519 lappend aCmplFlags "-D_CRT_SECURE_NO_WARNINGS"
2520 lappend aCmplFlags "-D_CRT_NONSTDC_NO_DEPRECATE"
2521 } elseif { "$theCmpl" == "gcc" } {
d6cda17a 2522 if { "$thePlatform" != "qnx" } {
7c65581d 2523 set aCmplFlags "-mmmx -msse -msse2 -mfpmath=sse"
2524 }
2525 set aCmplFlagsRelease "-O2"
2526 set aCmplFlagsDebug "-O0 -g"
d6cda17a 2527 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
7c65581d 2528 lappend aCmplFlags "-std=gnu++0x"
2529 lappend aCmplFlags "-D_WIN32_WINNT=0x0501"
2530 } else {
2531 lappend aCmplFlags "-std=c++0x"
2532 lappend aCmplFlags "-fPIC"
2533 lappend aCmplFlags "-DOCC_CONVERT_SIGNALS"
2534 }
2535 lappend aCmplFlags "-Wall"
2536 lappend aCmplFlags "-fexceptions"
2537 }
2538 lappend aCmplFlagsRelease "-DNDEBUG"
2539 lappend aCmplFlagsRelease "-DNo_Exception"
2540 lappend aCmplFlagsDebug "-D_DEBUG"
d6cda17a 2541 if { "$thePlatform" == "qnx" } {
7c65581d 2542 lappend aCmplFlags "-D_QNX_SOURCE"
2543 }
2544
2545 set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2546 set aLnkFileName "${theProjName}_obj.link"
2547 set aLnkDebFileName "${theProjName}_objd.link"
2548 set aLnkFilePath "${theOutDir}/${aLnkFileName}"
2549 set aLnkDebFilePath "${theOutDir}/${aLnkDebFileName}"
910970ab 2550 set aFile [open $aCbpFilePath "w"]
2551 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2552 puts $aFile "<CodeBlocks_project_file>"
2553 puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2554 puts $aFile "\t<Project>"
2555 puts $aFile "\t\t<Option title=\"$theProjName\" />"
2556 puts $aFile "\t\t<Option pch_mode=\"2\" />"
7c65581d 2557 puts $aFile "\t\t<Option compiler=\"$aCmplCbp\" />"
910970ab 2558 puts $aFile "\t\t<Build>"
2559
2560 # Release target configuration
2561 puts $aFile "\t\t\t<Target title=\"Release\">"
2562 if { "$theIsExe" == "true" } {
aafe169f 2563 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/bin/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2564 puts $aFile "\t\t\t\t<Option type=\"1\" />"
2565 } else {
d6cda17a 2566 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
aafe169f 2567 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 2568 } else {
aafe169f 2569 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/lib/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2570 }
2571 puts $aFile "\t\t\t\t<Option type=\"3\" />"
2572 }
aafe169f 2573 puts $aFile "\t\t\t\t<Option object_output=\"../../../${aPlatformAndCompiler}/obj\" />"
7c65581d 2574 puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
2575 puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
d6cda17a 2576 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
7c65581d 2577 puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
910970ab 2578 } else {
7c65581d 2579 puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
910970ab 2580 }
910970ab 2581
2582 # compiler options per TARGET (including defines)
2583 puts $aFile "\t\t\t\t<Compiler>"
7c65581d 2584 foreach aFlagIter $aCmplFlagsRelease {
2585 puts $aFile "\t\t\t\t\t<Add option=\"$aFlagIter\" />"
910970ab 2586 }
2587 foreach aMacro $theDefines {
2588 puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2589 }
910970ab 2590 puts $aFile "\t\t\t\t</Compiler>"
2591
2592 puts $aFile "\t\t\t\t<Linker>"
7c65581d 2593 if { $toPassArgsByFile == 1 } {
2594 puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkFileName\" />"
2595 }
aafe169f 2596 puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aPlatformAndCompiler}/lib\" />"
d6cda17a 2597 if { "$thePlatform" == "mac" } {
7c65581d 2598 if { [ lsearch $theLibsList X11 ] >= 0} {
2599 puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2600 }
910970ab 2601 }
2602 puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
d6cda17a 2603 if { "$thePlatform" == "lin" } {
aafe169f 2604 puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aPlatformAndCompiler}/lib\" />"
55fb31da 2605 }
910970ab 2606 puts $aFile "\t\t\t\t</Linker>"
2607
2608 puts $aFile "\t\t\t</Target>"
2609
2610 # Debug target configuration
2611 puts $aFile "\t\t\t<Target title=\"Debug\">"
2612 if { "$theIsExe" == "true" } {
aafe169f 2613 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/bind/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2614 puts $aFile "\t\t\t\t<Option type=\"1\" />"
2615 } else {
d6cda17a 2616 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
aafe169f 2617 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 2618 } else {
aafe169f 2619 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/libd/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
910970ab 2620 }
2621 puts $aFile "\t\t\t\t<Option type=\"3\" />"
2622 }
aafe169f 2623 puts $aFile "\t\t\t\t<Option object_output=\"../../../${aPlatformAndCompiler}/objd\" />"
7c65581d 2624 puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
2625 puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
d6cda17a 2626 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
7c65581d 2627 puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
910970ab 2628 } else {
7c65581d 2629 puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
910970ab 2630 }
910970ab 2631
2632 # compiler options per TARGET (including defines)
2633 puts $aFile "\t\t\t\t<Compiler>"
7c65581d 2634 foreach aFlagIter $aCmplFlagsDebug {
2635 puts $aFile "\t\t\t\t\t<Add option=\"$aFlagIter\" />"
910970ab 2636 }
2637 foreach aMacro $theDefines {
2638 puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2639 }
910970ab 2640 puts $aFile "\t\t\t\t</Compiler>"
2641
2642 puts $aFile "\t\t\t\t<Linker>"
7c65581d 2643 if { $toPassArgsByFile == 1 } {
2644 puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkDebFileName\" />"
2645 }
aafe169f 2646 puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aPlatformAndCompiler}/libd\" />"
d6cda17a 2647 if { "$thePlatform" == "mac" } {
7c65581d 2648 if { [ lsearch $theLibsList X11 ] >= 0} {
2649 puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2650 }
910970ab 2651 }
2652 puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
d6cda17a 2653 if { "$thePlatform" == "lin" } {
aafe169f 2654 puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aPlatformAndCompiler}/libd\" />"
55fb31da 2655 }
910970ab 2656 puts $aFile "\t\t\t\t</Linker>"
2657
2658 puts $aFile "\t\t\t</Target>"
2659
2660 puts $aFile "\t\t</Build>"
2661
2662 # COMMON compiler options
2663 puts $aFile "\t\t<Compiler>"
7c65581d 2664 foreach aFlagIter $aCmplFlags {
2665 puts $aFile "\t\t\t<Add option=\"$aFlagIter\" />"
2666 }
910970ab 2667 puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2668 foreach anIncPath $theIncPaths {
2669 puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2670 }
2671 puts $aFile "\t\t</Compiler>"
2672
2673 # COMMON linker options
2674 puts $aFile "\t\t<Linker>"
d6cda17a 2675 if { "$thePlatform" == "wnt" && "$theCmpl" == "gcc" } {
7c65581d 2676 puts $aFile "\t\t\t<Add option=\"-Wl,--export-all-symbols\" />"
2677 }
910970ab 2678 foreach aFrameworkName $theFrameworks {
2679 if { "$aFrameworkName" != "" } {
2680 puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2681 }
2682 }
2683 foreach aLibName $theLibsList {
2684 if { "$aLibName" != "" } {
7c65581d 2685 if { "$theCmpl" == "msvc" } {
2686 puts $aFile "\t\t\t<Add library=\"${aLibName}.lib\" />"
2687 } else {
2688 puts $aFile "\t\t\t<Add library=\"${aLibName}\" />"
2689 }
910970ab 2690 }
2691 }
2692 puts $aFile "\t\t</Linker>"
2693
2694 # list of sources
7c65581d 2695
2696 set aFileLnkObj ""
2697 set aFileLnkObjd ""
2698 set isFirstSrcFile 1
2699 if { $toPassArgsByFile == 1 } {
2700 set aFileLnkObj [open $aLnkFilePath "w"]
2701 set aFileLnkObjd [open $aLnkDebFilePath "w"]
2702 }
2703
910970ab 2704 foreach aSrcFile $theSrcFiles {
2705 if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2706 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2707 puts $aFile "\t\t\t<Option compile=\"1\" />"
2708 puts $aFile "\t\t\t<Option link=\"1\" />"
2709 puts $aFile "\t\t</Unit>"
2710 } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2711 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2712 puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2713 puts $aFile "\t\t</Unit>"
7c65581d 2714 } elseif { $toPassArgsByFile == 1 && $isFirstSrcFile == 0 && [string equal -nocase [file extension $aSrcFile] ".cxx" ] } {
2715 # pass at list single source file to Code::Blocks as is
2716 # and pack the list of other files into the dedicated file to workaround process arguments limits on systems like Windows
2717 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2718 puts $aFile "\t\t\t<Option link=\"0\" />"
2719 puts $aFile "\t\t</Unit>"
2720
aafe169f 2721 set aFileObj [string map {.cxx .o} [string map [list "/src/" "/${aPlatformAndCompiler}/obj/src/"] $aSrcFile]]
2722 set aFileObjd [string map {.cxx .o} [string map [list "/src/" "/${aPlatformAndCompiler}/objd/src/"] $aSrcFile]]
7c65581d 2723 puts -nonewline $aFileLnkObj "$aFileObj "
2724 puts -nonewline $aFileLnkObjd "$aFileObjd "
910970ab 2725 } else {
2726 puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
7c65581d 2727 set isFirstSrcFile 0
910970ab 2728 }
2729 }
2730
d6cda17a 2731 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
7c65581d 2732 close $aFileLnkObj
2733 close $aFileLnkObjd
2734 }
2735
910970ab 2736 puts $aFile "\t</Project>"
2737 puts $aFile "</CodeBlocks_project_file>"
2738 close $aFile
2739
2740 return $aCbpFilePath
2741}
2742
910970ab 2743# Define libraries to link using only EXTERNLIB file
f6d8ca74 2744proc LibToLinkX {thePackage theDummyName theSrcDir theSourceDirOther} {
2745 set aToolKits [LibToLink $thePackage $theSrcDir $theSourceDirOther]
910970ab 2746 return $aToolKits
2747}
2748
c7d774c5 2749# Function to generate Xcode workspace and project files
2750proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
2751
2752 puts stderr "Generating project files for Xcode"
2753
2754 # Generate projects for toolkits and separate workspace for each module
2755 foreach aModule $theModules {
2756 OS:xcworkspace $aModule $aModule $theOutDir
2757 OS:xcodeproj $aModule $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
2758 }
2759
2760 # Generate single workspace "OCCT" containing projects from all modules
2761 if { "$theAllSolution" != "" } {
2762 OS:xcworkspace $theAllSolution $theModules $theOutDir
2763 }
2764}
2765
2766# Generates toolkits sections for Xcode workspace file.
2767proc OS:xcworkspace:toolkits { theModule } {
2768 set aBuff ""
2769
2770 # Adding toolkits for module in workspace.
f6d8ca74 2771 foreach aToolKit [osutils:tk:sort [${theModule}:toolkits] "src" ""] {
c7d774c5 2772 append aBuff " <FileRef\n"
2773 append aBuff " location = \"group:${aToolKit}.xcodeproj\">\n"
2774 append aBuff " </FileRef>\n"
2775 }
2776
2777 # Adding executables for module, assume one project per cxx file...
2778 foreach aUnit [OS:executable ${theModule}] {
2779 set aUnitLoc $aUnit
f6d8ca74 2780 set src_files [_get_used_files $aUnit "src" false]
c7d774c5 2781 set aSrcFiles {}
2782 foreach s $src_files {
2783 regexp {source ([^\s]+)} $s dummy name
2784 lappend aSrcFiles $name
2785 }
2786 foreach aSrcFile $aSrcFiles {
2787 set aFileExtension [file extension $aSrcFile]
2788 if { $aFileExtension == ".cxx" } {
2789 set aPrjName [file rootname $aSrcFile]
2790 append aBuff " <FileRef\n"
2791 append aBuff " location = \"group:${aPrjName}.xcodeproj\">\n"
2792 append aBuff " </FileRef>\n"
2793 }
2794 }
2795 }
2796
2797 # Removing unnecessary newline character from the end.
2798 set aBuff [string replace $aBuff end end]
2799 return $aBuff
2800}
2801
2802# Generates workspace files for Xcode.
2803proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
2804 # Creating workspace directory for Xcode.
2805 set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
2806 wokUtils:FILES:mkdir $aWorkspaceDir
2807 if { ! [file exists $aWorkspaceDir] } {
2808 puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
2809 return
2810 }
2811
2812 # Creating workspace file.
2813 set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
2814 set aFile [open $aWsFilePath "w"]
2815
2816 # Adding header and section for main Group.
2817 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2818 puts $aFile "<Workspace"
2819 puts $aFile " version = \"1.0\">"
2820 puts $aFile " <Group"
2821 puts $aFile " location = \"container:\""
2822 puts $aFile " name = \"${theWorkspaceName}\">"
2823
2824 # Adding modules.
2825 if { [llength "$theModules"] > 1 } {
2826 foreach aModule $theModules {
2827 puts $aFile " <Group"
2828 puts $aFile " location = \"container:\""
2829 puts $aFile " name = \"${aModule}\">"
2830 puts $aFile [OS:xcworkspace:toolkits $aModule]
2831 puts $aFile " </Group>"
2832 }
2833 } else {
2834 puts $aFile [OS:xcworkspace:toolkits $theModules]
2835 }
2836
2837 # Adding footer.
2838 puts $aFile " </Group>"
2839 puts $aFile "</Workspace>"
2840 close $aFile
2841}
2842
2843# Generates Xcode project files.
2844proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
2845 upvar $theGuidsMap aGuidsMap
2846
2847 set isStatic 0
2848 if { "$theLibType" == "static" } {
2849 set isStatic 1
2850 } elseif { "$thePlatform" == "ios" } {
2851 set isStatic 1
2852 }
2853
2854 set aProjectFiles {}
2855 foreach aModule $theModules {
2856 foreach aToolKit [${aModule}:toolkits] {
2857 lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit aGuidsMap $isStatic $thePlatform "dylib"]
2858 }
2859 foreach anExecutable [OS:executable ${aModule}] {
2860 lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
2861 }
2862 }
2863 return $aProjectFiles
2864}
2865
2866# Generates dependencies section for Xcode project files.
48ba1811 2867proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids thePlatform theIsStatic} {
c7d774c5 2868 upvar $theGuidsMap aGuidsMap
2869 upvar $theFileRefSection aFileRefSection
2870 upvar $theDepsGuids aDepsGuids
2871 upvar $theDepsRefGuids aDepsRefGuids
2872
2873 set aBuildFileSection ""
f6d8ca74 2874 set aUsedLibs [wokUtils:LIST:Purge [osutils:tk:close $theToolKit "src" ""]]
2875 set aDepToolkits [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit "src" ""]] $theToolKit]
c7d774c5 2876
2877 if { "$theTargetType" == "executable" } {
f6d8ca74 2878 set aFile [osutils:tk:cxxfiles $theToolKit mac "src"]
c7d774c5 2879 set aProjName [file rootname [file tail $aFile]]
f6d8ca74 2880 set aDepToolkits [LibToLinkX $theToolKit $aProjName "src" ""]
c7d774c5 2881 }
2882
2883 set aLibExt "dylib"
2884 if { $theIsStatic == 1 } {
2885 set aLibExt "a"
2886 if { "$theTargetType" != "executable" } {
2887 return $aBuildFileSection
2888 }
2889 }
2890
f6d8ca74 2891 osutils:usedOsLibs $theToolKit $thePlatform aLibs aFrameworks "src"
7c65581d 2892 set aUsedLibs [concat $aUsedLibs $aLibs]
2893 set aUsedLibs [concat $aUsedLibs $aFrameworks]
2894 foreach tkx $aUsedLibs {
c7d774c5 2895 set aDepLib "${tkx}_Dep"
2896 set aDepLibRef "${tkx}_DepRef"
2897
2898 if { ! [info exists aGuidsMap($aDepLib)] } {
2899 set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
2900 }
2901 if { ! [info exists aGuidsMap($aDepLibRef)] } {
2902 set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
2903 }
2904
2905 append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
2906 if {[lsearch -nocase $aFrameworks $tkx] == -1} {
2907 append aFileRefSection "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
2908 } else {
2909 append aFileRefSection "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
2910 }
2911 append aDepsGuids "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
2912 append aDepsRefGuids "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
2913 }
2914
2915 return $aBuildFileSection
2916}
2917
2918# Generates PBXBuildFile and PBXGroup sections for project file.
2919proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
2920 upvar $theSrcFileRefSection aSrcFileRefSection
2921 upvar $theGroupSection aGroupSection
2922 upvar $thePackageGuids aPackagesGuids
2923 upvar $theSrcFileGuids aSrcFileGuids
2924 upvar $theGuidsMap aGuidsMap
2925 upvar $theIncPaths anIncPaths
2926
f6d8ca74 2927 set listloc [osutils:tk:units $theToolKit "src"]
c7d774c5 2928 set resultloc [osutils:justunix $listloc]
2929 set aBuildFileSection ""
2930 set aPackages [lsort -nocase $resultloc]
2931 if { "$theTargetType" == "executable" } {
2932 set aPackages [list "$theToolKit"]
2933 }
2934
2935 # Generating PBXBuildFile, PBXGroup sections and groups for each package.
2936 foreach fxlo $aPackages {
2937 set xlo $fxlo
2938 set aPackage "${xlo}_Package"
2939 set aSrcFileRefGuids ""
2940 if { ! [info exists aGuidsMap($aPackage)] } {
2941 set aGuidsMap($aPackage) [OS:genGUID "xcd"]
2942 }
2943
f6d8ca74 2944 set aSrcFiles [osutils:tk:cxxfiles $xlo mac "src"]
c7d774c5 2945 foreach aSrcFile [lsort $aSrcFiles] {
2946 set aFileExt "sourcecode.cpp.cpp"
2947
2948 if { [file extension $aSrcFile] == ".c" } {
2949 set aFileExt "sourcecode.c.c"
2950 } elseif { [file extension $aSrcFile] == ".mm" } {
2951 set aFileExt "sourcecode.cpp.objcpp"
2952 }
2953
2954 if { ! [info exists aGuidsMap($aSrcFile)] } {
2955 set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
2956 }
2957 set aSrcFileRef "${aSrcFile}_Ref"
2958 if { ! [info exists aGuidsMap($aSrcFileRef)] } {
2959 set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
2960 }
2961 if { ! [info exists written([file tail $aSrcFile])] } {
2962 set written([file tail $aSrcFile]) 1
2963 append aBuildFileSection "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
2964 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"
2965 append aSrcFileGuids "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
2966 append aSrcFileRefGuids "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
2967 } else {
2968 puts "Warning : more than one occurences for [file tail $aSrcFile]"
2969 }
2970 }
2971
2972 append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
2973 append aGroupSection "\t\t\tisa = PBXGroup;\n"
2974 append aGroupSection "\t\t\tchildren = (\n"
2975 append aGroupSection $aSrcFileRefGuids
2976 append aGroupSection "\t\t\t);\n"
2977 append aGroupSection "\t\t\tname = $xlo;\n"
2978 append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
2979 append aGroupSection "\t\t\};\n"
2980
2981 # Storing packages IDs for adding them later as a child of toolkit
2982 append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
2983 }
2984
2985 # Removing unnecessary newline character from the end.
2986 set aPackagesGuids [string replace $aPackagesGuids end end]
2987
2988 return $aBuildFileSection
2989}
2990
2991# Creates folders structure and all necessary files for Xcode project.
2992proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
2993 set aPBXBuildPhase "Headers"
2994 set aRunOnlyForDeployment "0"
2995 set aProductType "library.dynamic"
2996 set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
2997 set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
2998 set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
050c18ac 2999 set aTKDefines [list "OCC_CONVERT_SIGNALS"]
d5265175 3000 if { $theIsStatic == 1 } {
3001 lappend aTKDefines "OCCT_NO_PLUGINS"
3002 }
c7d774c5 3003
3004 if { "$theTargetType" == "executable" } {
3005 set aPBXBuildPhase "CopyFiles"
3006 set aRunOnlyForDeployment "1"
3007 set aProductType "tool"
3008 set anExecExtension ""
3009 set anExecPrefix ""
3010 set aWrapperExtension ""
3011 } elseif { $theIsStatic == 1 } {
3012 set aProductType "library.static"
3013 set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
3014 set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
3015 }
3016
3017 set aUsername [exec whoami]
3018
3019 # Creation of folders for Xcode projectP.
3020 set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
3021 wokUtils:FILES:mkdir $aToolkitDir
3022 if { ! [file exists $aToolkitDir] } {
3023 puts stderr "Error: Could not create project directory \"$aToolkitDir\""
3024 return
3025 }
3026
3027 set aUserDataDir "${aToolkitDir}/xcuserdata"
3028 wokUtils:FILES:mkdir $aUserDataDir
3029 if { ! [file exists $aUserDataDir] } {
3030 puts stderr "Error: Could not create xcuserdata directorty in \"$aToolkitDir\""
3031 return
3032 }
3033
3034 set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3035 wokUtils:FILES:mkdir $aUserDataDir
3036 if { ! [file exists $aUserDataDir] } {
3037 puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$aToolkitDir\"/xcuserdata"
3038 return
3039 }
3040
3041 set aSchemesDir "${aUserDataDir}/xcschemes"
3042 wokUtils:FILES:mkdir $aSchemesDir
3043 if { ! [file exists $aSchemesDir] } {
3044 puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3045 return
3046 }
3047 # End of folders creation.
3048
3049 # Generating GUID for tookit.
3050 upvar $theGuidsMap aGuidsMap
3051 if { ! [info exists aGuidsMap($theToolKit)] } {
3052 set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
3053 }
3054
3055 # Creating xcscheme file for toolkit from template.
3056 set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
3057 regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
3058 regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
3059 set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme" "w"]
3060 puts $aXcschemeFile $aXcschemeTmpl
3061 close $aXcschemeFile
3062
3063 # Creating xcschememanagement.plist file for toolkit from template.
3064 set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
3065 regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
3066 regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
3067 set aPlistFile [open "$aSchemesDir/xcschememanagement.plist" "w"]
3068 puts $aPlistFile $aPlistTmpl
3069 close $aPlistFile
3070
3071 # Creating project.pbxproj file for toolkit.
3072 set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
3073 puts $aPbxprojFile "// !\$*UTF8*\$!"
3074 puts $aPbxprojFile "\{"
3075 puts $aPbxprojFile "\tarchiveVersion = 1;"
3076 puts $aPbxprojFile "\tclasses = \{"
3077 puts $aPbxprojFile "\t\};"
3078 puts $aPbxprojFile "\tobjectVersion = 46;"
3079 puts $aPbxprojFile "\tobjects = \{\n"
3080
3081 # Begin PBXBuildFile section
3082 set aPackagesGuids ""
3083 set aGroupSection ""
3084 set aSrcFileRefSection ""
3085 set aSrcFileGuids ""
3086 set aDepsFileRefSection ""
3087 set aDepsGuids ""
3088 set aDepsRefGuids ""
3089 set anIncPaths [list "../../../inc"]
3090 set anLibPaths ""
3091
3092 if { [info exists ::env(CSF_OPT_INC)] } {
3093 set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
3094 foreach anIncCfgPath $anIncCfg {
3095 lappend anIncPaths $anIncCfgPath
3096 }
3097 }
3098 if { [info exists ::env(CSF_OPT_LIB64)] } {
3099 set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
3100 foreach anLibCfgPath $anLibCfg {
3101 lappend anLibPaths $anLibCfgPath
3102 }
3103 }
3104
3105 puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
48ba1811 3106 puts $aPbxprojFile [osutils:xcdtk:deps $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $thePlatform $theIsStatic]
c7d774c5 3107 # End PBXBuildFile section
3108
3109 # Begin PBXFileReference section
3110 set aToolkitLib "lib${theToolKit}.dylib"
3111 set aPath "$aToolkitLib"
3112 if { "$theTargetType" == "executable" } {
3113 set aPath "$theToolKit"
3114 } elseif { $theIsStatic == 1 } {
3115 set aToolkitLib "lib${theToolKit}.a"
3116 }
3117
3118 if { ! [info exists aGuidsMap($aToolkitLib)] } {
3119 set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
3120 }
3121
3122 puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
3123 puts $aPbxprojFile $aSrcFileRefSection
3124 puts $aPbxprojFile $aDepsFileRefSection
3125 # End PBXFileReference section
3126
3127
3128 # Begin PBXFrameworksBuildPhase section
3129 set aTkFrameworks "${theToolKit}_Frameworks"
3130 if { ! [info exists aGuidsMap($aTkFrameworks)] } {
3131 set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
3132 }
3133
3134 puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
3135 puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
3136 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3137 puts $aPbxprojFile "\t\t\tfiles = ("
3138 puts $aPbxprojFile $aDepsGuids
3139 puts $aPbxprojFile "\t\t\t);"
3140 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3141 puts $aPbxprojFile "\t\t\};\n"
3142 # End PBXFrameworksBuildPhase section
3143
3144 # Begin PBXGroup section
3145 set aTkPBXGroup "${theToolKit}_PBXGroup"
3146 if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
3147 set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
3148 }
3149
3150 set aTkSrcGroup "${theToolKit}_SrcGroup"
3151 if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
3152 set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
3153 }
3154
3155 puts $aPbxprojFile $aGroupSection
3156 puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
3157 puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
3158 puts $aPbxprojFile "\t\t\tchildren = ("
3159 puts $aPbxprojFile $aDepsRefGuids
3160 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
3161 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
3162 puts $aPbxprojFile "\t\t\t);"
3163 puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
3164 puts $aPbxprojFile "\t\t\};"
3165 puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
3166 puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
3167 puts $aPbxprojFile "\t\t\tchildren = ("
3168 puts $aPbxprojFile $aPackagesGuids
3169 puts $aPbxprojFile "\t\t\t);"
3170 puts $aPbxprojFile "\t\t\tname = \"Source files\";"
3171 puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
3172 puts $aPbxprojFile "\t\t\};\n"
3173 # End PBXGroup section
3174
3175 # Begin PBXHeadersBuildPhase section
3176 set aTkHeaders "${theToolKit}_Headers"
3177 if { ! [info exists aGuidsMap($aTkHeaders)] } {
3178 set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
3179 }
3180
3181 puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
3182 puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
3183 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3184 puts $aPbxprojFile "\t\t\tfiles = ("
3185 puts $aPbxprojFile "\t\t\t);"
3186 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
3187 puts $aPbxprojFile "\t\t\};\n"
3188 # End PBXHeadersBuildPhase section
3189
3190 # Begin PBXNativeTarget section
3191 set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
3192 if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
3193 set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
3194 }
3195
3196 set aTkSources "${theToolKit}_Sources"
3197 if { ! [info exists aGuidsMap($aTkSources)] } {
3198 set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
3199 }
3200
3201 puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
3202 puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
3203 puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
3204 puts $aPbxprojFile "\t\t\tbuildPhases = ("
3205 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
3206 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
3207 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
3208 puts $aPbxprojFile "\t\t\t);"
3209 puts $aPbxprojFile "\t\t\tbuildRules = ("
3210 puts $aPbxprojFile "\t\t\t);"
3211 puts $aPbxprojFile "\t\t\tdependencies = ("
3212 puts $aPbxprojFile "\t\t\t);"
3213 puts $aPbxprojFile "\t\t\tname = $theToolKit;"
3214 puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
3215 puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
3216 puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
3217 puts $aPbxprojFile "\t\t\};\n"
3218 # End PBXNativeTarget section
3219
3220 # Begin PBXProject section
3221 set aTkProjectObj "${theToolKit}_ProjectObj"
3222 if { ! [info exists aGuidsMap($aTkProjectObj)] } {
3223 set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
3224 }
3225
3226 set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
3227 if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
3228 set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
3229 }
3230
3231 puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
3232 puts $aPbxprojFile "\t\t\tisa = PBXProject;"
3233 puts $aPbxprojFile "\t\t\tattributes = \{"
3234 puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
3235 puts $aPbxprojFile "\t\t\t\};"
3236 puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
3237 puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
3238 puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
3239 puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
3240 puts $aPbxprojFile "\t\t\tknownRegions = ("
3241 puts $aPbxprojFile "\t\t\t\ten,"
3242 puts $aPbxprojFile "\t\t\t);"
3243 puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
3244 puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
3245 puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
3246 puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
3247 puts $aPbxprojFile "\t\t\ttargets = ("
3248 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
3249 puts $aPbxprojFile "\t\t\t);"
3250 puts $aPbxprojFile "\t\t\};\n"
3251 # End PBXProject section
3252
3253 # Begin PBXSourcesBuildPhase section
3254 puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
3255 puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
3256 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3257 puts $aPbxprojFile "\t\t\tfiles = ("
3258 puts $aPbxprojFile $aSrcFileGuids
3259 puts $aPbxprojFile "\t\t\t);"
3260 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3261 puts $aPbxprojFile "\t\t\};\n"
3262 # End PBXSourcesBuildPhase section
3263
3264 # Begin XCBuildConfiguration section
3265 set aTkDebugProject "${theToolKit}_DebugProject"
3266 if { ! [info exists aGuidsMap($aTkDebugProject)] } {
3267 set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
3268 }
3269
3270 set aTkReleaseProject "${theToolKit}_ReleaseProject"
3271 if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
3272 set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
3273 }
3274
3275 set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
3276 if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
3277 set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
3278 }
3279
3280 set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
3281 if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
3282 set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
3283 }
3284
3285 # Debug target
3286 puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
3287 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3288 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3289
3290 puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
3291 puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3292 if { "$thePlatform" == "ios" } {
3293 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3294 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
c7d774c5 3295 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3296 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3297 }
3298 puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
810b672f 3299 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3300 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"c++0x\";"
c7d774c5 3301 puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
3302 puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3303 puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
3304 puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3305 puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
3306 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3307 puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
3308 puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
3309 puts $aPbxprojFile "\t\t\t\t);"
3310 puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
3311 puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3312 puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3313 puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3314 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3315 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3316 puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
3317 if { "$thePlatform" == "ios" } {
3318 puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
3319 puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3320 } else {
3321 puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
3322 }
3323 puts $aPbxprojFile "\t\t\t\};"
3324
3325 puts $aPbxprojFile "\t\t\tname = Debug;"
3326 puts $aPbxprojFile "\t\t\};"
3327
3328 # Release target
3329 puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
3330 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3331 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3332
3333 puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
3334 puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3335 if { "$thePlatform" == "ios" } {
3336 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3337 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
c7d774c5 3338 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3339 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3340 }
3341 puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
810b672f 3342 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3343 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"c++0x\";"
c7d774c5 3344 puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
3345 puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3346 puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3347 puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
3348 puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
3349 puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3350 puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3351 puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3352 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3353 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3354 puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
3355 if { "$thePlatform" == "ios" } {
3356 puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
3357 puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3358 }
3359 puts $aPbxprojFile "\t\t\t\};"
3360 puts $aPbxprojFile "\t\t\tname = Release;"
3361 puts $aPbxprojFile "\t\t\};"
3362 puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
3363 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3364 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3365 puts $aPbxprojFile "${anExecExtension}"
3366 puts $aPbxprojFile "${anExecPrefix}"
3367 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3368 foreach aMacro $aTKDefines {
3369 puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3370 }
3371 puts $aPbxprojFile "\t\t\t\t);"
3372
3373 puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3374 foreach anIncPath $anIncPaths {
3375 puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3376 }
3377 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3378 puts $aPbxprojFile "\t\t\t\t);"
3379
3380 puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3381 foreach anLibPath $anLibPaths {
3382 puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3383 }
3384 puts $aPbxprojFile "\t\t\t\t);"
3385
3386 puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3387 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3388 puts $aPbxprojFile "\t\t\t\t);"
3389 puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3390 puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3391 puts $aPbxprojFile "\t\t\t\t);"
3392 puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3393 set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
3394 foreach anIncPath $anIncPaths {
3395 append anUserHeaderSearchPath " ${anIncPath}"
3396 }
3397 append anUserHeaderSearchPath "\";"
3398 puts $aPbxprojFile $anUserHeaderSearchPath
3399 puts $aPbxprojFile "${aWrapperExtension}"
3400 puts $aPbxprojFile "\t\t\t\};"
3401 puts $aPbxprojFile "\t\t\tname = Debug;"
3402 puts $aPbxprojFile "\t\t\};"
3403 puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
3404 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3405 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3406 puts $aPbxprojFile "${anExecExtension}"
3407 puts $aPbxprojFile "${anExecPrefix}"
3408 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3409 foreach aMacro $aTKDefines {
3410 puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3411 }
3412 puts $aPbxprojFile "\t\t\t\t);"
3413 puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3414 foreach anIncPath $anIncPaths {
3415 puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3416 }
3417 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3418 puts $aPbxprojFile "\t\t\t\t);"
3419
3420 puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3421 foreach anLibPath $anLibPaths {
3422 puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3423 }
3424 puts $aPbxprojFile "\t\t\t\t);"
3425
3426 puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3427 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3428 puts $aPbxprojFile "\t\t\t\t);"
3429 puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3430 puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3431 puts $aPbxprojFile "\t\t\t\t);"
3432 puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3433 puts $aPbxprojFile $anUserHeaderSearchPath
3434 puts $aPbxprojFile "${aWrapperExtension}"
3435 puts $aPbxprojFile "\t\t\t\};"
3436 puts $aPbxprojFile "\t\t\tname = Release;"
3437 puts $aPbxprojFile "\t\t\};\n"
3438 # End XCBuildConfiguration section
3439
3440 # Begin XCConfigurationList section
3441 puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
3442 puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3443 puts $aPbxprojFile "\t\tbuildConfigurations = ("
3444 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
3445 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
3446 puts $aPbxprojFile "\t\t\t);"
3447 puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3448 puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3449 puts $aPbxprojFile "\t\t\};"
3450 puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
3451 puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3452 puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
3453 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
3454 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
3455 puts $aPbxprojFile "\t\t\t);"
3456 puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3457 puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3458 puts $aPbxprojFile "\t\t\};\n"
3459 # End XCConfigurationList section
3460
3461 puts $aPbxprojFile "\t\};"
3462 puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3463 puts $aPbxprojFile "\}"
3464
3465 close $aPbxprojFile
3466}
3467
3468proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3469 set aUsername [exec whoami]
3470
3471 # Creating folders for Xcode project file.
3472 set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3473 wokUtils:FILES:mkdir $anExecutableDir
3474 if { ! [file exists $anExecutableDir] } {
3475 puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3476 return
3477 }
3478
3479 set aUserDataDir "${anExecutableDir}/xcuserdata"
3480 wokUtils:FILES:mkdir $aUserDataDir
3481 if { ! [file exists $aUserDataDir] } {
3482 puts stderr "Error: Could not create xcuserdata directorty in \"$anExecutableDir\""
3483 return
3484 }
3485
3486 set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3487 wokUtils:FILES:mkdir $aUserDataDir
3488 if { ! [file exists $aUserDataDir] } {
3489 puts stderr "Error: Could not create ${aUsername}.xcuserdatad directorty in \"$anExecutableDir\"/xcuserdata"
3490 return
3491 }
3492
3493 set aSchemesDir "${aUserDataDir}/xcschemes"
3494 wokUtils:FILES:mkdir $aSchemesDir
3495 if { ! [file exists $aSchemesDir] } {
3496 puts stderr "Error: Could not create xcschemes directorty in \"$aUserDataDir\""
3497 return
3498 }
3499 # End folders creation.
3500
3501 # Generating GUID for tookit.
3502 upvar $theGuidsMap aGuidsMap
3503 if { ! [info exists aGuidsMap($theExecutable)] } {
3504 set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3505 }
3506
3507 # Creating xcscheme file for toolkit from template.
3508 set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3509 regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3510 regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3511 set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme" "w"]
3512 puts $aXcschemeFile $aXcschemeTmpl
3513 close $aXcschemeFile
3514
3515 # Creating xcschememanagement.plist file for toolkit from template.
3516 set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3517 regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3518 regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3519 set aPlistFile [open "$aSchemesDir/xcschememanagement.plist" "w"]
3520 puts $aPlistFile $aPlistTmpl
3521 close $aPlistFile
3522}
7fbac3c2 3523
3524# Returns available Windows SDKs versions
3525proc osutils:sdk { theSdkMajorVer {isQuietMode false} {theSdkDirectories {}} } {
3526 if { ![llength ${theSdkDirectories}] } {
3527 foreach anEnvVar { "ProgramFiles" "ProgramFiles\(x86\)" "ProgramW6432" } {
3528 if {[ info exists ::env(${anEnvVar}) ]} {
3529 lappend theSdkDirectories "$::env(${anEnvVar})/Windows Kits/${theSdkMajorVer}/Include"
3530 }
3531 }
3532 }
3533
3534 set sdk_versions {}
3535 foreach sdk_dir ${theSdkDirectories} {
3536 if { [file isdirectory ${sdk_dir}] } {
3537 lappend sdk_versions [glob -tails -directory "${sdk_dir}" -type d *]
3538 }
3539 }
3540
3541 if {![llength ${sdk_versions}] && !${isQuietMode}} {
3542 error "Error : Could not find Windows SDK ${theSdkMajorVer}"
3543 }
3544
3545 return [join [lsort -unique ${sdk_versions}] " "]
3546}
3547
3548# Generate global properties to Visual Studio project file for UWP solution
d6cda17a 3549proc osutils:uwp:proj { isUWP theProjTmpl } {
7fbac3c2 3550
3551 set uwp_properties ""
3552 set uwp_generate_metadata ""
3553 set uwp_app_container ""
3554
3555 set format_template ""
3556
d6cda17a 3557 if { $isUWP } {
7fbac3c2 3558 set sdk_versions [osutils:sdk 10]
3559 set sdk_max_ver [lindex ${sdk_versions} end]
3560
3561 set uwp_properties "<DefaultLanguage>en-US</DefaultLanguage>\n \
3562<ApplicationType>Windows Store</ApplicationType>\n \
3563<ApplicationTypeRevision>10.0</ApplicationTypeRevision>\n \
3564<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\n \
3565<AppContainerApplication>true</AppContainerApplication>\n \
3566<WindowsTargetPlatformVersion>${sdk_max_ver}</WindowsTargetPlatformVersion>\n \
3567<WindowsTargetPlatformMinVersion>${sdk_max_ver}</WindowsTargetPlatformMinVersion>"
3568
3569 set uwp_generate_metadata "<GenerateWindowsMetadata>false</GenerateWindowsMetadata>"
3570
3571 regsub -all -- {[\r\n\s]*<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>} ${theProjTmpl} "" theProjTmpl
3572 } else {
3573 set format_template "\[\\r\\n\\s\]*"
3574 }
3575
3576 regsub -all -- "${format_template}__UWP_PROPERTIES__" ${theProjTmpl} "${uwp_properties}"