1 # =======================================================================
2 # Created on: 2014-07-24
4 # Copyright (c) 2014 OPEN CASCADE SAS
6 # This file is part of Open CASCADE Technology software library.
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.
14 # Alternatively, this file may be used under the terms of Open CASCADE
15 # commercial license or contractual agreement.
17 # =======================================================================
18 # This script defines Tcl command genproj generating project files for
19 # different IDEs and platforms. Run it with -help to get synopsis.
20 # =======================================================================
22 source [file join [file dirname [info script]] genconfdeps.tcl]
24 # the script is assumed to be run from CASROOT (or dependent Products root)
25 set path [file normalize .]
28 if { [info exists ::env(CASROOT)] } {
29 set THE_CASROOT [file normalize "$::env(CASROOT)"]
32 proc _get_options { platform type branch } {
34 if {[file exists "$::THE_CASROOT/adm/CMPLRS"]} {
35 set fd [open "$::THE_CASROOT/adm/CMPLRS" rb]
36 set opts [split [read $fd] "\n"]
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"
49 proc _get_type { name } {
51 if {[file exists "$::path/adm/UDLIST"]} {
52 set fd [open "$::path/adm/UDLIST" rb]
53 set UDLIST [concat $UDLIST [split [read $fd] "\n"]]
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"]]
62 foreach uitem $UDLIST {
63 set line [split $uitem]
64 if {[lindex $line 1] == "$name"} {
65 return [lindex $line 0]
71 proc _get_used_files { pk theSrcDir {inc true} {src true} } {
73 set type [_get_type $pk]
75 set pk_path "$path/$theSrcDir/$pk"
76 set FILES_path "$path/$theSrcDir/$pk/FILES"
78 if {[file exists $FILES_path]} {
79 set fd [open $FILES_path rb]
80 set FILES [split [read $fd] "\n"]
83 set FILES [lsearch -inline -all -not -exact $FILES ""]
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"
92 if {[regexp {:} $line]} {
93 regexp {[^:]*:+([^\s]*)} $line dummy line
95 regexp {([^\s]*)} $line dummy line
96 if {$src && [file exists $pk_path/$line]} {
97 lappend lret "source $line $pk_path/$line"
103 # return location of the path within source directory
104 proc osutils:findSrcSubPath {theSrcDir theSubPath} {
105 if {[file exists "$::path/$theSrcDir/$theSubPath"]} {
106 return "$::path/$theSrcDir/$theSubPath"
108 return "$::THE_CASROOT/$theSrcDir/$theSubPath"
111 # Auxiliary tool comparing content of two files line-by-line.
112 proc osutils:isEqualContent { theContent1 theContent2 } {
113 set aLen1 [llength $theContent1]
114 set aLen2 [llength $theContent2]
115 if { $aLen1 != $aLen2 } {
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 } {
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.
132 proc osutils:writeTextFile { theFile theContent {theEol lf} {theToBackup false} } {
133 if {[file exists "${theFile}"]} {
134 set aFileOld [open "${theFile}" rb]
135 fconfigure $aFileOld -translation crlf
136 set aLineListOld [split [read $aFileOld] "\n"]
139 # append empty line for proper comparison (which will be implicitly added by last puts below)
140 set aContent $theContent
142 if { [osutils:isEqualContent $aLineListOld $aContent] == true } {
146 if { $theToBackup == true } {
147 puts "Warning: file ${theFile} is updated. Old content is saved to ${theFile}.bak"
148 file copy -force -- "${theFile}" "${theFile}.bak"
150 file delete -force "${theFile}"
153 set anOutFile [open "$theFile" "w"]
154 fconfigure $anOutFile -translation $theEol
155 foreach aLine ${theContent} {
156 puts $anOutFile "${aLine}"
162 # Function re-generating header files for specified text resource
163 proc genResources { theSrcDir theResource } {
167 set aResourceAbsPath [file normalize "${path}/$theSrcDir/${theResource}"]
168 set aResourceDirectory ""
169 set isResDirectory false
171 if {[file isdirectory "${aResourceAbsPath}"]} {
172 if {[file exists "${aResourceAbsPath}/FILES"]} {
173 set aFilesFile [open "${aResourceAbsPath}/FILES" rb]
174 set aResFileList [split [read $aFilesFile] "\n"]
177 set aResFileList [lsearch -inline -all -not -exact $aResFileList ""]
178 set aResourceDirectory "${theResource}"
179 set isResDirectory true
181 set aResourceName [file tail "${theResource}"]
182 lappend aResFileList "res:::${aResourceName}"
183 set aResourceDirectory [file dirname "${theResource}"]
186 foreach aResFileIter ${aResFileList} {
187 if {![regexp {^[^:]+:::(.+)} "${aResFileIter}" dump aResFileIter]} {
191 set aResFileName [file tail "${aResFileIter}"]
192 regsub -all {\.} "${aResFileName}" {_} aResFileName
193 set aHeaderFileName "${aResourceDirectory}_${aResFileName}.pxx"
194 if { $isResDirectory == true && [lsearch $aResFileList $aHeaderFileName] == -1 } {
200 lappend aContent "// This file has been automatically generated from resource file $theSrcDir/${aResourceDirectory}/${aResFileIter}"
203 # generate necessary structures
205 if {[file exists "${path}/$theSrcDir/${aResourceDirectory}/${aResFileIter}"]} {
206 set anInputFile [open "${path}/$theSrcDir/${aResourceDirectory}/${aResFileIter}" rb]
207 fconfigure $anInputFile -translation crlf
208 set aLineList [split [read $anInputFile] "\n"]
212 # drop empty trailing line
214 if { [lindex $aLineList end] == "" } {
215 set aLineList [lreplace $aLineList end end]
216 set anEndOfFile "\\n"
219 lappend aContent "static const char ${aResourceDirectory}_${aResFileName}\[\] ="
220 set aNbLines [llength $aLineList]
221 set aLastLine [expr $aNbLines - 1]
222 for {set aLineIter 0} {$aLineIter < $aNbLines} {incr aLineIter} {
223 set aLine [lindex $aLineList $aLineIter]
224 regsub -all {\"} "${aLine}" {\\"} aLine
225 if { $aLineIter == $aLastLine } {
226 lappend aContent " \"${aLine}${anEndOfFile}\";"
228 lappend aContent " \"${aLine}\\n\""
232 # Save generated content to header file
233 set aHeaderFilePath "${path}/$theSrcDir/${aResourceDirectory}/${aHeaderFileName}"
234 if { [osutils:writeTextFile $aHeaderFilePath $aContent] == true } {
235 puts "Generating header file from resource file: ${path}/$theSrcDir/${aResourceDirectory}/${aResFileIter}"
237 #puts "Header file from resource ${path}/src/${aResourceDirectory}/${aResFileIter} is up-to-date"
242 # Function re-generating header files for all text resources
243 proc genAllResources { theSrcDir } {
245 set aCasRoot [file normalize $path]
246 if {![file exists "$aCasRoot/adm/RESOURCES"]} {
247 puts "OCCT directory is not defined correctly: $aCasRoot"
251 set aFileResources [open "$aCasRoot/adm/RESOURCES" rb]
252 set anAdmResources [split [read $aFileResources] "\r\n"]
253 close $aFileResources
254 set anAdmResources [lsearch -inline -all -not -exact $anAdmResources ""]
256 foreach line $anAdmResources {
257 genResources $theSrcDir "${line}"
261 # Wrapper-function to generate VS project files
262 proc genproj {theFormat args} {
263 set aSupportedFormats { "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "vc141" "vc142" "vclang" "cbp" "xcd" "pro"}
264 set aSupportedPlatforms { "wnt" "uwp" "lin" "mac" "ios" "qnx" }
265 set isHelpRequire false
267 # check format argument
268 if { $theFormat == "-h" || $theFormat == "-help" || $theFormat == "--help" } {
269 set isHelpRequire true
270 } elseif { [lsearch -exact $aSupportedFormats $theFormat] < 0 } {
271 puts "Error: genproj: unrecognized project format \"$theFormat\""
272 set isHelpRequire true
275 # choice of compiler for Code::Blocks, currently hard-coded
278 # Determine default platform: wnt for vc*, mac for xcd, current for cbp
279 if { [regexp "^vc" $theFormat] } {
281 } elseif { $theFormat == "xcd" || $::tcl_platform(os) == "Darwin" } {
283 } elseif { $::tcl_platform(platform) == "windows" } {
285 } elseif { $::tcl_platform(platform) == "unix" } {
289 # Check optional arguments
290 set aLibType "dynamic"
292 for {set anArgIter 0} {$anArgIter < [llength args]} {incr anArgIter} {
293 set arg [lindex $args $anArgIter]
296 } elseif { $arg == "-h" || $arg == "-help" || $arg == "--help" } {
297 set isHelpRequire true
298 } elseif { [lsearch -exact $aSupportedPlatforms $arg] >= 0 } {
300 } elseif { $arg == "-static" } {
301 set aLibType "static"
302 puts "Static build has been selected"
303 } elseif { $arg == "-dynamic" } {
304 set aLibType "dynamic"
305 puts "Dynamic build has been selected"
306 } elseif { $arg == "-solution" } {
308 set aSolution [lindex $args $anArgIter]
310 puts "Error: genproj: unrecognized option \"$arg\""
311 set isHelpRequire true
315 if { $isHelpRequire == true } {
316 puts "usage: genproj Format \[Platform\] \[-static\] \[-h|-help|--help\]
318 Format must be one of:
319 vc8 - Visual Studio 2005
320 vc9 - Visual Studio 2008
321 vc10 - Visual Studio 2010
322 vc11 - Visual Studio 2012
323 vc12 - Visual Studio 2013
324 vc14 - Visual Studio 2015
325 vc141 - Visual Studio 2017
326 vc142 - Visual Studio 2019
327 vclang - Visual Studio with ClangCL toolset
333 wnt - Windows Desktop
334 uwp - Universal Windows Platform
340 Option -static can be used with XCode to build static libraries
345 if { ! [info exists aPlatform] } {
346 puts "Error: genproj: Cannon identify default platform, please specify!"
350 puts "Preparing to generate $theFormat projects for $aPlatform platform..."
352 # base path to where to generate projects, hardcoded from current dir
353 set anAdmPath [file normalize "${::path}/adm"]
355 OS:MKPRC "$anAdmPath" "$theFormat" "$aLibType" "$aPlatform" "$aCmpl" "$aSolution"
357 genprojbat "$theFormat" "$aPlatform" "$aSolution"
358 genAllResources "src"
361 # copy file providing warning if the target file exists and has
362 # different date or size; if it is newer than source, save it as .bak
363 proc copy_with_warning {from to} {
364 if { [file exists "$to"] &&
365 ([file size "$to"] != [file size "$from"] ||
366 [file mtime "$to"] != [file mtime "$from"]) } {
367 puts "Warning: file $to is updated (copied from $from)!"
368 if { [file mtime $to] > [file mtime $from] } {
369 puts "Info: old content of file $to is saved in ${to}.bak"
370 file copy -force -- "$to" "${to}.bak"
374 file copy -force -- "$from" "$to"
377 # Generate auxiliary scripts for launching IDE.
378 proc genprojbat {theFormat thePlatform theSolution} {
379 set aTargetPlatformExt sh
381 if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
382 set aTargetPlatformExt bat
386 if { [file exists "$::path/src/OS/FoundationClasses.tcl"] || ![file exists "$::path/env.${aTargetPlatformExt}"] } {
387 # generate env.bat/sh
388 set anEnvTmplFilePath "$::THE_CASROOT/adm/templates/env.${aTargetPlatformExt}"
389 set anEnvTmplFile [open "$anEnvTmplFilePath" "r"]
390 set anEnvTmpl [read $anEnvTmplFile]
394 if { [file normalize "$::path"] != [file normalize "$::THE_CASROOT"] } {
395 set aCasRoot [relativePath "$::path" "$::THE_CASROOT"]
398 regsub -all -- {__CASROOT__} $anEnvTmpl "$aCasRoot" anEnvTmpl
399 set aLineList [split $anEnvTmpl "\n"]
400 osutils:writeTextFile "$::path/env.${aTargetPlatformExt}" $aLineList $aTargetEol true
402 copy_with_warning "$::THE_CASROOT/adm/templates/draw.${aTargetPlatformExt}" "$::path/draw.${aTargetPlatformExt}"
404 if { "$::BUILD_Inspector" == "true" } {
405 copy_with_warning "$::THE_CASROOT/adm/templates/inspector.${aTargetPlatformExt}" "$::path/inspector.${aTargetPlatformExt}"
410 if { [regexp {^vc} $theFormat] } {
411 set aSolShList "msvc.bat"
413 switch -exact -- "$theFormat" {
415 set aSolShList { "codeblocks.sh" "codeblocks.bat" }
416 # Code::Blocks 16.01 does not create directory for import libs, help him
417 set aPlatformAndCompiler "${thePlatform}/gcc"
418 if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } {
419 set aPlatformAndCompiler "${thePlatform}/clang"
421 file mkdir "$::path/${aPlatformAndCompiler}/lib"
422 file mkdir "$::path/${aPlatformAndCompiler}/libd"
424 "xcd" { set aSolShList "xcode.sh" }
428 foreach aSolSh $aSolShList {
429 set anShFile [open "$::THE_CASROOT/adm/templates/${aSolSh}" "r"]
430 set anShTmpl [read $anShFile]
433 regsub -all -- {__SOLUTION__} $anShTmpl "$theSolution" anShTmpl
435 set anShFile [open "$::path/${aSolSh}" "w"]
436 puts $anShFile $anShTmpl
441 ###### MSVC #############################################################33
442 proc removeAllOccurrencesOf { theObject theList } {
443 set aSortIndices [lsort -decreasing [lsearch -all -nocase $theList $theObject]]
444 foreach anIndex $aSortIndices {
445 set theList [lreplace $theList $anIndex $anIndex]
450 set aTKNullKey "TKNull"
451 set THE_GUIDS_LIST($aTKNullKey) "{00000000-0000-0000-0000-000000000000}"
453 # Entry function to generate project files
454 # @param theOutDir Root directory for project files
455 # @param theFormat Project format name (vc.. for Visual Studio projects, cbp for Code::Blocks, xcd for XCode)
456 # @param theLibType Library type - dynamic or static
457 # @param thePlatform Optional target platform for cross-compiling, e.g. ios for iOS
458 # @param theCmpl Compiler option (msvc or gcc)
459 # @param theSolution Solution name
460 proc OS:MKPRC { theOutDir theFormat theLibType thePlatform theCmpl theSolution } {
462 set anOutRoot $theOutDir
463 if { $anOutRoot == "" } {
464 error "Error : \"theOutDir\" is not initialized"
467 # Create output directory
468 set aWokStation "$thePlatform"
469 if { [regexp {^vc} $theFormat] } {
470 set aWokStation "msvc"
474 if { $thePlatform == "uwp" } {
478 set anOutDir "${anOutRoot}/${aWokStation}/${theFormat}${aSuffix}"
480 # read map of already generated GUIDs
481 set aGuidsFilePath [file join $anOutDir "wok_${theFormat}_guids.txt"]
482 if [file exists "$aGuidsFilePath"] {
483 set aFileIn [open "$aGuidsFilePath" r]
484 set aFileDataRaw [read $aFileIn]
486 set aFileData [split $aFileDataRaw "\n"]
487 foreach aLine $aFileData {
488 set aLineSplt [split $aLine "="]
489 if { [llength $aLineSplt] == 2 } {
490 set ::THE_GUIDS_LIST([lindex $aLineSplt 0]) [lindex $aLineSplt 1]
495 # make list of modules and platforms
496 set aModules [OS:init OS Modules]
497 if { [llength $aModules] == 0 } {
498 set aModules [OS:init VAS Products]
500 if { "$thePlatform" == "ios" } {
501 set goaway [list Draw]
502 set aModules [osutils:juststation $goaway $aModules]
505 # Draw module is turned off due to it is not supported on UWP
507 set aDrawIndex [lsearch -exact ${aModules} "Draw"]
508 if { ${aDrawIndex} != -1 } {
509 set aModules [lreplace ${aModules} ${aDrawIndex} ${aDrawIndex}]
513 # create the out dir if it does not exist
514 if (![file isdirectory $path/inc]) {
515 puts "$path/inc folder does not exists and will be created"
516 wokUtils:FILES:mkdir $path/inc
519 # collect all required header files
520 puts "Collecting required header files into $path/inc ..."
521 osutils:collectinc $aModules "src" $path/inc
523 # make list of Inspector tools
525 if { "$::BUILD_Inspector" == "true" } {
526 set aTools [OS:init OS Tools]
527 if { [llength $aTools] == 0 } {
528 set aTools [OS:init VAS Tools]
531 # create the out dir if it does not exist
532 if (![file isdirectory $path/inc/inspector]) {
533 puts "$path/inc/inspector folder does not exists and will be created"
534 wokUtils:FILES:mkdir $path/inc/inspector
537 # collect all required header files
538 puts "Collecting required tools header files into $path/inc/inspector ..."
539 osutils:collectinc $aTools "tools" $path/inc/inspector
542 if { "$theFormat" == "pro" } {
546 wokUtils:FILES:mkdir $anOutDir
547 if { ![file exists $anOutDir] } {
548 puts stderr "Error: Could not create output directory \"$anOutDir\""
552 # Generating project files for the selected format
553 switch -exact -- "$theFormat" {
563 "vclang" { OS:MKVC $anOutDir $aModules $aTools $theSolution $theFormat $isUWP}
564 "cbp" { OS:MKCBP $anOutDir $aModules $theSolution $thePlatform $theCmpl }
566 set ::THE_GUIDS_LIST($::aTKNullKey) "000000000000000000000000"
567 OS:MKXCD $anOutDir $aModules $theSolution $theLibType $thePlatform
571 # Store generated GUIDs map
572 set anOutFile [open "$aGuidsFilePath" "w"]
573 fconfigure $anOutFile -translation lf
574 foreach aKey [array names ::THE_GUIDS_LIST] {
575 set aValue $::THE_GUIDS_LIST($aKey)
576 puts $anOutFile "${aKey}=${aValue}"
581 # Function to generate Visual Studio solution and project files
582 proc OS:MKVC { theOutDir theModules theTools theAllSolution theVcVer isUWP } {
584 puts stderr "Generating VS project files for $theVcVer"
586 # generate projects for toolkits and separate solution for each module
587 foreach aModule $theModules {
588 OS:vcsolution $theVcVer $aModule $aModule $theOutDir ::THE_GUIDS_LIST "src" "" ""
589 OS:vcproj $theVcVer $isUWP $aModule $theOutDir ::THE_GUIDS_LIST "src" ""
592 # generate projects for toolkits and separate solution for each tool
593 foreach aTool $theTools {
594 OS:vcsolution $theVcVer $aTool $aTool $theOutDir ::THE_GUIDS_LIST "tools" "" "src"
595 OS:vcproj $theVcVer $isUWP $aTool $theOutDir ::THE_GUIDS_LIST "tools" "src"
598 # generate single solution "OCCT" containing projects from all modules
599 if { "$theAllSolution" != "" } {
600 OS:vcsolution $theVcVer $theAllSolution $theModules $theOutDir ::THE_GUIDS_LIST "src" $theTools "tools"
603 puts "The Visual Studio solution and project files are stored in the $theOutDir directory"
606 proc OS:init {theVas theNameOfDefFile {os {}}} {
610 set os $::tcl_platform(os)
613 if { ![file exists "$::path/src/${theVas}/${theNameOfDefFile}.tcl"]} {
617 # Load list of OCCT modules and their definitions
618 source "$::path/src/${theVas}/${theNameOfDefFile}.tcl"
619 foreach aModuleIter [${theVas}:${theNameOfDefFile}] {
620 set aFileTcl "$::path/src/${theVas}/${aModuleIter}.tcl"
621 if [file exists $aFileTcl] {
623 lappend aModules $aModuleIter
625 puts stderr "Definition file for $aModuleIter is not found in unit ${theVas}"
632 # topological sort. returns a list { {a h} {b g} {c f} {c h} {d i} } => { d a b c i g f h }
633 proc wokUtils:EASY:tsort { listofpairs } {
634 foreach x $listofpairs {
637 if ![info exists pcnt($e1)] {
640 if ![ info exists pcnt($e2)] {
645 if ![info exists scnt($e1)] {
651 if [info exists slist($e1)] {
659 foreach node [array names pcnt] {
661 if { $pcnt($node) == 0 } {
665 if ![info exists scnt($node)] {
670 for {set front 1} { $front <= $back } { incr front } {
671 lappend res [set node $q($front)]
672 for {set i 1} {$i <= $scnt($node) } { incr i } {
674 set j [expr {$i - 1}]
675 set u [expr { $pcnt([lindex $ll $j]) - 1 }]
676 if { [set pcnt([lindex $ll $j]) $u] == 0 } {
678 set q($back) [lindex $ll $j]
682 if { $back != $nodecnt } {
683 puts stderr "input contains a cycle"
690 proc wokUtils:LIST:Purge { l } {
693 if ![info exist tab($e)] {
701 # Read file pointed to by path
703 # 2. trim = 1 plusieurs blancs => 1 seul blanc
704 # 3. purge= not yet implemented.
705 # 4. emptl= dont process blank lines
706 proc wokUtils:FILES:FileToList { path {sort 0} {trim 0} {purge 0} {emptl 1} } {
707 if ![ catch { set id [ open $path r ] } ] {
709 while {[gets $id line] >= 0 } {
711 regsub -all {[ ]+} $line " " line
714 if { [string length ${line}] != 0 } {
732 # retorn the list of executables in module.
733 proc OS:executable { module } {
735 foreach XXX [${module}:ressources] {
736 if { "[lindex $XXX 1]" == "x" } {
737 lappend lret [lindex $XXX 2]
743 # Topological sort of toolkits in tklm
744 proc osutils:tk:sort { tklm theSrcDir theSourceDirOther } {
746 foreach tkloc $tklm {
747 set lprg [wokUtils:LIST:Purge [osutils:tk:close $tkloc $theSrcDir $theSourceDirOther]]
749 if { [lsearch $tklm $tkx] != -1 } {
750 lappend tkby2 [list $tkx $tkloc]
752 lappend tkby2 [list $tkloc {}]
757 foreach e [wokUtils:EASY:tsort $tkby2] {
765 # close dependencies of ltk. (full work paths of toolkits)
766 # The CURRENT WOK LOCATION MUST contains ALL TOOLKITS required.
767 # (locate not performed.)
768 proc osutils:tk:close { ltk theSrcDir theSourceDirOther } {
772 set ids [LibToLink $dir $theSrcDir $theSourceDirOther]
773 # puts "osutils:tk:close($ltk) ids='$ids'"
774 set eated [osutils:tk:eatpk $ids]
775 set result [concat $result $eated]
776 set ids [LibToLink $dir $theSrcDir $theSourceDirOther]
777 set result [concat $result $ids]
779 foreach file $eated {
780 set kds [osutils:findSrcSubPath $theSrcDir "$file/EXTERNLIB"]
781 if { [osutils:tk:eatpk $kds] != {} } {
782 lappend recurse $file
786 if { $recurse != {} } {
787 set result [concat $result [osutils:tk:close $recurse $theSrcDir $theSourceDirOther]]
792 proc osutils:tk:eatpk { EXTERNLIB } {
793 set l [wokUtils:FILES:FileToList $EXTERNLIB]
796 if ![regexp -- {(CSF_[^ ]*)} $str csf] {
802 # Define libraries to link using only EXTERNLIB file
804 proc LibToLink {theTKit theSrcDir theSourceDirOther} {
805 regexp {^.*:([^:]+)$} $theTKit dummy theTKit
806 set type [_get_type $theTKit]
807 if {$type != "t" && $type != "x"} {
811 set anExtLibList [osutils:tk:eatpk [osutils:findSrcSubPath $theSrcDir "$theTKit/EXTERNLIB"]]
812 foreach anExtLib $anExtLibList {
813 set aFullPath [LocateRecur $anExtLib $theSrcDir]
814 if { "$aFullPath" == "" && "$theSourceDirOther" != "" } {
815 set aFullPath [LocateRecur $anExtLib $theSourceDirOther]
817 if { "$aFullPath" != "" && [_get_type $anExtLib] == "t" } {
818 lappend aToolkits $anExtLib
823 # Search unit recursively
825 proc LocateRecur {theName theSrcDir} {
826 set theNamePath [osutils:findSrcSubPath $theSrcDir "$theName"]
827 if {[file isdirectory $theNamePath]} {
833 proc OS:genGUID { {theFormat "vc"} } {
834 if { "$theFormat" == "vc" } {
835 set p1 "[format %07X [expr { int(rand() * 268435456) }]][format %X [expr { int(rand() * 16) }]]"
836 set p2 "[format %04X [expr { int(rand() * 6536) }]]"
837 set p3 "[format %04X [expr { int(rand() * 6536) }]]"
838 set p4 "[format %04X [expr { int(rand() * 6536) }]]"
839 set p5 "[format %06X [expr { int(rand() * 16777216) }]][format %06X [expr { int(rand() * 16777216) }]]"
840 return "{$p1-$p2-$p3-$p4-$p5}"
842 set p1 "[format %04X [expr { int(rand() * 6536) }]]"
843 set p2 "[format %04X [expr { int(rand() * 6536) }]]"
844 set p3 "[format %04X [expr { int(rand() * 6536) }]]"
845 set p4 "[format %04X [expr { int(rand() * 6536) }]]"
846 set p5 "[format %04X [expr { int(rand() * 6536) }]]"
847 set p6 "[format %04X [expr { int(rand() * 6536) }]]"
848 return "$p1$p2$p3$p4$p5$p6"
852 # collect all include file that required for theModules in theOutDir
853 proc osutils:collectinc {theModules theSrcDir theIncPath} {
855 set aCasRoot [file normalize $path]
856 set anIncPath [file normalize $theIncPath]
858 if {![file isdirectory $aCasRoot]} {
859 puts "OCCT directory is not defined correctly: $aCasRoot"
863 set anUsedToolKits {}
864 foreach aModule $theModules {
865 foreach aToolKit [${aModule}:toolkits] {
866 lappend anUsedToolKits $aToolKit
868 foreach aDependency [LibToLink $aToolKit $theSrcDir ""] {
869 lappend anUsedToolKits $aDependency
872 foreach anExecutable [OS:executable ${aModule}] {
873 lappend anUsedToolKits $anExecutable
875 foreach aDependency [LibToLink $anExecutable $theSrcDir ""] {
876 lappend anUsedToolKits $aDependency
880 set anUsedToolKits [lsort -unique $anUsedToolKits]
883 foreach anUsedToolKit $anUsedToolKits {
884 set anUnits [concat $anUnits [osutils:tk:units $anUsedToolKit $theSrcDir] ]
886 set anUnits [lsort -unique $anUnits]
888 # define copying style
890 if { [info exists ::env(SHORTCUT_HEADERS)] } {
891 if { [string equal -nocase $::env(SHORTCUT_HEADERS) "hard"]
892 || [string equal -nocase $::env(SHORTCUT_HEADERS) "hardlink"] } {
893 set aCopyType "hardlink"
894 } elseif { [string equal -nocase $::env(SHORTCUT_HEADERS) "true"]
895 || [string equal -nocase $::env(SHORTCUT_HEADERS) "shortcut"] } {
896 set aCopyType "shortcut"
900 set allHeaderFiles {}
901 if { $aCopyType == "shortcut" } {
902 # template preparation
903 if { ![file exists $::THE_CASROOT/adm/templates/header.in] } {
904 puts "template file does not exist: $::THE_CASROOT/adm/templates/header.in"
907 set aHeaderTmpl [wokUtils:FILES:FileToString $::THE_CASROOT/adm/templates/header.in]
909 # relative anIncPath in connection with aCasRoot/$theSrcDir
910 set aFromBuildIncToSrcPath [relativePath "$anIncPath" "$aCasRoot/$theSrcDir"]
912 # create and copy shortcut header files
913 foreach anUnit $anUnits {
914 osutils:checksrcfiles ${anUnit} $theSrcDir
916 set aHFiles [_get_used_files ${anUnit} $theSrcDir true false]
917 foreach aHeaderFile ${aHFiles} {
918 set aHeaderFileName [lindex ${aHeaderFile} 1]
919 lappend allHeaderFiles "${aHeaderFileName}"
921 regsub -all -- {@OCCT_HEADER_FILE_CONTENT@} $aHeaderTmpl "#include \"$aFromBuildIncToSrcPath/$anUnit/$aHeaderFileName\"" aShortCutHeaderFileContent
923 if {[file exists "$theIncPath/$aHeaderFileName"] && [file readable "$theIncPath/$aHeaderFileName"]} {
924 set fp [open "$theIncPath/$aHeaderFileName" r]
925 set aHeaderContent [read $fp]
929 set aHeaderLenght [expr [string length $aHeaderContent] - 1]
931 if {$aHeaderLenght == [string length $aShortCutHeaderFileContent]} {
932 # remove eof from string
933 set aHeaderContent [string range $aHeaderContent 0 [expr $aHeaderLenght - 1]]
935 if {[string compare $aShortCutHeaderFileContent $aHeaderContent] == 0} {
939 file delete -force "$theIncPath/$aHeaderFileName"
942 set aShortCutHeaderFile [open "$theIncPath/$aHeaderFileName" "w"]
943 fconfigure $aShortCutHeaderFile -translation lf
944 puts $aShortCutHeaderFile $aShortCutHeaderFileContent
945 close $aShortCutHeaderFile
950 foreach anUnit $anUnits {
951 osutils:checksrcfiles ${anUnit} $theSrcDir
953 set aHFiles [_get_used_files ${anUnit} $theSrcDir true false]
954 foreach aHeaderFile ${aHFiles} {
955 set aHeaderFileName [lindex ${aHeaderFile} 1]
956 lappend allHeaderFiles "${aHeaderFileName}"
958 # copy file only if target does not exist or is older than original
959 set torig [file mtime $aCasRoot/$theSrcDir/$anUnit/$aHeaderFileName]
961 if { [file isfile $anIncPath/$aHeaderFileName] } {
962 set tcopy [file mtime $anIncPath/$aHeaderFileName]
964 if { $tcopy < $torig } {
966 if { $aCopyType == "hardlink" } {
968 file delete -force "$theIncPath/$aHeaderFileName"
970 file link -hard $anIncPath/$aHeaderFileName $aCasRoot/$theSrcDir/$anUnit/$aHeaderFileName
972 file copy -force $aCasRoot/$theSrcDir/$anUnit/$aHeaderFileName $anIncPath/$aHeaderFileName
974 } elseif { $tcopy != $torig } {
975 puts "Warning: file $anIncPath/$aHeaderFileName is newer than $aCasRoot/$theSrcDir/$anUnit/$aHeaderFileName, not changed!"
979 puts "Info: $nbcopied files updated"
982 # remove header files not listed in FILES
983 set anIncFiles [glob -tails -nocomplain -dir ${anIncPath} "*"]
984 foreach anIncFile ${anIncFiles} {
985 if { [lsearch -exact ${allHeaderFiles} ${anIncFile}] == -1 } {
986 puts "Warning: file ${anIncPath}/${anIncFile} is not present in the sources and will be removed from ${theIncPath}"
987 file delete -force "${theIncPath}/${anIncFile}"
992 # Generate header for VS solution file
993 proc osutils:vcsolution:header { vcversion } {
994 if { "$vcversion" == "vc7" } {
996 "Microsoft Visual Studio Solution File, Format Version 8.00\n"
997 } elseif { "$vcversion" == "vc8" } {
999 "Microsoft Visual Studio Solution File, Format Version 9.00\n" \
1000 "# Visual Studio 2005\n"
1001 } elseif { "$vcversion" == "vc9" } {
1003 "Microsoft Visual Studio Solution File, Format Version 10.00\n" \
1004 "# Visual Studio 2008\n"
1005 } elseif { "$vcversion" == "vc10" } {
1007 "Microsoft Visual Studio Solution File, Format Version 11.00\n" \
1008 "# Visual Studio 2010\n"
1009 } elseif { "$vcversion" == "vc11" } {
1011 "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
1012 "# Visual Studio 2012\n"
1013 } elseif { "$vcversion" == "vc12" } {
1015 "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
1016 "# Visual Studio 2013\n"
1017 } elseif { "$vcversion" == "vc14" || "$vcversion" == "vc141" ||
1018 "$vcversion" == "vc142" || "$vcversion" == "vclang" } {
1020 "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
1021 "# Visual Studio 14\n"
1023 puts stderr "Error: Visual Studio version $vcversion is not supported by this function!"
1027 # Returns extension (without dot) for project files of given version of VC
1029 proc osutils:vcproj:ext { vcversion } {
1030 if { "$vcversion" == "vc7" || "$vcversion" == "vc8" || "$vcversion" == "vc9" } {
1036 # Generate start of configuration section of VS solution file
1038 proc osutils:vcsolution:config:begin { vcversion } {
1039 if { "$vcversion" == "vc7" } {
1042 "\tGlobalSection(SolutionConfiguration) = preSolution\n" \
1043 "\t\tDebug = Debug\n" \
1044 "\t\tRelease = Release\n" \
1045 "\tEndGlobalSection\n" \
1046 "\tGlobalSection(ProjectConfiguration) = postSolution\n"
1050 "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" \
1051 "\t\tDebug|Win32 = Debug|Win32\n" \
1052 "\t\tRelease|Win32 = Release|Win32\n" \
1053 "\t\tDebug|x64 = Debug|x64\n" \
1054 "\t\tRelease|x64 = Release|x64\n" \
1055 "\tEndGlobalSection\n" \
1056 "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"
1060 # Generate part of configuration section of VS solution file describing one project
1062 proc osutils:vcsolution:config:project { vcversion guid } {
1063 if { "$vcversion" == "vc7" } {
1065 "\t\t$guid.Debug.ActiveCfg = Debug|Win32\n" \
1066 "\t\t$guid.Debug.Build.0 = Debug|Win32\n" \
1067 "\t\t$guid.Release.ActiveCfg = Release|Win32\n" \
1068 "\t\t$guid.Release.Build.0 = Release|Win32\n"
1071 "\t\t$guid.Debug|Win32.ActiveCfg = Debug|Win32\n" \
1072 "\t\t$guid.Debug|Win32.Build.0 = Debug|Win32\n" \
1073 "\t\t$guid.Release|Win32.ActiveCfg = Release|Win32\n" \
1074 "\t\t$guid.Release|Win32.Build.0 = Release|Win32\n" \
1075 "\t\t$guid.Debug|x64.ActiveCfg = Debug|x64\n" \
1076 "\t\t$guid.Debug|x64.Build.0 = Debug|x64\n" \
1077 "\t\t$guid.Release|x64.ActiveCfg = Release|x64\n" \
1078 "\t\t$guid.Release|x64.Build.0 = Release|x64\n"
1082 # Generate start of configuration section of VS solution file
1084 proc osutils:vcsolution:config:end { vcversion } {
1085 if { "$vcversion" == "vc7" } {
1087 "\tEndGlobalSection\n" \
1088 "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" \
1089 "\tEndGlobalSection\n" \
1090 "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" \
1091 "\tEndGlobalSection\n"
1094 "\tEndGlobalSection\n" \
1095 "\tGlobalSection(SolutionProperties) = preSolution\n" \
1096 "\t\tHideSolutionNode = FALSE\n" \
1097 "\tEndGlobalSection\n"
1101 # generate Visual Studio solution file
1102 # if module is empty, generates one solution for all known modules
1104 proc OS:vcsolution { theVcVer theSolName theModules theOutDir theGuidsMap theSrcDir theModulesOther theSourceDirOther } {
1106 upvar $theGuidsMap aGuidsMap
1108 # collect list of projects to be created
1110 set aDependencies {}
1112 osutils:convertModules $theModules $theSrcDir $theSourceDirOther aProjects aProjectsInModule aDependencies
1113 osutils:convertModules $theModulesOther $theSourceDirOther $theSrcDir aProjects aProjectsInModule aDependencies
1115 # generate GUIDs for projects (unless already known)
1116 foreach aProject $aProjects {
1117 if { ! [info exists aGuidsMap($aProject)] } {
1118 set aGuidsMap($aProject) [OS:genGUID]
1122 # generate solution file
1123 # puts "Generating Visual Studio ($theVcVer) solution file for $theSolName ($aProjects)"
1124 append aFileBuff [osutils:vcsolution:header $theVcVer]
1126 # GUID identifying group projects in Visual Studio
1127 set VC_GROUP_GUID "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"
1129 # generate group projects -- one per module
1130 if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
1131 foreach aModule $theModules {
1132 if { ! [info exists aGuidsMap(_$aModule)] } {
1133 set aGuidsMap(_$aModule) [OS:genGUID]
1135 set aGuid $aGuidsMap(_$aModule)
1136 append aFileBuff "Project(\"${VC_GROUP_GUID}\") = \"$aModule\", \"$aModule\", \"$aGuid\"\nEndProject\n"
1140 if { "$theVcVer" != "vc7" && [llength "$theModulesOther"] > 1 } {
1142 if { ! [info exists aGuidsMap(_$aModule)] } {
1143 set aGuidsMap(_$aModule) [OS:genGUID]
1145 set aGuid $aGuidsMap(_$aModule)
1146 append aFileBuff "Project(\"${VC_GROUP_GUID}\") = \"$aModule\", \"$aModule\", \"$aGuid\"\nEndProject\n"
1149 # extension of project files
1150 set aProjExt [osutils:vcproj:ext $theVcVer]
1152 # GUID identifying C++ projects in Visual Studio
1153 set VC_CPP_GUID "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
1155 # generate normal projects
1156 set aProjsNb [llength $aProjects]
1157 for {set aProjId 0} {$aProjId < $aProjsNb} {incr aProjId} {
1158 set aProj [lindex $aProjects $aProjId]
1159 set aGuid $aGuidsMap($aProj)
1160 append aFileBuff "Project(\"${VC_CPP_GUID}\") = \"$aProj\", \"$aProj.${aProjExt}\", \"$aGuid\"\n"
1161 # write projects dependencies information (vc7 to vc9)
1163 foreach aDepLib [lindex $aDependencies $aProjId] {
1164 if { $aDepLib != $aProj && [lsearch $aProjects $aDepLib] != "-1" } {
1165 set depGUID $aGuidsMap($aDepLib)
1166 append aDepGuids "\t\t$depGUID = $depGUID\n"
1169 if { "$aDepGuids" != "" } {
1170 append aFileBuff "\tProjectSection(ProjectDependencies) = postProject\n"
1171 append aFileBuff "$aDepGuids"
1172 append aFileBuff "\tEndProjectSection\n"
1174 append aFileBuff "EndProject\n"
1177 # generate configuration section
1178 append aFileBuff [osutils:vcsolution:config:begin $theVcVer]
1179 foreach aProj $aProjects {
1180 append aFileBuff [osutils:vcsolution:config:project $theVcVer $aGuidsMap($aProj)]
1182 append aFileBuff [osutils:vcsolution:config:end $theVcVer]
1184 # write information of grouping of projects by module
1185 if { "$theVcVer" != "vc7" && [llength "$theModules"] > 1 } {
1186 append aFileBuff " GlobalSection(NestedProjects) = preSolution\n"
1187 foreach aModule $theModules {
1188 if { ! [info exists aProjectsInModule($aModule)] } { continue }
1189 foreach aProject $aProjectsInModule($aModule) {
1190 append aFileBuff " $aGuidsMap($aProject) = $aGuidsMap(_$aModule)\n"
1193 set aToolsName "Tools"
1194 foreach aModule $theModulesOther {
1195 if { ! [info exists aProjectsInModule($aModule)] } { continue }
1196 foreach aProject $aProjectsInModule($aModule) {
1197 append aFileBuff " $aGuidsMap($aProject) = $aGuidsMap(_$aToolsName)\n"
1200 append aFileBuff " EndGlobalSection\n"
1203 # final word (footer)
1204 append aFileBuff "EndGlobal"
1207 set aFile [open [set fdsw [file join $theOutDir ${theSolName}.sln]] w]
1208 fconfigure $aFile -translation crlf
1209 puts $aFile $aFileBuff
1211 return [file join $theOutDir ${theSolName}.sln]
1214 # Generate auxiliary containers with information about modules.
1215 # @param theModules List of modules
1216 # @param theSrcDir Directory of module toolkits
1217 # @param theSourceDirOther Directory with other additional sources to find out toolkits in dependencies
1218 # @param theProjects list of all found projects/toolkits
1219 # @param theProjectsInModule map of module into toolkits/projects
1220 # @param theDependencies list of the project dependencies. To find the project dependencies, get it by the index in project container
1221 proc osutils:convertModules { theModules theSrcDir theSourceDirOther theProjects theProjectsInModule theDependencies } {
1223 upvar $theProjectsInModule aProjectsInModule
1224 upvar $theProjects aProjects
1225 upvar $theDependencies aDependencies
1227 foreach aModule $theModules {
1229 foreach aToolKit [osutils:tk:sort [${aModule}:toolkits] $theSrcDir $theSourceDirOther] {
1230 lappend aProjects $aToolKit
1231 lappend aProjectsInModule($aModule) $aToolKit
1232 lappend aDependencies [LibToLink $aToolKit $theSrcDir $theSourceDirOther]
1234 # executables, assume one project per cxx file...
1235 foreach aUnit [OS:executable ${aModule}] {
1237 set src_files [_get_used_files $aUnit $theSrcDir false]
1239 foreach s $src_files {
1240 regexp {source ([^\s]+)} $s dummy name
1241 lappend aSrcFiles $name
1243 foreach aSrcFile $aSrcFiles {
1244 set aFileExtension [file extension $aSrcFile]
1245 if { $aFileExtension == ".cxx" } {
1246 set aPrjName [file rootname $aSrcFile]
1247 lappend aProjects $aPrjName
1248 lappend aProjectsInModule($aModule) $aPrjName
1249 if {[file isdirectory $path/$theSrcDir/$aUnitLoc]} {
1250 lappend aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile] $theSrcDir $theSourceDirOther]
1252 lappend aDependencies {}
1259 # Generate Visual Studio projects for specified version
1261 proc OS:vcproj { theVcVer isUWP theModules theOutDir theGuidsMap theSrcDir theSourceDirOther } {
1262 upvar $theGuidsMap aGuidsMap
1264 set aProjectFiles {}
1266 foreach aModule $theModules {
1267 foreach aToolKit [${aModule}:toolkits] {
1268 lappend aProjectFiles [osutils:vcproj $theVcVer $isUWP $theOutDir $aToolKit aGuidsMap $theSrcDir $theSourceDirOther]
1270 foreach anExecutable [OS:executable ${aModule}] {
1271 lappend aProjectFiles [osutils:vcprojx $theVcVer $isUWP $theOutDir $anExecutable aGuidsMap $theSrcDir $theSourceDirOther]
1274 return $aProjectFiles
1276 # generate template name and load it for given version of Visual Studio and platform
1278 proc osutils:vcproj:readtemplate {theVcVer isUWP isExec} {
1280 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1284 # determine versions of runtime and toolset
1285 set aVCRTVer $theVcVer
1286 set aToolset "v[string range $theVcVer 2 3]0"
1287 if { $theVcVer == "vc141" } {
1290 } elseif { $theVcVer == "vc142" } {
1293 } elseif { $theVcVer == "vclang" } {
1295 set aToolset "ClangCL"
1298 set what "$theVcVer"
1301 set aCharSet "Unicode"
1303 set anExt "${anExt}x"
1304 set what "$what executable"
1306 if { "$theVcVer" == "vc10" } {
1307 # SSE2 is enabled by default in vc11+, but not in vc10 for 32-bit target
1308 set aCmpl32 "<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>"
1310 set aTmpl [osutils:readtemplate $anExt "MS VC++ project ($what)"]
1313 set UwpWinRt "<CompileAsWinRT>false</CompileAsWinRT>"
1314 foreach bitness {32 64} {
1316 if {"[set aCmpl${bitness}]" != ""} {
1319 set aCmpl${bitness} "[set aCmpl${bitness}]${indent}${UwpWinRt}"
1323 set format_template "\[\\r\\n\\s\]*"
1324 foreach bitness {32 64} {
1325 set format_templateloc ""
1326 if {"[set aCmpl${bitness}]" == ""} {
1327 set format_templateloc "$format_template"
1329 regsub -all -- "${format_templateloc}__VCMPL${bitness}__" $aTmpl "[set aCmpl${bitness}]" aTmpl
1334 if { "$::HAVE_RelWithDebInfo" == "true" } {
1335 set aDebugInfo "true"
1336 set aReleaseLnk "\n <OptimizeReferences>true</OptimizeReferences>\n <EnableCOMDATFolding>true</EnableCOMDATFolding>"
1339 regsub -all -- {__VCVER__} $aTmpl $aVCRTVer aTmpl
1340 regsub -all -- {__VCVEREXT__} $aTmpl $aToolset aTmpl
1341 regsub -all -- {__VCCHARSET__} $aTmpl $aCharSet aTmpl
1342 regsub -all -- {__VCReleasePDB__} $aTmpl $aDebugInfo aTmpl
1343 regsub -all -- "${format_template}__VCLNKREL__" $aTmpl "${aReleaseLnk}" aTmpl
1348 proc osutils:readtemplate {ext what} {
1349 set loc "$::THE_CASROOT/adm/templates/template.$ext"
1350 return [wokUtils:FILES:FileToString $loc]
1352 # Read a file in a string as is.
1354 proc wokUtils:FILES:FileToString { fin } {
1355 if { [catch { set in [ open $fin r ] } errin] == 0 } {
1356 set strin [read $in [file size $fin]]
1364 # List extensions of compilable files in OCCT
1365 proc osutils:compilable {thePlatform} {
1366 if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } { return [list .c .cxx .cpp .mm] }
1367 return [list .c .cxx .cpp]
1370 # List extensions of header file in OCCT
1371 proc osutils:fileExtensionsHeaders {thePlatform} {
1372 if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } { return [list .h .hxx .hpp .lxx .pxx .gxx ] }
1373 return [list .h .hxx .hpp .lxx .pxx .gxx .mm ]
1376 # List extensions of Qt resource file in OCCT
1377 proc osutils:fileExtensionsResources {thePlatform} {
1381 proc osutils:commonUsedTK { theToolKit theSrcDir theSourceDirOther} {
1382 set anUsedToolKits [list]
1383 set aDepToolkits [LibToLink $theToolKit $theSrcDir $theSourceDirOther]
1384 foreach tkx $aDepToolkits {
1385 if {[_get_type $tkx] == "t"} {
1386 lappend anUsedToolKits "${tkx}"
1389 return $anUsedToolKits
1392 # Return the list of name *CSF_ in a EXTERNLIB description of a toolkit
1393 proc osutils:tk:csfInExternlib { EXTERNLIB } {
1394 set l [wokUtils:FILES:FileToList $EXTERNLIB]
1397 if [regexp -- {(CSF_[^ ]*)} $str csf] {
1404 # Collect dependencies map depending on target OS (libraries for CSF_ codenames used in EXTERNLIB) .
1405 # @param theOS - target OS
1406 # @param theCsfLibsMap - libraries map
1407 # @param theCsfFrmsMap - frameworks map, OS X specific
1408 proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap theRelease} {
1409 upvar $theCsfLibsMap aLibsMap
1410 upvar $theCsfFrmsMap aFrmsMap
1415 if { "$::HAVE_FREETYPE" == "true" } {
1416 set aLibsMap(CSF_FREETYPE) "freetype"
1418 set aLibsMap(CSF_TclLibs) "tcl8.6"
1419 if { "$::HAVE_TK" == "true" } {
1420 set aLibsMap(CSF_TclTkLibs) "tk8.6"
1422 if { "$::HAVE_FREEIMAGE" == "true" } {
1423 if { "$theOS" == "wnt" } {
1424 set aLibsMap(CSF_FreeImagePlus) "FreeImage"
1426 set aLibsMap(CSF_FreeImagePlus) "freeimage"
1428 } elseif { "$theOS" == "wnt" } {
1429 set aLibsMap(CSF_FreeImagePlus) "windowscodecs"
1431 if { "$::HAVE_FFMPEG" == "true" } {
1432 set aLibsMap(CSF_FFmpeg) "avcodec avformat swscale avutil"
1434 if { "$::HAVE_TBB" == "true" } {
1435 set aLibsMap(CSF_TBB) "tbb tbbmalloc"
1437 if { "$::HAVE_VTK" == "true" } {
1438 if { "$theOS" == "wnt" } {
1439 set aLibsMap(CSF_VTK) [osutils:vtkCsf "wnt"]
1441 set aLibsMap(CSF_VTK) [osutils:vtkCsf "unix"]
1444 if { "$::HAVE_ZLIB" == "true" } {
1445 set aLibsMap(CSF_ZLIB) "z"
1447 if { "$::HAVE_LIBLZMA" == "true" } {
1448 set aLibsMap(CSF_LIBLZMA) "liblzma"
1450 if { "$::HAVE_DRACO" == "true" } {
1451 set aLibsMap(CSF_Draco) "draco"
1453 if { "$::HAVE_OPENVR" == "true" } {
1454 set aLibsMap(CSF_OpenVR) "openvr_api"
1456 if { "$::HAVE_E57" == "true" && "$theOS" != "wnt" } {
1457 # exclude wnt, as there are different pragma lib depending on debug/release
1458 set aLibsMap(CSF_E57) "E57RefImpl"
1459 set aLibsMap(CSF_xerces) "xerces-c"
1462 if { "$theOS" == "wnt" } {
1464 set aLibsMap(CSF_kernel32) "kernel32"
1465 set aLibsMap(CSF_advapi32) "advapi32"
1466 set aLibsMap(CSF_gdi32) "gdi32"
1467 set aLibsMap(CSF_user32) "user32 comdlg32"
1468 set aLibsMap(CSF_shell32) "shell32"
1469 set aLibsMap(CSF_opengl32) "opengl32"
1470 set aLibsMap(CSF_wsock32) "wsock32"
1471 set aLibsMap(CSF_netapi32) "netapi32"
1472 set aLibsMap(CSF_winmm) "winmm"
1473 set aLibsMap(CSF_OpenGlLibs) "opengl32"
1474 set aLibsMap(CSF_OpenGlesLibs) "libEGL libGLESv2"
1475 set aLibsMap(CSF_psapi) "Psapi"
1476 set aLibsMap(CSF_d3d9) "d3d9"
1478 # the naming is different on Windows
1479 set aLibsMap(CSF_TclLibs) "tcl86"
1480 if { "$::HAVE_TK" == "true" } {
1481 set aLibsMap(CSF_TclTkLibs) "tk86"
1483 if { "$theRelease" == "true" } {
1484 set aLibsMap(CSF_QT) "Qt5Gui Qt5Widgets Qt5Xml Qt5Core"
1486 set aLibsMap(CSF_QT) "Qt5Guid Qt5Widgetsd Qt5Xmld Qt5Cored"
1489 # tbb headers define different pragma lib depending on debug/release
1490 set aLibsMap(CSF_TBB) ""
1492 if { "$::HAVE_ZLIB" == "true" } {
1493 set aLibsMap(CSF_ZLIB) "zlib"
1496 set aLibsMap(CSF_dl) "dl"
1497 if { "$::HAVE_XLIB" == "true" } {
1498 set aLibsMap(CSF_OpenGlLibs) "GL"
1500 set aLibsMap(CSF_OpenGlLibs) "GL EGL"
1502 set aLibsMap(CSF_OpenGlesLibs) "EGL GLESv2"
1503 if { "$theOS" == "mac" || "$theOS" == "ios" } {
1504 set aLibsMap(CSF_objc) "objc"
1505 set aLibsMap(CSF_OpenGlLibs) ""
1506 set aLibsMap(CSF_OpenGlesLibs) ""
1507 set aFrmsMap(CSF_OpenGlLibs) "OpenGL"
1508 set aFrmsMap(CSF_OpenGlesLibs) "OpenGLES"
1509 if { "$theOS" == "ios" } {
1510 set aFrmsMap(CSF_Appkit) "UIKit"
1512 set aFrmsMap(CSF_Appkit) "AppKit"
1514 set aFrmsMap(CSF_IOKit) "IOKit"
1515 set aLibsMap(CSF_TclLibs) ""
1516 set aLibsMap(CSF_TclTkLibs) ""
1517 set aFrmsMap(CSF_TclLibs) "Tcl"
1518 if { "$::HAVE_TK" == "true" } {
1519 set aFrmsMap(CSF_TclTkLibs) "Tk"
1521 set aLibsMap(CSF_QT) "QtCore QtGui"
1522 } elseif { "$theOS" == "android" } {
1523 set aLibsMap(CSF_androidlog) "log"
1525 if { "$::HAVE_FREETYPE" == "true" } {
1526 set aLibsMap(CSF_fontconfig) "fontconfig"
1528 if { "$theOS" == "qnx" } {
1529 # CSF_ThreadLibs - pthread API is part of libc on QNX
1531 set aLibsMap(CSF_ThreadLibs) "pthread rt"
1532 if { "$::HAVE_TK" == "true" } {
1533 set aLibsMap(CSF_TclTkLibs) "tk8.6"
1535 if { "$::HAVE_XLIB" == "true" } {
1536 set aLibsMap(CSF_XwLibs) "X11"
1543 # Returns string of library dependencies for generation of Visual Studio project or make lists.
1544 proc osutils:vtkCsf {{theOS ""}} {
1547 set aPathSplitter ":"
1548 if {"$theOS" == "wnt"} {
1549 set aPathSplitter ";"
1552 set anOptIncs [split $::env(CSF_OPT_INC) "$aPathSplitter"]
1553 foreach anIncItem $anOptIncs {
1554 if {[regexp -- "vtk-(.*)$" [file tail $anIncItem] dummy aFoundVtkVer]} {
1555 set aVtkVer $aFoundVtkVer
1559 set aLibArray [list vtkCommonCore vtkCommonDataModel vtkCommonExecutionModel vtkCommonMath vtkCommonTransforms vtkRenderingCore \
1560 vtkRenderingOpenGL vtkFiltersGeneral vtkIOCore vtkIOImage vtkImagingCore vtkInteractionStyle]
1562 # Additional suffices for the libraries
1564 foreach anItem $aLibArray {
1565 lset aLibArray $anIdx $anItem-$aVtkVer
1569 return [join $aLibArray " "]
1572 # @param theLibsList - dependencies (libraries list)
1573 # @param theFrameworks - dependencies (frameworks list, OS X specific)
1574 proc osutils:usedOsLibs { theToolKit theOS theLibsList theFrameworks theSrcDir { theRelease true } } {
1576 upvar $theLibsList aLibsList
1577 upvar $theFrameworks aFrameworks
1578 set aLibsList [list]
1579 set aFrameworks [list]
1581 osutils:csfList $theOS aLibsMap aFrmsMap $theRelease
1583 foreach aCsfElem [osutils:tk:csfInExternlib "$path/$theSrcDir/${theToolKit}/EXTERNLIB"] {
1584 if [info exists aLibsMap($aCsfElem)] {
1585 foreach aLib [split "$aLibsMap($aCsfElem)"] {
1586 if { [lsearch $aLibsList $aLib] == "-1" } {
1587 lappend aLibsList $aLib
1591 if [info exists aFrmsMap($aCsfElem)] {
1592 foreach aFrm [split "$aFrmsMap($aCsfElem)"] {
1593 if { [lsearch $aFrameworks $aFrm] == "-1" } {
1594 lappend aFrameworks $aFrm
1601 # Returns liste of UD in a toolkit. tkloc is a full path wok.
1602 proc osutils:tk:units { tkloc theSrcDir } {
1605 set PACKAGES "$path/$theSrcDir/$tkloc/PACKAGES"
1606 foreach u [wokUtils:FILES:FileToList $PACKAGES] {
1607 if {[file isdirectory "$path/$theSrcDir/$u"]} {
1612 ;#puts stderr "Warning. No devunit included in $tkloc"
1617 # remove from listloc OpenCascade units indesirables on NT
1618 proc osutils:juststation {goaway listloc} {
1621 foreach u $listloc {
1622 if {([file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 )
1623 || (![file isdirectory "$path/src/$u"] && [lsearch $goaway $u] == -1 ) } {
1630 # intersect3 - perform the intersecting of two lists, returning a list containing three lists.
1631 # The first list is everything in the first list that wasn't in the second,
1632 # the second list contains the intersection of the two lists, the third list contains everything
1633 # in the second list that wasn't in the first.
1634 proc osutils:intersect3 {list1 list2} {
1635 set la1(0) {} ; unset la1(0)
1636 set lai(0) {} ; unset lai(0)
1637 set la2(0) {} ; unset la2(0)
1644 foreach elem [concat $list1 $list2] {
1645 if {[info exists la1($elem)] && [info exists la2($elem)]} {
1651 list [lsort [array names la1]] [lsort [array names lai]] [lsort [array names la2]]
1654 # Prepare relative path
1655 proc relativePath {thePathFrom thePathTo} {
1656 if { [file isdirectory "$thePathFrom"] == 0 } {
1660 set aPathFrom [file normalize "$thePathFrom"]
1661 set aPathTo [file normalize "$thePathTo"]
1663 set aCutedPathFrom "${aPathFrom}/dummy"
1664 set aRelatedDeepPath ""
1666 while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
1667 set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
1668 # does aPathTo contain aCutedPathFrom?
1669 regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
1670 if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
1671 if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
1672 set aPathTo ".${aPathTo}"
1673 } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
1674 set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
1676 regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
1677 regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
1678 return $aPathToAfterCut
1680 set aRelatedDeepPath "$aRelatedDeepPath../"
1687 proc wokUtils:EASY:bs1 { s } {
1688 regsub -all {/} $s {\\} r
1692 # Returns for a full path the liste of n last directory part
1694 # n = 2 => dir/file.c
1695 # n = 3 => sdir/dir/file.c
1697 proc wokUtils:FILES:wtail { f n } {
1698 set ll [expr [llength [set lif [file split $f]]] -$n]
1699 return [join [lrange $lif $ll end] /]
1702 # Generate entry for one source file in Visual Studio 10 project file
1703 proc osutils:vcxproj:cxxfile { theFile theParams theSrcFileLevel } {
1704 if { $theParams == "" } {
1705 return " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile $theSrcFileLevel]]\" />\n"
1708 set aParams [string trim ${theParams}]
1709 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
1710 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1711 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1712 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1713 append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
1714 append text " </ClCompile>\n"
1718 # Generate entry for one header file in Visual Studio 10 project file
1719 proc osutils:vcxproj:hxxfile { theFile } { return " <ClInclude Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\" />\n" }
1721 # Generate Visual Studio 2010 project filters file
1722 proc osutils:vcxproj:filters { dir proj theCxxFilesMap theHxxFilesMap } {
1723 upvar $theCxxFilesMap aCxxFilesMap
1724 upvar $theHxxFilesMap aHxxFilesMap
1727 append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1728 append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
1730 # list of "filters" (units)
1731 append text " <ItemGroup>\n"
1732 append text " <Filter Include=\"Source files\">\n"
1733 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1734 append text " </Filter>\n"
1735 append text " <Filter Include=\"Header files\">\n"
1736 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1737 append text " </Filter>\n"
1738 foreach unit $aCxxFilesMap(units) {
1739 append text " <Filter Include=\"Source files\\${unit}\">\n"
1740 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1741 append text " </Filter>\n"
1743 foreach unit $aHxxFilesMap(units) {
1744 append text " <Filter Include=\"Header files\\${unit}\">\n"
1745 append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
1746 append text " </Filter>\n"
1748 append text " </ItemGroup>\n"
1751 append text " <ItemGroup>\n"
1752 foreach unit $aCxxFilesMap(units) {
1753 foreach file $aCxxFilesMap($unit) {
1754 append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1755 append text " <Filter>Source files\\${unit}</Filter>\n"
1756 append text " </ClCompile>\n"
1759 append text " </ItemGroup>\n"
1762 append text " <ItemGroup>\n"
1763 foreach unit $aHxxFilesMap(units) {
1764 foreach file $aHxxFilesMap($unit) {
1765 append text " <ClInclude Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
1766 append text " <Filter>Header files\\${unit}</Filter>\n"
1767 append text " </ClInclude>\n"
1770 append text " </ItemGroup>\n"
1772 append text " <ItemGroup>\n"
1773 append text " <ResourceCompile Include=\"${proj}.rc\" />\n"
1774 append text " </ItemGroup>\n"
1777 append text "</Project>"
1780 set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
1781 fconfigure $fp -translation crlf
1785 return ${proj}.vcxproj.filters
1788 # Generate RC file content for ToolKit from template
1789 proc osutils:readtemplate:rc {theOutDir theToolKit} {
1790 set aLoc "$::THE_CASROOT/adm/templates/template_dll.rc"
1791 set aBody [wokUtils:FILES:FileToString $aLoc]
1792 regsub -all -- {__TKNAM__} $aBody $theToolKit aBody
1794 set aFile [open "${theOutDir}/${theToolKit}.rc" "w"]
1795 fconfigure $aFile -translation lf
1798 return "${theOutDir}/${theToolKit}.rc"
1801 # Generate Visual Studio project file for ToolKit
1802 proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap theSrcDir theSourceDirOther } {
1805 set aHasQtDep "false"
1807 foreach aCsfElem [osutils:tk:csfInExternlib "$path/$theSrcDir/${theToolKit}/EXTERNLIB"] {
1808 if { "$aCsfElem" == "CSF_QT" } {
1809 set aHasQtDep "true"
1810 } elseif { "$aCsfElem" == "CSF_OpenGlLibs" } {
1811 set aTkDefines "$aTkDefines;HAVE_OPENGL"
1812 } elseif { "$aCsfElem" == "CSF_OpenGlesLibs" } {
1813 set aTkDefines "$aTkDefines;HAVE_GLES2"
1816 set theProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 0]
1818 set l_compilable [osutils:compilable wnt]
1819 regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
1821 upvar $theGuidsMap aGuidsMap
1822 if { ! [info exists aGuidsMap($theToolKit)] } {
1823 set aGuidsMap($theToolKit) [OS:genGUID]
1825 regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
1827 set theProjTmpl [osutils:uwp:proj $isUWP ${theProjTmpl}]
1829 set aUsedLibs [list]
1832 lappend aUsedLibs "WindowsApp.lib"
1835 foreach tkx [osutils:commonUsedTK $theToolKit $theSrcDir $theSourceDirOther] {
1836 lappend aUsedLibs "${tkx}.lib"
1839 set anOsReleaseLibs {}
1840 set anOsDebugLibs {}
1841 osutils:usedOsLibs $theToolKit "wnt" anOsReleaseLibs aFrameworks $theSrcDir true
1842 osutils:usedOsLibs $theToolKit "wnt" anOsDebugLibs aFrameworks $theSrcDir false
1844 # correct names of referred third-party libraries that are named with suffix
1845 # depending on VC version
1846 regsub -all -- {__TKDEP__} $theProjTmpl [osutils:depLibraries $aUsedLibs $anOsReleaseLibs $theVcVer] theProjTmpl
1847 regsub -all -- {__TKDEP_DEBUG__} $theProjTmpl [osutils:depLibraries $aUsedLibs $anOsDebugLibs $theVcVer] theProjTmpl
1848 regsub -all -- {__TKDEFINES__} $theProjTmpl $aTkDefines theProjTmpl
1850 set anIncPaths "..\\..\\..\\inc"
1851 set aFilesSection ""
1852 set aVcFilesCxx(units) ""
1853 set aVcFilesHxx(units) ""
1854 set listloc [osutils:tk:units $theToolKit $theSrcDir]
1855 if [array exists written] { unset written }
1856 #puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
1857 #puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
1858 #puts "\t1 [wokparam -v %CMPLRS_C_Options [w_info -f]] father"
1859 #puts "\t2 [wokparam -v %CMPLRS_C_Options] branch"
1860 set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
1861 set fxloparamfc [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
1863 foreach fxlo $listloc {
1865 set aSrcFiles [osutils:tk:cxxfiles $xlo wnt $theSrcDir]
1866 set aHxxFiles [osutils:tk:hxxfiles $xlo wnt $theSrcDir]
1868 # prepare Qt moc files, appears only in Inspector - directory tools
1869 set aGeneratedFiles {}
1870 if { "$aHasQtDep" == "true" } {
1871 set aMocResFiles [osutils:tk:mocfiles $aHxxFiles $theOutDir]
1872 set aGeneratedFiles [osutils:tk:execfiles $aMocResFiles $theOutDir moc${::SYS_EXE_SUFFIX} moc cpp]
1874 set aQrcResFiles [osutils:tk:qrcfiles $xlo wnt $theSrcDir]
1875 set aQrcFiles [osutils:tk:execfiles $aQrcResFiles $theOutDir rcc${::SYS_EXE_SUFFIX} rcc cpp]
1876 foreach resFile $aQrcFiles {
1877 lappend aGeneratedFiles $resFile
1881 set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
1882 if {$fxlo_cmplrs_options_cxx == ""} {
1883 set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
1885 set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c $fxlo]
1886 if {$fxlo_cmplrs_options_c == ""} {
1887 set fxlo_cmplrs_options_c [_get_options wnt cmplrs_c b]
1889 set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx b] $fxlo_cmplrs_options_cxx] 2]"
1890 set fxloparam "$fxloparam [lindex [osutils:intersect3 [_get_options wnt cmplrs_c b] $fxlo_cmplrs_options_c] 2]"
1891 #puts "\t3 [wokparam -v %CMPLRS_CXX_Options] branch CXX "
1892 #puts "\t4 [wokparam -v %CMPLRS_CXX_Options $fxlo] $fxlo CXX"
1893 #puts "\t5 [wokparam -v %CMPLRS_C_Options] branch C"
1894 #puts "\t6 [wokparam -v %CMPLRS_C_Options $fxlo] $fxlo C"
1896 foreach partopt $fxloparam {
1897 if {[string first "-I" $partopt] == "0"} {
1898 # this is an additional includes search path
1901 set needparam "$needparam $partopt"
1904 # Format of projects in vc10+ is different from vc7-9
1905 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1906 foreach aSrcFile [lsort $aSrcFiles] {
1907 if { ![info exists written([file tail $aSrcFile])] } {
1908 set written([file tail $aSrcFile]) 1
1909 append aFilesSection [osutils:vcxproj:cxxfile $aSrcFile $needparam 3]
1911 puts "Warning : in vcproj more than one occurrences for [file tail $aSrcFile]"
1913 if { ! [info exists aVcFilesCxx($xlo)] } { lappend aVcFilesCxx(units) $xlo }
1914 lappend aVcFilesCxx($xlo) $aSrcFile
1916 foreach aHxxFile [lsort $aHxxFiles] {
1917 if { ![info exists written([file tail $aHxxFile])] } {
1918 set written([file tail $aHxxFile]) 1
1919 append aFilesSection [osutils:vcxproj:hxxfile $aHxxFile]
1921 puts "Warning : in vcproj more than one occurrences for [file tail $aHxxFile]"
1923 if { ! [info exists aVcFilesHxx($xlo)] } { lappend aVcFilesHxx(units) $xlo }
1924 lappend aVcFilesHxx($xlo) $aHxxFile
1926 foreach aGenFile [lsort $aGeneratedFiles] {
1927 if { ![info exists written([file tail $aGenFile])] } {
1928 set written([file tail $aGenFile]) 1
1929 append aFilesSection [osutils:vcxproj:cxxfile $aGenFile $needparam 5]
1931 puts "Warning : in vcproj more than one occurrences for [file tail $aGenFile]"
1933 if { ! [info exists aVcFilesCxx($xlo)] } { lappend aVcFilesCxx(units) $xlo }
1934 lappend aVcFilesCxx($xlo) $aGenFile
1937 append aFilesSection "\t\t\t<Filter\n"
1938 append aFilesSection "\t\t\t\tName=\"${xlo}\"\n"
1939 append aFilesSection "\t\t\t\t>\n"
1940 foreach aSrcFile [lsort $aSrcFiles] {
1941 if { ![info exists written([file tail $aSrcFile])] } {
1942 set written([file tail $aSrcFile]) 1
1943 append aFilesSection [osutils:vcproj:file $theVcVer $aSrcFile $needparam]
1945 puts "Warning : in vcproj more than one occurrences for [file tail $aSrcFile]"
1948 append aFilesSection "\t\t\t</Filter>\n"
1952 regsub -all -- {__TKINC__} $theProjTmpl $anIncPaths theProjTmpl
1953 regsub -all -- {__FILES__} $theProjTmpl $aFilesSection theProjTmpl
1956 set aFile [open [set aVcFiles [file join $theOutDir ${theToolKit}.[osutils:vcproj:ext $theVcVer]]] w]
1957 fconfigure $aFile -translation crlf
1958 puts $aFile $theProjTmpl
1961 # write filters file for vc10+
1962 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1963 lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesCxx aVcFilesHxx]
1966 # write resource file
1967 lappend aVcFiles [osutils:readtemplate:rc $theOutDir $theToolKit]
1972 # Appends OS libraries into the list of used libraries.
1973 # Corrects list of referred third-party libraries that are named with suffix
1974 # depending on VC version
1975 # Unites list of used libraries into a variable with separator for VStudio older than vc9
1976 # @param theUsedLibs List of libraries, to be changed
1977 # @param theOsLibs List of Os library names, before using an extension should be added
1978 # @param theVcVer version of VStudio
1980 proc osutils:depLibraries { theUsedLibs theOsLibs theVcVer } {
1981 foreach aLibIter $theOsLibs {
1982 lappend theUsedLibs "${aLibIter}.${::SYS_LIB_SUFFIX}"
1985 # correct names of referred third-party libraries that are named with suffix
1986 # depending on VC version
1987 set aVCRTVer [string range $theVcVer 0 3]
1988 regsub -all -- {vc[0-9]+} $theUsedLibs $aVCRTVer theUsedLibs
1990 # and put this list to project file
1991 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
1992 set theUsedLibs [join $theUsedLibs {;}]
1998 # for a unit returns a map containing all its file in the current
2000 # local = 1 only local files
2001 proc osutils:tk:loadunit { loc map theSrcDir} {
2004 catch { unset TLOC }
2005 set lfiles [_get_used_files $loc $theSrcDir]
2010 if [info exists TLOC($t)] {
2021 # Returns the list of all files name in a toolkit within specified list of file extensions.
2022 proc osutils:tk:files { tkloc theExtensions theSrcDir } {
2023 set Tfiles(source,nocdlpack) {source pubinclude}
2024 set Tfiles(source,toolkit) {}
2025 set Tfiles(source,executable) {source pubinclude}
2026 set listloc [concat [osutils:tk:units $tkloc $theSrcDir] $tkloc ]
2027 #puts " listloc = $listloc"
2029 set resultloc $listloc
2031 foreach loc $resultloc {
2032 set utyp [_get_type $loc]
2033 #puts "\"$utyp\" \"$loc\""
2035 "t" { set utyp "toolkit" }
2036 "n" { set utyp "nocdlpack" }
2037 "x" { set utyp "executable" }
2038 default { error "Error: Cannot determine type of unit $loc, check adm/UDLIST!" }
2040 if [array exists map] { unset map }
2041 osutils:tk:loadunit $loc map $theSrcDir
2042 #puts " loc = $loc === > [array names map]"
2043 set LType $Tfiles(source,${utyp})
2044 foreach typ [array names map] {
2045 if { [lsearch $LType $typ] == -1 } {
2049 foreach type [array names map] {
2051 foreach f $map($type) {
2053 if { [lsearch $theExtensions [file extension $f]] != -1 } {
2062 # Returns the list of all compilable files name in a toolkit.
2063 proc osutils:tk:cxxfiles { tkloc thePlatform theSrcDir } { return [osutils:tk:files $tkloc [osutils:compilable $thePlatform] $theSrcDir] }
2065 # Returns the list of all header files name in a toolkit.
2066 proc osutils:tk:hxxfiles { tkloc thePlatform theSrcDir } { return [osutils:tk:files $tkloc [osutils:fileExtensionsHeaders $thePlatform] $theSrcDir] }
2068 # Returns the list of all resource (qrc) files name in a toolkit.
2069 proc osutils:tk:qrcfiles { tkloc thePlatform theSourceDir } { return [osutils:tk:files $tkloc [osutils:fileExtensionsResources $thePlatform] $theSourceDir] }
2071 # Returns the list of all header files name in a toolkit.
2072 proc osutils:tk:mocfiles { HxxFiles theOutDir } {
2074 foreach file $HxxFiles {
2075 # processing only files where Q_OBJECT exists
2076 set fd [open "$file" rb]
2077 set FILES [split [read $fd] "\n"]
2080 set isQObject [expr [regexp "Q_OBJECT" $FILES]]
2081 if { ! $isQObject } {
2089 # Returns the list of all header files name in a toolkit.
2090 proc osutils:tk:execfiles { theFiles theOutDir theCommand thePrefix theExtension} {
2092 set anOutDir $theOutDir/$thePrefix
2093 file mkdir $anOutDir
2095 foreach file $theFiles {
2096 set aResourceName [file tail $file]
2097 set anOutFile $anOutDir/${thePrefix}_[file rootname $aResourceName].$theExtension
2099 exec $theCommand $file -o $anOutFile
2100 lappend lret $anOutFile
2105 # Generate Visual Studio project file for executable
2106 proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap theSrcDir theSourceDirOther } {
2108 foreach f [osutils:tk:cxxfiles $theToolKit wnt $theSrcDir] {
2109 set aProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 1]
2111 set aProjName [file rootname [file tail $f]]
2112 set l_compilable [osutils:compilable wnt]
2113 regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
2115 upvar $theGuidsMap aGuidsMap
2116 if { ! [info exists aGuidsMap($aProjName)] } {
2117 set aGuidsMap($aProjName) [OS:genGUID]
2119 regsub -all -- {__PROJECT_GUID__} $aProjTmpl $aGuidsMap($aProjName) aProjTmpl
2121 set aUsedLibs [list]
2122 foreach tkx [osutils:commonUsedTK $theToolKit $theSrcDir $theSourceDirOther] {
2123 lappend aUsedLibs "${tkx}.lib"
2126 set anOsReleaseLibs {}
2127 set anOsDebugLibs {}
2128 osutils:usedOsLibs $theToolKit "wnt" anOsReleaseLibs aFrameworks $theSrcDir true
2129 osutils:usedOsLibs $theToolKit "wnt" anOsDebugLibs aFrameworks $theSrcDir false
2131 set aVCRTVer [string range $theVcVer 0 3]
2132 regsub -all -- {__TKDEP__} $aProjTmpl [osutils:depLibraries $aUsedLibs $anOsReleaseLibs $theVcVer] aProjTmpl
2133 regsub -all -- {__TKDEP_DEBUG__} $aProjTmpl [osutils:depLibraries $aUsedLibs $anOsDebugLibs $theVcVer] aProjTmpl
2134 regsub -all -- {__TKDEFINES__} $aProjTmpl "" aProjTmpl
2136 set aFilesSection ""
2137 set aVcFilesCxx(units) ""
2138 set aVcFilesHxx(units) ""
2140 if { ![info exists written([file tail $f])] } {
2141 set written([file tail $f]) 1
2143 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
2144 append aFilesSection [osutils:vcxproj:cxxfile $f "" 3]
2145 if { ! [info exists aVcFilesCxx($theToolKit)] } { lappend aVcFilesCxx(units) $theToolKit }
2146 lappend aVcFilesCxx($theToolKit) $f
2148 append aFilesSection "\t\t\t<Filter\n"
2149 append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
2150 append aFilesSection "\t\t\t\t>\n"
2151 append aFilesSection [osutils:vcproj:file $theVcVer $f ""]
2152 append aFilesSection "\t\t\t</Filter>"
2155 puts "Warning : in vcproj there are more than one occurrences for [file tail $f]"
2157 #puts "$aProjTmpl $aFilesSection"
2158 set anIncPaths "..\\..\\..\\inc"
2159 regsub -all -- {__TKINC__} $aProjTmpl $anIncPaths aProjTmpl
2160 regsub -all -- {__FILES__} $aProjTmpl $aFilesSection aProjTmpl
2161 regsub -all -- {__CONF__} $aProjTmpl Application aProjTmpl
2163 regsub -all -- {__XQTEXT__} $aProjTmpl "exe" aProjTmpl
2165 set aFile [open [set aVcFilePath [file join $theOutDir ${aProjName}.[osutils:vcproj:ext $theVcVer]]] w]
2166 fconfigure $aFile -translation crlf
2167 puts $aFile $aProjTmpl
2170 set aCommonSettingsFile "$aVcFilePath.user"
2171 lappend aVcFiles $aVcFilePath
2173 # write filters file for vc10
2174 if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
2175 lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesCxx aVcFilesHxx]
2178 # write resource file
2179 lappend aVcFiles [osutils:readtemplate:rc $theOutDir $aProjName]
2181 set aCommonSettingsFileTmpl ""
2182 if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
2184 } elseif { "$theVcVer" == "vc9" } {
2185 set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcproj.user.vc9x"]
2187 set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcxproj.user.vc10x"]
2189 if { "$aCommonSettingsFileTmpl" != "" } {
2190 regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $aVCRTVer aCommonSettingsFileTmpl
2192 set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
2193 fconfigure $aFile -translation crlf
2194 puts $aFile $aCommonSettingsFileTmpl
2197 lappend aVcFiles "$aCommonSettingsFile"
2203 # Generate entry for one source file in Visual Studio 7 - 9 project file
2204 proc osutils:vcproj:file { theVcVer theFile theOptions } {
2205 append aText "\t\t\t\t<File\n"
2206 append aText "\t\t\t\t\tRelativePath=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
2207 if { $theOptions == "" } {
2208 append aText "\t\t\t\t</File>\n"
2212 append aText "\t\t\t\t\t<FileConfiguration\n"
2213 append aText "\t\t\t\t\t\tName=\"Release\|Win32\">\n"
2214 append aText "\t\t\t\t\t\t<Tool\n"
2215 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2216 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2217 foreach aParam $theOptions {
2218 append aText "$aParam "
2221 append aText "\t\t\t\t\t\t/>\n"
2222 append aText "\t\t\t\t\t</FileConfiguration>\n"
2224 append aText "\t\t\t\t\t<FileConfiguration\n"
2225 append aText "\t\t\t\t\t\tName=\"Debug\|Win32\">\n"
2226 append aText "\t\t\t\t\t\t<Tool\n"
2227 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2228 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2229 foreach aParam $theOptions {
2230 append aText "$aParam "
2233 append aText "\t\t\t\t\t\t/>\n"
2234 append aText "\t\t\t\t\t</FileConfiguration>\n"
2235 if { "$theVcVer" == "vc7" } {
2236 append aText "\t\t\t\t</File>\n"
2240 append aText "\t\t\t\t\t<FileConfiguration\n"
2241 append aText "\t\t\t\t\t\tName=\"Release\|x64\">\n"
2242 append aText "\t\t\t\t\t\t<Tool\n"
2243 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2244 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2245 foreach aParam $theOptions {
2246 append aText "$aParam "
2249 append aText "\t\t\t\t\t\t/>\n"
2250 append aText "\t\t\t\t\t</FileConfiguration>\n"
2252 append aText "\t\t\t\t\t<FileConfiguration\n"
2253 append aText "\t\t\t\t\t\tName=\"Debug\|x64\">\n"
2254 append aText "\t\t\t\t\t\t<Tool\n"
2255 append aText "\t\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
2256 append aText "\t\t\t\t\t\t\tAdditionalOptions=\""
2257 foreach aParam $theOptions {
2258 append aText "$aParam "
2261 append aText "\t\t\t\t\t\t/>\n"
2262 append aText "\t\t\t\t\t</FileConfiguration>\n"
2264 append aText "\t\t\t\t</File>\n"
2268 proc wokUtils:FILES:mkdir { d } {
2270 regsub -all {\.[^.]*} $tcl_version "" major
2271 if { $major == 8 } {
2274 if ![file exists $d] {
2275 if { "[info command mkdir]" == "mkdir" } {
2278 puts stderr "wokUtils:FILES:mkdir : Error unable to find a mkdir command."
2282 if [file exists $d] {
2289 ####### CODEBLOCK ###################################################################
2290 # Function to generate Code Blocks workspace and project files
2291 proc OS:MKCBP { theOutDir theModules theAllSolution thePlatform theCmpl } {
2292 puts stderr "Generating project files for Code Blocks"
2294 # Generate projects for toolkits and separate workspace for each module
2295 foreach aModule $theModules {
2296 OS:cworkspace $aModule $aModule $theOutDir
2297 OS:cbp $theCmpl $aModule $theOutDir $thePlatform
2300 # Generate single workspace "OCCT" containing projects from all modules
2301 if { "$theAllSolution" != "" } {
2302 OS:cworkspace $theAllSolution $theModules $theOutDir
2305 puts "The Code Blocks workspace and project files are stored in the $theOutDir directory"
2308 # Generate Code Blocks projects
2309 proc OS:cbp { theCmpl theModules theOutDir thePlatform } {
2310 set aProjectFiles {}
2311 foreach aModule $theModules {
2312 foreach aToolKit [${aModule}:toolkits] {
2313 lappend aProjectFiles [osutils:cbptk $theCmpl $theOutDir $aToolKit $thePlatform]
2315 foreach anExecutable [OS:executable ${aModule}] {
2316 lappend aProjectFiles [osutils:cbpx $theCmpl $theOutDir $anExecutable $thePlatform]
2319 return $aProjectFiles
2322 # Generate Code::Blocks project file for ToolKit
2323 proc osutils:cbptk { theCmpl theOutDir theToolKit thePlatform} {
2324 set aUsedLibs [list]
2325 set aFrameworks [list]
2326 set anIncPaths [list]
2327 set aTKDefines [list]
2328 set aTKSrcFiles [list]
2330 # collect list of referred libraries to link with
2331 osutils:usedOsLibs $theToolKit $thePlatform aUsedLibs aFrameworks "src"
2332 set aDepToolkits [wokUtils:LIST:Purge [osutils:tk:close $theToolKit "src" ""]]
2333 foreach tkx $aDepToolkits {
2334 lappend aUsedLibs "${tkx}"
2337 lappend anIncPaths "../../../inc"
2338 set listloc [osutils:tk:units $theToolKit "src"]
2340 if { [llength $listloc] == 0 } {
2341 set listloc $theToolKit
2344 if [array exists written] { unset written }
2345 foreach fxlo $listloc {
2347 set aSrcFiles [osutils:tk:cxxfiles $xlo $thePlatform "src"]
2348 foreach aSrcFile [lsort $aSrcFiles] {
2349 if { ![info exists written([file tail $aSrcFile])] } {
2350 set written([file tail $aSrcFile]) 1
2351 lappend aTKSrcFiles "../../../[wokUtils:FILES:wtail $aSrcFile 3]"
2353 puts "Warning : more than one occurrences for [file tail $aSrcFile]"
2357 # macros for correct DLL exports
2358 # if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
2359 # lappend aTKDefines "__${xlo}_DLL"
2363 return [osutils:cbp $theCmpl $theOutDir $theToolKit $thePlatform $aTKSrcFiles $aUsedLibs $aFrameworks $anIncPaths $aTKDefines]
2366 # Generates Code Blocks workspace.
2367 proc OS:cworkspace { theSolName theModules theOutDir } {
2369 set aWsFilePath "${theOutDir}/${theSolName}.workspace"
2370 set aFile [open $aWsFilePath "w"]
2372 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2373 puts $aFile "<CodeBlocks_workspace_file>"
2374 puts $aFile "\t<Workspace title=\"${theSolName}\">"
2376 # collect list of projects to be created
2377 foreach aModule $theModules {
2379 foreach aToolKit [osutils:tk:sort [${aModule}:toolkits] "src" ""] {
2380 set aDependencies [LibToLink $aToolKit "src" ""]
2381 if { [llength $aDependencies] == 0 } {
2382 puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" />"
2384 puts $aFile "\t\t<Project filename=\"${aToolKit}.cbp\" >"
2385 foreach aDepTk $aDependencies {
2386 puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2388 puts $aFile "\t\t</Project>"
2392 # executables, assume one project per cxx file...
2393 foreach aUnit [OS:executable ${aModule}] {
2395 set src_files [_get_used_files $aUnit "src" false]
2397 foreach s $src_files {
2398 regexp {source ([^\s]+)} $s dummy name
2399 lappend aSrcFiles $name
2401 foreach aSrcFile $aSrcFiles {
2402 set aFileExtension [file extension $aSrcFile]
2403 if { $aFileExtension == ".cxx" } {
2404 set aPrjName [file rootname $aSrcFile]
2405 set aDependencies [list]
2406 if {[file isdirectory $path/src/$aUnitLoc]} {
2407 set aDependencies [LibToLinkX $aUnitLoc [file rootname $aSrcFile] "src" ""]
2409 set anActiveState ""
2410 if { $isActiveSet == 0 } {
2411 set anActiveState " active=\"1\""
2414 if { [llength $aDependencies] == 0 } {
2415 puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}/>"
2417 puts $aFile "\t\t<Project filename=\"${aPrjName}.cbp\"${anActiveState}>"
2418 foreach aDepTk $aDependencies {
2419 puts $aFile "\t\t\t<Depends filename=\"${aDepTk}.cbp\" />"
2421 puts $aFile "\t\t</Project>"
2428 puts $aFile "\t</Workspace>"
2429 puts $aFile "</CodeBlocks_workspace_file>"
2435 # Generate Code::Blocks project file for Executable
2436 proc osutils:cbpx { theCmpl theOutDir theToolKit thePlatform } {
2438 set aWokArch "$::env(ARCH)"
2441 foreach aSrcFile [osutils:tk:cxxfiles $theToolKit $thePlatform "src"] {
2442 # collect list of referred libraries to link with
2443 set aUsedLibs [list]
2444 set aFrameworks [list]
2445 set anIncPaths [list]
2446 set aTKDefines [list]
2447 set aTKSrcFiles [list]
2448 set aProjName [file rootname [file tail $aSrcFile]]
2450 osutils:usedOsLibs $theToolKit $thePlatform aUsedLibs aFrameworks "src"
2452 set aDepToolkits [LibToLinkX $theToolKit $aProjName "src" ""]
2453 foreach tkx $aDepToolkits {
2454 if {[_get_type $tkx] == "t"} {
2455 lappend aUsedLibs "${tkx}"
2457 if {[lsearch [glob -tails -directory "$path/src" -types d *] $tkx] == "-1"} {
2458 lappend aUsedLibs "${tkx}"
2462 set WOKSteps_exec_link [_get_options lin WOKSteps_exec_link $theToolKit]
2463 if { [regexp {WOKStep_DLLink} $WOKSteps_exec_link] || [regexp {WOKStep_Libink} $WOKSteps_exec_link] } {
2464 set isExecutable "false"
2466 set isExecutable "true"
2469 if { ![info exists written([file tail $aSrcFile])] } {
2470 set written([file tail $aSrcFile]) 1
2471 lappend aTKSrcFiles "../../../[wokUtils:FILES:wtail $aSrcFile 3]"
2473 puts "Warning : in cbp there are more than one occurrences for [file tail $aSrcFile]"
2476 # macros for correct DLL exports
2477 # if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
2478 # lappend aTKDefines "__${theToolKit}_DLL"
2481 # common include paths
2482 lappend anIncPaths "../../../inc"
2484 lappend aCbpFiles [osutils:cbp $theCmpl $theOutDir $aProjName $thePlatform $aTKSrcFiles $aUsedLibs $aFrameworks $anIncPaths $aTKDefines $isExecutable]
2490 # This function intended to generate Code::Blocks project file
2491 # @param theCmpl - the compiler (gcc or msvc)
2492 # @param theOutDir - output directory to place project file
2493 # @param theProjName - project name
2494 # @param theSrcFiles - list of source files
2495 # @param theLibsList - dependencies (libraries list)
2496 # @param theFrameworks - dependencies (frameworks list, Mac OS X specific)
2497 # @param theIncPaths - header search paths
2498 # @param theDefines - compiler macro definitions
2499 # @param theIsExe - flag to indicate executable / library target
2500 proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
2501 set aWokArch "$::env(ARCH)"
2504 set aCmplFlags [list]
2505 set aCmplFlagsRelease [list]
2506 set aCmplFlagsDebug [list]
2507 set toPassArgsByFile 0
2508 set aLibPrefix "lib"
2509 set aPlatformAndCompiler "${thePlatform}/gcc"
2510 if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } {
2511 set aPlatformAndCompiler "${thePlatform}/clang"
2513 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" || "$thePlatform" == "qnx" } {
2514 set toPassArgsByFile 1
2516 if { "$theCmpl" == "msvc" } {
2517 set aCmplCbp "msvc8"
2521 if { "$theCmpl" == "msvc" } {
2522 set aCmplFlags "-arch:SSE2 -EHsc -W4 -MP"
2523 set aCmplFlagsRelease "-MD -O2"
2524 set aCmplFlagsDebug "-MDd -Od -Zi"
2525 lappend aCmplFlags "-D_CRT_SECURE_NO_WARNINGS"
2526 lappend aCmplFlags "-D_CRT_NONSTDC_NO_DEPRECATE"
2527 } elseif { "$theCmpl" == "gcc" } {
2528 if { "$thePlatform" != "qnx" } {
2529 set aCmplFlags "-mmmx -msse -msse2 -mfpmath=sse"
2531 set aCmplFlagsRelease "-O2"
2532 set aCmplFlagsDebug "-O0 -g"
2533 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
2534 lappend aCmplFlags "-std=gnu++0x"
2535 lappend aCmplFlags "-D_WIN32_WINNT=0x0501"
2537 lappend aCmplFlags "-std=c++0x"
2538 lappend aCmplFlags "-fPIC"
2539 lappend aCmplFlags "-DOCC_CONVERT_SIGNALS"
2541 lappend aCmplFlags "-Wall"
2542 lappend aCmplFlags "-Wextra"
2543 lappend aCmplFlags "-fexceptions"
2545 lappend aCmplFlagsRelease "-DNDEBUG"
2546 lappend aCmplFlagsRelease "-DNo_Exception"
2547 lappend aCmplFlagsDebug "-D_DEBUG"
2548 if { "$thePlatform" == "qnx" } {
2549 lappend aCmplFlags "-D_QNX_SOURCE"
2552 set aCbpFilePath "${theOutDir}/${theProjName}.cbp"
2553 set aLnkFileName "${theProjName}_obj.link"
2554 set aLnkDebFileName "${theProjName}_objd.link"
2555 set aLnkFilePath "${theOutDir}/${aLnkFileName}"
2556 set aLnkDebFilePath "${theOutDir}/${aLnkDebFileName}"
2557 set aFile [open $aCbpFilePath "w"]
2558 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"
2559 puts $aFile "<CodeBlocks_project_file>"
2560 puts $aFile "\t<FileVersion major=\"1\" minor=\"6\" />"
2561 puts $aFile "\t<Project>"
2562 puts $aFile "\t\t<Option title=\"$theProjName\" />"
2563 puts $aFile "\t\t<Option pch_mode=\"2\" />"
2564 puts $aFile "\t\t<Option compiler=\"$aCmplCbp\" />"
2565 puts $aFile "\t\t<Build>"
2567 # Release target configuration
2568 puts $aFile "\t\t\t<Target title=\"Release\">"
2569 if { "$theIsExe" == "true" } {
2570 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/bin/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
2571 puts $aFile "\t\t\t\t<Option type=\"1\" />"
2573 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
2574 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\" />"
2576 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/lib/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
2578 puts $aFile "\t\t\t\t<Option type=\"3\" />"
2580 puts $aFile "\t\t\t\t<Option object_output=\"../../../${aPlatformAndCompiler}/obj\" />"
2581 puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
2582 puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
2583 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
2584 puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2586 puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
2589 # compiler options per TARGET (including defines)
2590 puts $aFile "\t\t\t\t<Compiler>"
2591 foreach aFlagIter $aCmplFlagsRelease {
2592 puts $aFile "\t\t\t\t\t<Add option=\"$aFlagIter\" />"
2594 foreach aMacro $theDefines {
2595 puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2597 puts $aFile "\t\t\t\t</Compiler>"
2599 puts $aFile "\t\t\t\t<Linker>"
2600 if { $toPassArgsByFile == 1 } {
2601 puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkFileName\" />"
2603 puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aPlatformAndCompiler}/lib\" />"
2604 if { "$thePlatform" == "mac" } {
2605 if { [ lsearch $theLibsList X11 ] >= 0} {
2606 puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2609 puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
2610 if { "$thePlatform" == "lin" } {
2611 puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aPlatformAndCompiler}/lib\" />"
2613 puts $aFile "\t\t\t\t</Linker>"
2615 puts $aFile "\t\t\t</Target>"
2617 # Debug target configuration
2618 puts $aFile "\t\t\t<Target title=\"Debug\">"
2619 if { "$theIsExe" == "true" } {
2620 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/bind/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
2621 puts $aFile "\t\t\t\t<Option type=\"1\" />"
2623 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
2624 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\" />"
2626 puts $aFile "\t\t\t\t<Option output=\"../../../${aPlatformAndCompiler}/libd/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
2628 puts $aFile "\t\t\t\t<Option type=\"3\" />"
2630 puts $aFile "\t\t\t\t<Option object_output=\"../../../${aPlatformAndCompiler}/objd\" />"
2631 puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
2632 puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
2633 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
2634 puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
2636 puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
2639 # compiler options per TARGET (including defines)
2640 puts $aFile "\t\t\t\t<Compiler>"
2641 foreach aFlagIter $aCmplFlagsDebug {
2642 puts $aFile "\t\t\t\t\t<Add option=\"$aFlagIter\" />"
2644 foreach aMacro $theDefines {
2645 puts $aFile "\t\t\t\t\t<Add option=\"-D${aMacro}\" />"
2647 puts $aFile "\t\t\t\t</Compiler>"
2649 puts $aFile "\t\t\t\t<Linker>"
2650 if { $toPassArgsByFile == 1 } {
2651 puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkDebFileName\" />"
2653 puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aPlatformAndCompiler}/libd\" />"
2654 if { "$thePlatform" == "mac" } {
2655 if { [ lsearch $theLibsList X11 ] >= 0} {
2656 puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
2659 puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
2660 if { "$thePlatform" == "lin" } {
2661 puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aPlatformAndCompiler}/libd\" />"
2663 puts $aFile "\t\t\t\t</Linker>"
2665 puts $aFile "\t\t\t</Target>"
2667 puts $aFile "\t\t</Build>"
2669 # COMMON compiler options
2670 puts $aFile "\t\t<Compiler>"
2671 foreach aFlagIter $aCmplFlags {
2672 puts $aFile "\t\t\t<Add option=\"$aFlagIter\" />"
2674 puts $aFile "\t\t\t<Add option=\"\$(CSF_OPT_CMPL)\" />"
2675 foreach anIncPath $theIncPaths {
2676 puts $aFile "\t\t\t<Add directory=\"$anIncPath\" />"
2678 puts $aFile "\t\t</Compiler>"
2680 # COMMON linker options
2681 puts $aFile "\t\t<Linker>"
2682 if { "$thePlatform" == "wnt" && "$theCmpl" == "gcc" } {
2683 puts $aFile "\t\t\t<Add option=\"-Wl,--export-all-symbols\" />"
2685 foreach aFrameworkName $theFrameworks {
2686 if { "$aFrameworkName" != "" } {
2687 puts $aFile "\t\t\t<Add option=\"-framework $aFrameworkName\" />"
2690 foreach aLibName $theLibsList {
2691 if { "$aLibName" != "" } {
2692 if { "$theCmpl" == "msvc" } {
2693 puts $aFile "\t\t\t<Add library=\"${aLibName}.lib\" />"
2695 puts $aFile "\t\t\t<Add library=\"${aLibName}\" />"
2699 puts $aFile "\t\t</Linker>"
2705 set isFirstSrcFile 1
2706 if { $toPassArgsByFile == 1 } {
2707 set aFileLnkObj [open $aLnkFilePath "w"]
2708 set aFileLnkObjd [open $aLnkDebFilePath "w"]
2711 foreach aSrcFile $theSrcFiles {
2712 if {[string equal -nocase [file extension $aSrcFile] ".mm"]} {
2713 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2714 puts $aFile "\t\t\t<Option compile=\"1\" />"
2715 puts $aFile "\t\t\t<Option link=\"1\" />"
2716 puts $aFile "\t\t</Unit>"
2717 } elseif {[string equal -nocase [file extension $aSrcFile] ".c"]} {
2718 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2719 puts $aFile "\t\t\t<Option compilerVar=\"CC\" />"
2720 puts $aFile "\t\t</Unit>"
2721 } elseif { $toPassArgsByFile == 1 && $isFirstSrcFile == 0 && [string equal -nocase [file extension $aSrcFile] ".cxx" ] } {
2722 # pass at list single source file to Code::Blocks as is
2723 # and pack the list of other files into the dedicated file to workaround process arguments limits on systems like Windows
2724 puts $aFile "\t\t<Unit filename=\"$aSrcFile\">"
2725 puts $aFile "\t\t\t<Option link=\"0\" />"
2726 puts $aFile "\t\t</Unit>"
2728 set aFileObj [string map {.cxx .o} [string map [list "/src/" "/${aPlatformAndCompiler}/obj/src/"] $aSrcFile]]
2729 set aFileObjd [string map {.cxx .o} [string map [list "/src/" "/${aPlatformAndCompiler}/objd/src/"] $aSrcFile]]
2730 puts -nonewline $aFileLnkObj "$aFileObj "
2731 puts -nonewline $aFileLnkObjd "$aFileObjd "
2733 puts $aFile "\t\t<Unit filename=\"$aSrcFile\" />"
2734 set isFirstSrcFile 0
2738 if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
2743 puts $aFile "\t</Project>"
2744 puts $aFile "</CodeBlocks_project_file>"
2747 return $aCbpFilePath
2750 # Define libraries to link using only EXTERNLIB file
2751 proc LibToLinkX {thePackage theDummyName theSrcDir theSourceDirOther} {
2752 set aToolKits [LibToLink $thePackage $theSrcDir $theSourceDirOther]
2756 # Function to generate Xcode workspace and project files
2757 proc OS:MKXCD { theOutDir {theModules {}} {theAllSolution ""} {theLibType "dynamic"} {thePlatform ""} } {
2759 puts stderr "Generating project files for Xcode"
2761 # Generate projects for toolkits and separate workspace for each module
2762 foreach aModule $theModules {
2763 OS:xcworkspace $aModule $aModule $theOutDir
2764 OS:xcodeproj $aModule $theOutDir ::THE_GUIDS_LIST $theLibType $thePlatform
2767 # Generate single workspace "OCCT" containing projects from all modules
2768 if { "$theAllSolution" != "" } {
2769 OS:xcworkspace $theAllSolution $theModules $theOutDir
2773 # Generates toolkits sections for Xcode workspace file.
2774 proc OS:xcworkspace:toolkits { theModule } {
2777 # Adding toolkits for module in workspace.
2778 foreach aToolKit [osutils:tk:sort [${theModule}:toolkits] "src" ""] {
2779 append aBuff " <FileRef\n"
2780 append aBuff " location = \"group:${aToolKit}.xcodeproj\">\n"
2781 append aBuff " </FileRef>\n"
2784 # Adding executables for module, assume one project per cxx file...
2785 foreach aUnit [OS:executable ${theModule}] {
2787 set src_files [_get_used_files $aUnit "src" false]
2789 foreach s $src_files {
2790 regexp {source ([^\s]+)} $s dummy name
2791 lappend aSrcFiles $name
2793 foreach aSrcFile $aSrcFiles {
2794 set aFileExtension [file extension $aSrcFile]
2795 if { $aFileExtension == ".cxx" } {
2796 set aPrjName [file rootname $aSrcFile]
2797 append aBuff " <FileRef\n"
2798 append aBuff " location = \"group:${aPrjName}.xcodeproj\">\n"
2799 append aBuff " </FileRef>\n"
2804 # Removing unnecessary newline character from the end.
2805 set aBuff [string replace $aBuff end end]
2809 # Generates workspace files for Xcode.
2810 proc OS:xcworkspace { theWorkspaceName theModules theOutDir } {
2811 # Creating workspace directory for Xcode.
2812 set aWorkspaceDir "${theOutDir}/${theWorkspaceName}.xcworkspace"
2813 wokUtils:FILES:mkdir $aWorkspaceDir
2814 if { ! [file exists $aWorkspaceDir] } {
2815 puts stderr "Error: Could not create workspace directory \"$aWorkspaceDir\""
2819 # Creating workspace file.
2820 set aWsFilePath "${aWorkspaceDir}/contents.xcworkspacedata"
2821 set aFile [open $aWsFilePath "w"]
2823 # Adding header and section for main Group.
2824 puts $aFile "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2825 puts $aFile "<Workspace"
2826 puts $aFile " version = \"1.0\">"
2827 puts $aFile " <Group"
2828 puts $aFile " location = \"container:\""
2829 puts $aFile " name = \"${theWorkspaceName}\">"
2832 if { [llength "$theModules"] > 1 } {
2833 foreach aModule $theModules {
2834 puts $aFile " <Group"
2835 puts $aFile " location = \"container:\""
2836 puts $aFile " name = \"${aModule}\">"
2837 puts $aFile [OS:xcworkspace:toolkits $aModule]
2838 puts $aFile " </Group>"
2841 puts $aFile [OS:xcworkspace:toolkits $theModules]
2845 puts $aFile " </Group>"
2846 puts $aFile "</Workspace>"
2850 # Generates Xcode project files.
2851 proc OS:xcodeproj { theModules theOutDir theGuidsMap theLibType thePlatform} {
2852 upvar $theGuidsMap aGuidsMap
2855 if { "$theLibType" == "static" } {
2857 } elseif { "$thePlatform" == "ios" } {
2861 set aProjectFiles {}
2862 foreach aModule $theModules {
2863 foreach aToolKit [${aModule}:toolkits] {
2864 lappend aProjectFiles [osutils:xcdtk $theOutDir $aToolKit aGuidsMap $isStatic $thePlatform "dylib"]
2866 foreach anExecutable [OS:executable ${aModule}] {
2867 lappend aProjectFiles [osutils:xcdtk $theOutDir $anExecutable aGuidsMap $isStatic $thePlatform "executable"]
2870 return $aProjectFiles
2873 # Generates dependencies section for Xcode project files.
2874 proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection theDepsGuids theDepsRefGuids thePlatform theIsStatic} {
2875 upvar $theGuidsMap aGuidsMap
2876 upvar $theFileRefSection aFileRefSection
2877 upvar $theDepsGuids aDepsGuids
2878 upvar $theDepsRefGuids aDepsRefGuids
2880 set aBuildFileSection ""
2881 set aUsedLibs [wokUtils:LIST:Purge [osutils:tk:close $theToolKit "src" ""]]
2882 set aDepToolkits [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit "src" ""]] $theToolKit]
2884 if { "$theTargetType" == "executable" } {
2885 set aFile [osutils:tk:cxxfiles $theToolKit mac "src"]
2886 set aProjName [file rootname [file tail $aFile]]
2887 set aDepToolkits [LibToLinkX $theToolKit $aProjName "src" ""]
2891 if { $theIsStatic == 1 } {
2893 if { "$theTargetType" != "executable" } {
2894 return $aBuildFileSection
2898 osutils:usedOsLibs $theToolKit $thePlatform aLibs aFrameworks "src"
2899 set aUsedLibs [concat $aUsedLibs $aLibs]
2900 set aUsedLibs [concat $aUsedLibs $aFrameworks]
2901 foreach tkx $aUsedLibs {
2902 set aDepLib "${tkx}_Dep"
2903 set aDepLibRef "${tkx}_DepRef"
2905 if { ! [info exists aGuidsMap($aDepLib)] } {
2906 set aGuidsMap($aDepLib) [OS:genGUID "xcd"]
2908 if { ! [info exists aGuidsMap($aDepLibRef)] } {
2909 set aGuidsMap($aDepLibRef) [OS:genGUID "xcd"]
2912 append aBuildFileSection "\t\t$aGuidsMap($aDepLib) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aDepLibRef) ; \};\n"
2913 if {[lsearch -nocase $aFrameworks $tkx] == -1} {
2914 append aFileRefSection "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = file; name = lib${tkx}.${aLibExt}; path = lib${tkx}.${aLibExt}; sourceTree = \"<group>\"; \};\n"
2916 append aFileRefSection "\t\t$aGuidsMap($aDepLibRef) = \{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ${tkx}.framework; path = /System/Library/Frameworks/${tkx}.framework; sourceTree = \"<absolute>\"; \};\n"
2918 append aDepsGuids "\t\t\t\t$aGuidsMap($aDepLib) ,\n"
2919 append aDepsRefGuids "\t\t\t\t$aGuidsMap($aDepLibRef) ,\n"
2922 return $aBuildFileSection
2925 # Generates PBXBuildFile and PBXGroup sections for project file.
2926 proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGroupSection thePackageGuids theSrcFileGuids theGuidsMap theIncPaths} {
2927 upvar $theSrcFileRefSection aSrcFileRefSection
2928 upvar $theGroupSection aGroupSection
2929 upvar $thePackageGuids aPackagesGuids
2930 upvar $theSrcFileGuids aSrcFileGuids
2931 upvar $theGuidsMap aGuidsMap
2932 upvar $theIncPaths anIncPaths
2934 set listloc [osutils:tk:units $theToolKit "src"]
2935 set aBuildFileSection ""
2936 set aPackages [lsort -nocase $listloc]
2937 if { "$theTargetType" == "executable" } {
2938 set aPackages [list "$theToolKit"]
2941 # Generating PBXBuildFile, PBXGroup sections and groups for each package.
2942 foreach fxlo $aPackages {
2944 set aPackage "${xlo}_Package"
2945 set aSrcFileRefGuids ""
2946 if { ! [info exists aGuidsMap($aPackage)] } {
2947 set aGuidsMap($aPackage) [OS:genGUID "xcd"]
2950 set aSrcFiles [osutils:tk:cxxfiles $xlo mac "src"]
2951 foreach aSrcFile [lsort $aSrcFiles] {
2952 set aFileExt "sourcecode.cpp.cpp"
2954 if { [file extension $aSrcFile] == ".c" } {
2955 set aFileExt "sourcecode.c.c"
2956 } elseif { [file extension $aSrcFile] == ".mm" } {
2957 set aFileExt "sourcecode.cpp.objcpp"
2960 if { ! [info exists aGuidsMap($aSrcFile)] } {
2961 set aGuidsMap($aSrcFile) [OS:genGUID "xcd"]
2963 set aSrcFileRef "${aSrcFile}_Ref"
2964 if { ! [info exists aGuidsMap($aSrcFileRef)] } {
2965 set aGuidsMap($aSrcFileRef) [OS:genGUID "xcd"]
2967 if { ! [info exists written([file tail $aSrcFile])] } {
2968 set written([file tail $aSrcFile]) 1
2969 append aBuildFileSection "\t\t$aGuidsMap($aSrcFile) = \{isa = PBXBuildFile; fileRef = $aGuidsMap($aSrcFileRef) ;\};\n"
2970 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"
2971 append aSrcFileGuids "\t\t\t\t$aGuidsMap($aSrcFile) ,\n"
2972 append aSrcFileRefGuids "\t\t\t\t$aGuidsMap($aSrcFileRef) ,\n"
2974 puts "Warning : more than one occurrences for [file tail $aSrcFile]"
2978 append aGroupSection "\t\t$aGuidsMap($aPackage) = \{\n"
2979 append aGroupSection "\t\t\tisa = PBXGroup;\n"
2980 append aGroupSection "\t\t\tchildren = (\n"
2981 append aGroupSection $aSrcFileRefGuids
2982 append aGroupSection "\t\t\t);\n"
2983 append aGroupSection "\t\t\tname = $xlo;\n"
2984 append aGroupSection "\t\t\tsourceTree = \"<group>\";\n"
2985 append aGroupSection "\t\t\};\n"
2987 # Storing packages IDs for adding them later as a child of toolkit
2988 append aPackagesGuids "\t\t\t\t$aGuidsMap($aPackage) ,\n"
2991 # Removing unnecessary newline character from the end.
2992 set aPackagesGuids [string replace $aPackagesGuids end end]
2994 return $aBuildFileSection
2997 # Creates folders structure and all necessary files for Xcode project.
2998 proc osutils:xcdtk { theOutDir theToolKit theGuidsMap theIsStatic thePlatform {theTargetType "dylib"} } {
2999 set aPBXBuildPhase "Headers"
3000 set aRunOnlyForDeployment "0"
3001 set aProductType "library.dynamic"
3002 set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = dylib;"
3003 set anExecPrefix "\t\t\t\tEXECUTABLE_PREFIX = lib;"
3004 set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = dylib;"
3005 set aTKDefines [list "OCC_CONVERT_SIGNALS"]
3006 if { $theIsStatic == 1 } {
3007 lappend aTKDefines "OCCT_NO_PLUGINS"
3010 if { "$theTargetType" == "executable" } {
3011 set aPBXBuildPhase "CopyFiles"
3012 set aRunOnlyForDeployment "1"
3013 set aProductType "tool"
3014 set anExecExtension ""
3016 set aWrapperExtension ""
3017 } elseif { $theIsStatic == 1 } {
3018 set aProductType "library.static"
3019 set anExecExtension "\t\t\t\tEXECUTABLE_EXTENSION = a;"
3020 set aWrapperExtension "\t\t\t\tWRAPPER_EXTENSION = a;"
3023 set aUsername [exec whoami]
3025 # Creation of folders for Xcode projectP.
3026 set aToolkitDir "${theOutDir}/${theToolKit}.xcodeproj"
3027 wokUtils:FILES:mkdir $aToolkitDir
3028 if { ! [file exists $aToolkitDir] } {
3029 puts stderr "Error: Could not create project directory \"$aToolkitDir\""
3033 set aUserDataDir "${aToolkitDir}/xcuserdata"
3034 wokUtils:FILES:mkdir $aUserDataDir
3035 if { ! [file exists $aUserDataDir] } {
3036 puts stderr "Error: Could not create xcuserdata directory in \"$aToolkitDir\""
3040 set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3041 wokUtils:FILES:mkdir $aUserDataDir
3042 if { ! [file exists $aUserDataDir] } {
3043 puts stderr "Error: Could not create ${aUsername}.xcuserdatad directory in \"$aToolkitDir\"/xcuserdata"
3047 set aSchemesDir "${aUserDataDir}/xcschemes"
3048 wokUtils:FILES:mkdir $aSchemesDir
3049 if { ! [file exists $aSchemesDir] } {
3050 puts stderr "Error: Could not create xcschemes directory in \"$aUserDataDir\""
3053 # End of folders creation.
3055 # Generating GUID for toolkit.
3056 upvar $theGuidsMap aGuidsMap
3057 if { ! [info exists aGuidsMap($theToolKit)] } {
3058 set aGuidsMap($theToolKit) [OS:genGUID "xcd"]
3061 # Creating xcscheme file for toolkit from template.
3062 set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcd"]
3063 regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theToolKit aXcschemeTmpl
3064 regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theToolKit) aXcschemeTmpl
3065 set aXcschemeFile [open "$aSchemesDir/${theToolKit}.xcscheme" "w"]
3066 puts $aXcschemeFile $aXcschemeTmpl
3067 close $aXcschemeFile
3069 # Creating xcschememanagement.plist file for toolkit from template.
3070 set aPlistTmpl [osutils:readtemplate "plist" "xcd"]
3071 regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theToolKit aPlistTmpl
3072 regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theToolKit) aPlistTmpl
3073 set aPlistFile [open "$aSchemesDir/xcschememanagement.plist" "w"]
3074 puts $aPlistFile $aPlistTmpl
3077 # Creating project.pbxproj file for toolkit.
3078 set aPbxprojFile [open "$aToolkitDir/project.pbxproj" "w"]
3079 puts $aPbxprojFile "// !\$*UTF8*\$!"
3080 puts $aPbxprojFile "\{"
3081 puts $aPbxprojFile "\tarchiveVersion = 1;"
3082 puts $aPbxprojFile "\tclasses = \{"
3083 puts $aPbxprojFile "\t\};"
3084 puts $aPbxprojFile "\tobjectVersion = 46;"
3085 puts $aPbxprojFile "\tobjects = \{\n"
3087 # Begin PBXBuildFile section
3088 set aPackagesGuids ""
3089 set aGroupSection ""
3090 set aSrcFileRefSection ""
3091 set aSrcFileGuids ""
3092 set aDepsFileRefSection ""
3094 set aDepsRefGuids ""
3095 set anIncPaths [list "../../../inc"]
3098 if { [info exists ::env(CSF_OPT_INC)] } {
3099 set anIncCfg [split "$::env(CSF_OPT_INC)" ":"]
3100 foreach anIncCfgPath $anIncCfg {
3101 lappend anIncPaths $anIncCfgPath
3104 if { [info exists ::env(CSF_OPT_LIB64)] } {
3105 set anLibCfg [split "$::env(CSF_OPT_LIB64)" ":"]
3106 foreach anLibCfgPath $anLibCfg {
3107 lappend anLibPaths $anLibCfgPath
3111 puts $aPbxprojFile [osutils:xcdtk:sources $theToolKit $theTargetType aSrcFileRefSection aGroupSection aPackagesGuids aSrcFileGuids aGuidsMap anIncPaths]
3112 puts $aPbxprojFile [osutils:xcdtk:deps $theToolKit $theTargetType aGuidsMap aDepsFileRefSection aDepsGuids aDepsRefGuids $thePlatform $theIsStatic]
3113 # End PBXBuildFile section
3115 # Begin PBXFileReference section
3116 set aToolkitLib "lib${theToolKit}.dylib"
3117 set aPath "$aToolkitLib"
3118 if { "$theTargetType" == "executable" } {
3119 set aPath "$theToolKit"
3120 } elseif { $theIsStatic == 1 } {
3121 set aToolkitLib "lib${theToolKit}.a"
3124 if { ! [info exists aGuidsMap($aToolkitLib)] } {
3125 set aGuidsMap($aToolkitLib) [OS:genGUID "xcd"]
3128 puts $aPbxprojFile "\t\t$aGuidsMap($aToolkitLib) = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.${theTargetType}\"; includeInIndex = 0; path = $aPath; sourceTree = BUILT_PRODUCTS_DIR; };\n"
3129 puts $aPbxprojFile $aSrcFileRefSection
3130 puts $aPbxprojFile $aDepsFileRefSection
3131 # End PBXFileReference section
3134 # Begin PBXFrameworksBuildPhase section
3135 set aTkFrameworks "${theToolKit}_Frameworks"
3136 if { ! [info exists aGuidsMap($aTkFrameworks)] } {
3137 set aGuidsMap($aTkFrameworks) [OS:genGUID "xcd"]
3140 puts $aPbxprojFile "\t\t$aGuidsMap($aTkFrameworks) = \{"
3141 puts $aPbxprojFile "\t\t\tisa = PBXFrameworksBuildPhase;"
3142 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3143 puts $aPbxprojFile "\t\t\tfiles = ("
3144 puts $aPbxprojFile $aDepsGuids
3145 puts $aPbxprojFile "\t\t\t);"
3146 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3147 puts $aPbxprojFile "\t\t\};\n"
3148 # End PBXFrameworksBuildPhase section
3150 # Begin PBXGroup section
3151 set aTkPBXGroup "${theToolKit}_PBXGroup"
3152 if { ! [info exists aGuidsMap($aTkPBXGroup)] } {
3153 set aGuidsMap($aTkPBXGroup) [OS:genGUID "xcd"]
3156 set aTkSrcGroup "${theToolKit}_SrcGroup"
3157 if { ! [info exists aGuidsMap($aTkSrcGroup)] } {
3158 set aGuidsMap($aTkSrcGroup) [OS:genGUID "xcd"]
3161 puts $aPbxprojFile $aGroupSection
3162 puts $aPbxprojFile "\t\t$aGuidsMap($aTkPBXGroup) = \{"
3163 puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
3164 puts $aPbxprojFile "\t\t\tchildren = ("
3165 puts $aPbxprojFile $aDepsRefGuids
3166 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSrcGroup) ,"
3167 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aToolkitLib) ,"
3168 puts $aPbxprojFile "\t\t\t);"
3169 puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
3170 puts $aPbxprojFile "\t\t\};"
3171 puts $aPbxprojFile "\t\t$aGuidsMap($aTkSrcGroup) = \{"
3172 puts $aPbxprojFile "\t\t\tisa = PBXGroup;"
3173 puts $aPbxprojFile "\t\t\tchildren = ("
3174 puts $aPbxprojFile $aPackagesGuids
3175 puts $aPbxprojFile "\t\t\t);"
3176 puts $aPbxprojFile "\t\t\tname = \"Source files\";"
3177 puts $aPbxprojFile "\t\t\tsourceTree = \"<group>\";"
3178 puts $aPbxprojFile "\t\t\};\n"
3179 # End PBXGroup section
3181 # Begin PBXHeadersBuildPhase section
3182 set aTkHeaders "${theToolKit}_Headers"
3183 if { ! [info exists aGuidsMap($aTkHeaders)] } {
3184 set aGuidsMap($aTkHeaders) [OS:genGUID "xcd"]
3187 puts $aPbxprojFile "\t\t$aGuidsMap($aTkHeaders) = \{"
3188 puts $aPbxprojFile "\t\t\tisa = PBX${aPBXBuildPhase}BuildPhase;"
3189 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3190 puts $aPbxprojFile "\t\t\tfiles = ("
3191 puts $aPbxprojFile "\t\t\t);"
3192 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = ${aRunOnlyForDeployment};"
3193 puts $aPbxprojFile "\t\t\};\n"
3194 # End PBXHeadersBuildPhase section
3196 # Begin PBXNativeTarget section
3197 set aTkBuildCfgListNativeTarget "${theToolKit}_BuildCfgListNativeTarget"
3198 if { ! [info exists aGuidsMap($aTkBuildCfgListNativeTarget)] } {
3199 set aGuidsMap($aTkBuildCfgListNativeTarget) [OS:genGUID "xcd"]
3202 set aTkSources "${theToolKit}_Sources"
3203 if { ! [info exists aGuidsMap($aTkSources)] } {
3204 set aGuidsMap($aTkSources) [OS:genGUID "xcd"]
3207 puts $aPbxprojFile "\t\t$aGuidsMap($theToolKit) = \{"
3208 puts $aPbxprojFile "\t\t\tisa = PBXNativeTarget;"
3209 puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListNativeTarget) ;"
3210 puts $aPbxprojFile "\t\t\tbuildPhases = ("
3211 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkSources) ,"
3212 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkFrameworks) ,"
3213 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkHeaders) ,"
3214 puts $aPbxprojFile "\t\t\t);"
3215 puts $aPbxprojFile "\t\t\tbuildRules = ("
3216 puts $aPbxprojFile "\t\t\t);"
3217 puts $aPbxprojFile "\t\t\tdependencies = ("
3218 puts $aPbxprojFile "\t\t\t);"
3219 puts $aPbxprojFile "\t\t\tname = $theToolKit;"
3220 puts $aPbxprojFile "\t\t\tproductName = $theToolKit;"
3221 puts $aPbxprojFile "\t\t\tproductReference = $aGuidsMap($aToolkitLib) ;"
3222 puts $aPbxprojFile "\t\t\tproductType = \"com.apple.product-type.${aProductType}\";"
3223 puts $aPbxprojFile "\t\t\};\n"
3224 # End PBXNativeTarget section
3226 # Begin PBXProject section
3227 set aTkProjectObj "${theToolKit}_ProjectObj"
3228 if { ! [info exists aGuidsMap($aTkProjectObj)] } {
3229 set aGuidsMap($aTkProjectObj) [OS:genGUID "xcd"]
3232 set aTkBuildCfgListProj "${theToolKit}_BuildCfgListProj"
3233 if { ! [info exists aGuidsMap($aTkBuildCfgListProj)] } {
3234 set aGuidsMap($aTkBuildCfgListProj) [OS:genGUID "xcd"]
3237 puts $aPbxprojFile "\t\t$aGuidsMap($aTkProjectObj) = \{"
3238 puts $aPbxprojFile "\t\t\tisa = PBXProject;"
3239 puts $aPbxprojFile "\t\t\tattributes = \{"
3240 puts $aPbxprojFile "\t\t\t\tLastUpgradeCheck = 0430;"
3241 puts $aPbxprojFile "\t\t\t\};"
3242 puts $aPbxprojFile "\t\t\tbuildConfigurationList = $aGuidsMap($aTkBuildCfgListProj) ;"
3243 puts $aPbxprojFile "\t\t\tcompatibilityVersion = \"Xcode 3.2\";"
3244 puts $aPbxprojFile "\t\t\tdevelopmentRegion = English;"
3245 puts $aPbxprojFile "\t\t\thasScannedForEncodings = 0;"
3246 puts $aPbxprojFile "\t\t\tknownRegions = ("
3247 puts $aPbxprojFile "\t\t\t\ten,"
3248 puts $aPbxprojFile "\t\t\t);"
3249 puts $aPbxprojFile "\t\t\tmainGroup = $aGuidsMap($aTkPBXGroup);"
3250 puts $aPbxprojFile "\t\t\tproductRefGroup = $aGuidsMap($aTkPBXGroup);"
3251 puts $aPbxprojFile "\t\t\tprojectDirPath = \"\";"
3252 puts $aPbxprojFile "\t\t\tprojectRoot = \"\";"
3253 puts $aPbxprojFile "\t\t\ttargets = ("
3254 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($theToolKit) ,"
3255 puts $aPbxprojFile "\t\t\t);"
3256 puts $aPbxprojFile "\t\t\};\n"
3257 # End PBXProject section
3259 # Begin PBXSourcesBuildPhase section
3260 puts $aPbxprojFile "\t\t$aGuidsMap($aTkSources) = \{"
3261 puts $aPbxprojFile "\t\t\tisa = PBXSourcesBuildPhase;"
3262 puts $aPbxprojFile "\t\t\tbuildActionMask = 2147483647;"
3263 puts $aPbxprojFile "\t\t\tfiles = ("
3264 puts $aPbxprojFile $aSrcFileGuids
3265 puts $aPbxprojFile "\t\t\t);"
3266 puts $aPbxprojFile "\t\t\trunOnlyForDeploymentPostprocessing = 0;"
3267 puts $aPbxprojFile "\t\t\};\n"
3268 # End PBXSourcesBuildPhase section
3270 # Begin XCBuildConfiguration section
3271 set aTkDebugProject "${theToolKit}_DebugProject"
3272 if { ! [info exists aGuidsMap($aTkDebugProject)] } {
3273 set aGuidsMap($aTkDebugProject) [OS:genGUID "xcd"]
3276 set aTkReleaseProject "${theToolKit}_ReleaseProject"
3277 if { ! [info exists aGuidsMap($aTkReleaseProject)] } {
3278 set aGuidsMap($aTkReleaseProject) [OS:genGUID "xcd"]
3281 set aTkDebugNativeTarget "${theToolKit}_DebugNativeTarget"
3282 if { ! [info exists aGuidsMap($aTkDebugNativeTarget)] } {
3283 set aGuidsMap($aTkDebugNativeTarget) [OS:genGUID "xcd"]
3286 set aTkReleaseNativeTarget "${theToolKit}_ReleaseNativeTarget"
3287 if { ! [info exists aGuidsMap($aTkReleaseNativeTarget)] } {
3288 set aGuidsMap($aTkReleaseNativeTarget) [OS:genGUID "xcd"]
3292 puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugProject) = \{"
3293 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3294 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3296 puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;"
3297 puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3298 if { "$thePlatform" == "ios" } {
3299 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3300 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
3301 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3302 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3304 puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
3305 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3306 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"c++0x\";"
3307 puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = NO;"
3308 puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3309 puts $aPbxprojFile "\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;"
3310 puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3311 puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;"
3312 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3313 puts $aPbxprojFile "\t\t\t\t\t\"DEBUG=1\","
3314 puts $aPbxprojFile "\t\t\t\t\t\"\$\(inherited\)\","
3315 puts $aPbxprojFile "\t\t\t\t);"
3316 puts $aPbxprojFile "\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;"
3317 puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3318 puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3319 puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3320 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3321 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3322 puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64D)\"; "
3323 if { "$thePlatform" == "ios" } {
3324 puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = NO;"
3325 puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3327 puts $aPbxprojFile "\t\t\t\tONLY_ACTIVE_ARCH = YES;"
3329 puts $aPbxprojFile "\t\t\t\};"
3331 puts $aPbxprojFile "\t\t\tname = Debug;"
3332 puts $aPbxprojFile "\t\t\};"
3335 puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseProject) = \{"
3336 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3337 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3339 puts $aPbxprojFile "\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";"
3340 puts $aPbxprojFile "\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;"
3341 if { "$thePlatform" == "ios" } {
3342 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphoneos\*\]\" = \"\$(ARCHS_STANDARD)\";";
3343 puts $aPbxprojFile "\t\t\t\t\"ARCHS\[sdk=iphonesimulator\*\]\" = \"x86_64\";";
3344 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_MODULES = YES;"
3345 puts $aPbxprojFile "\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;"
3347 puts $aPbxprojFile "\t\t\t\tARCHS = \"\$(ARCHS_STANDARD_64_BIT)\";"
3348 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";"
3349 puts $aPbxprojFile "\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"c++0x\";"
3350 puts $aPbxprojFile "\t\t\t\tCOPY_PHASE_STRIP = YES;"
3351 puts $aPbxprojFile "\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;"
3352 puts $aPbxprojFile "\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;"
3353 puts $aPbxprojFile "\t\t\t\tDEAD_CODE_STRIPPING = NO;"
3354 puts $aPbxprojFile "\t\t\t\tGCC_OPTIMIZATION_LEVEL = 2;"
3355 puts $aPbxprojFile "\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;"
3356 puts $aPbxprojFile "\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;"
3357 puts $aPbxprojFile "\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;"
3358 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;"
3359 puts $aPbxprojFile "\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;"
3360 puts $aPbxprojFile "\t\t\t\tOTHER_LDFLAGS = \"\$(CSF_OPT_LNK64)\";"
3361 if { "$thePlatform" == "ios" } {
3362 puts $aPbxprojFile "\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;"
3363 puts $aPbxprojFile "\t\t\t\tSDKROOT = iphoneos;"
3365 puts $aPbxprojFile "\t\t\t\};"
3366 puts $aPbxprojFile "\t\t\tname = Release;"
3367 puts $aPbxprojFile "\t\t\};"
3368 puts $aPbxprojFile "\t\t$aGuidsMap($aTkDebugNativeTarget) = \{"
3369 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3370 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3371 puts $aPbxprojFile "${anExecExtension}"
3372 puts $aPbxprojFile "${anExecPrefix}"
3373 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3374 foreach aMacro $aTKDefines {
3375 puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3377 puts $aPbxprojFile "\t\t\t\t);"
3379 puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3380 foreach anIncPath $anIncPaths {
3381 puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3383 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3384 puts $aPbxprojFile "\t\t\t\t);"
3386 puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3387 foreach anLibPath $anLibPaths {
3388 puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3390 puts $aPbxprojFile "\t\t\t\t);"
3392 puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3393 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3394 puts $aPbxprojFile "\t\t\t\t);"
3395 puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3396 puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3397 puts $aPbxprojFile "\t\t\t\t);"
3398 puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3399 set anUserHeaderSearchPath "\t\t\t\tUSER_HEADER_SEARCH_PATHS = \""
3400 foreach anIncPath $anIncPaths {
3401 append anUserHeaderSearchPath " ${anIncPath}"
3403 append anUserHeaderSearchPath "\";"
3404 puts $aPbxprojFile $anUserHeaderSearchPath
3405 puts $aPbxprojFile "${aWrapperExtension}"
3406 puts $aPbxprojFile "\t\t\t\};"
3407 puts $aPbxprojFile "\t\t\tname = Debug;"
3408 puts $aPbxprojFile "\t\t\};"
3409 puts $aPbxprojFile "\t\t$aGuidsMap($aTkReleaseNativeTarget) = \{"
3410 puts $aPbxprojFile "\t\t\tisa = XCBuildConfiguration;"
3411 puts $aPbxprojFile "\t\t\tbuildSettings = \{"
3412 puts $aPbxprojFile "${anExecExtension}"
3413 puts $aPbxprojFile "${anExecPrefix}"
3414 puts $aPbxprojFile "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = ("
3415 foreach aMacro $aTKDefines {
3416 puts $aPbxprojFile "\t\t\t\t\t${aMacro} ,"
3418 puts $aPbxprojFile "\t\t\t\t);"
3419 puts $aPbxprojFile "\t\t\t\tHEADER_SEARCH_PATHS = ("
3420 foreach anIncPath $anIncPaths {
3421 puts $aPbxprojFile "\t\t\t\t\t${anIncPath},"
3423 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_INC)\","
3424 puts $aPbxprojFile "\t\t\t\t);"
3426 puts $aPbxprojFile "\t\t\t\tLIBRARY_SEARCH_PATHS = ("
3427 foreach anLibPath $anLibPaths {
3428 puts $aPbxprojFile "\t\t\t\t\t${anLibPath},"
3430 puts $aPbxprojFile "\t\t\t\t);"
3432 puts $aPbxprojFile "\t\t\t\tOTHER_CFLAGS = ("
3433 puts $aPbxprojFile "\t\t\t\t\t\"\$(CSF_OPT_CMPL)\","
3434 puts $aPbxprojFile "\t\t\t\t);"
3435 puts $aPbxprojFile "\t\t\t\tOTHER_CPLUSPLUSFLAGS = ("
3436 puts $aPbxprojFile "\t\t\t\t\t\"\$(OTHER_CFLAGS)\","
3437 puts $aPbxprojFile "\t\t\t\t);"
3438 puts $aPbxprojFile "\t\t\t\tPRODUCT_NAME = \"\$(TARGET_NAME)\";"
3439 puts $aPbxprojFile $anUserHeaderSearchPath
3440 puts $aPbxprojFile "${aWrapperExtension}"
3441 puts $aPbxprojFile "\t\t\t\};"
3442 puts $aPbxprojFile "\t\t\tname = Release;"
3443 puts $aPbxprojFile "\t\t\};\n"
3444 # End XCBuildConfiguration section
3446 # Begin XCConfigurationList section
3447 puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListProj) = \{"
3448 puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3449 puts $aPbxprojFile "\t\tbuildConfigurations = ("
3450 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugProject) ,"
3451 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseProject) ,"
3452 puts $aPbxprojFile "\t\t\t);"
3453 puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3454 puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3455 puts $aPbxprojFile "\t\t\};"
3456 puts $aPbxprojFile "\t\t$aGuidsMap($aTkBuildCfgListNativeTarget) = \{"
3457 puts $aPbxprojFile "\t\t\tisa = XCConfigurationList;"
3458 puts $aPbxprojFile "\t\t\tbuildConfigurations = ("
3459 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkDebugNativeTarget) ,"
3460 puts $aPbxprojFile "\t\t\t\t$aGuidsMap($aTkReleaseNativeTarget) ,"
3461 puts $aPbxprojFile "\t\t\t);"
3462 puts $aPbxprojFile "\t\t\tdefaultConfigurationIsVisible = 0;"
3463 puts $aPbxprojFile "\t\t\tdefaultConfigurationName = Release;"
3464 puts $aPbxprojFile "\t\t\};\n"
3465 # End XCConfigurationList section
3467 puts $aPbxprojFile "\t\};"
3468 puts $aPbxprojFile "\trootObject = $aGuidsMap($aTkProjectObj) ;"
3469 puts $aPbxprojFile "\}"
3474 proc osutils:xcdx { theOutDir theExecutable theGuidsMap } {
3475 set aUsername [exec whoami]
3477 # Creating folders for Xcode project file.
3478 set anExecutableDir "${theOutDir}/${theExecutable}.xcodeproj"
3479 wokUtils:FILES:mkdir $anExecutableDir
3480 if { ! [file exists $anExecutableDir] } {
3481 puts stderr "Error: Could not create project directory \"$anExecutableDir\""
3485 set aUserDataDir "${anExecutableDir}/xcuserdata"
3486 wokUtils:FILES:mkdir $aUserDataDir
3487 if { ! [file exists $aUserDataDir] } {
3488 puts stderr "Error: Could not create xcuserdata directory in \"$anExecutableDir\""
3492 set aUserDataDir "${aUserDataDir}/${aUsername}.xcuserdatad"
3493 wokUtils:FILES:mkdir $aUserDataDir
3494 if { ! [file exists $aUserDataDir] } {
3495 puts stderr "Error: Could not create ${aUsername}.xcuserdatad directory in \"$anExecutableDir\"/xcuserdata"
3499 set aSchemesDir "${aUserDataDir}/xcschemes"
3500 wokUtils:FILES:mkdir $aSchemesDir
3501 if { ! [file exists $aSchemesDir] } {
3502 puts stderr "Error: Could not create xcschemes directory in \"$aUserDataDir\""
3505 # End folders creation.
3507 # Generating GUID for toolkit.
3508 upvar $theGuidsMap aGuidsMap
3509 if { ! [info exists aGuidsMap($theExecutable)] } {
3510 set aGuidsMap($theExecutable) [OS:genGUID "xcd"]
3513 # Creating xcscheme file for toolkit from template.
3514 set aXcschemeTmpl [osutils:readtemplate "xcscheme" "xcode"]
3515 regsub -all -- {__TOOLKIT_NAME__} $aXcschemeTmpl $theExecutable aXcschemeTmpl
3516 regsub -all -- {__TOOLKIT_GUID__} $aXcschemeTmpl $aGuidsMap($theExecutable) aXcschemeTmpl
3517 set aXcschemeFile [open "$aSchemesDir/${theExecutable}.xcscheme" "w"]
3518 puts $aXcschemeFile $aXcschemeTmpl
3519 close $aXcschemeFile
3521 # Creating xcschememanagement.plist file for toolkit from template.
3522 set aPlistTmpl [osutils:readtemplate "plist" "xcode"]
3523 regsub -all -- {__TOOLKIT_NAME__} $aPlistTmpl $theExecutable aPlistTmpl
3524 regsub -all -- {__TOOLKIT_GUID__} $aPlistTmpl $aGuidsMap($theExecutable) aPlistTmpl
3525 set aPlistFile [open "$aSchemesDir/xcschememanagement.plist" "w"]
3526 puts $aPlistFile $aPlistTmpl
3530 # Returns available Windows SDKs versions
3531 proc osutils:sdk { theSdkMajorVer {isQuietMode false} {theSdkDirectories {}} } {
3532 if { ![llength ${theSdkDirectories}] } {
3533 foreach anEnvVar { "ProgramFiles" "ProgramFiles\(x86\)" "ProgramW6432" } {
3534 if {[ info exists ::env(${anEnvVar}) ]} {
3535 lappend theSdkDirectories "$::env(${anEnvVar})/Windows Kits/${theSdkMajorVer}/Include"
3541 foreach sdk_dir ${theSdkDirectories} {
3542 if { [file isdirectory ${sdk_dir}] } {
3543 lappend sdk_versions [glob -tails -directory "${sdk_dir}" -type d *]
3547 if {![llength ${sdk_versions}] && !${isQuietMode}} {
3548 error "Error : Could not find Windows SDK ${theSdkMajorVer}"
3551 return [join [lsort -unique ${sdk_versions}] " "]
3554 # Generate global properties to Visual Studio project file for UWP solution
3555 proc osutils:uwp:proj { isUWP theProjTmpl } {
3557 set uwp_properties ""
3558 set uwp_generate_metadata ""
3559 set uwp_app_container ""
3561 set format_template ""
3564 set sdk_versions [osutils:sdk 10]
3565 set sdk_max_ver [lindex ${sdk_versions} end]
3567 set uwp_properties "<DefaultLanguage>en-US</DefaultLanguage>\n \
3568 <ApplicationType>Windows Store</ApplicationType>\n \
3569 <ApplicationTypeRevision>10.0</ApplicationTypeRevision>\n \
3570 <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\n \
3571 <AppContainerApplication>true</AppContainerApplication>\n \
3572 <WindowsTargetPlatformVersion>${sdk_max_ver}</WindowsTargetPlatformVersion>\n \
3573 <WindowsTargetPlatformMinVersion>${sdk_max_ver}</WindowsTargetPlatformMinVersion>"
3575 set uwp_generate_metadata "<GenerateWindowsMetadata>false</GenerateWindowsMetadata>"
3577 regsub -all -- {[\r\n\s]*<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>} ${theProjTmpl} "" theProjTmpl
3579 set format_template "\[\\r\\n\\s\]*"
3582 regsub -all -- "${format_template}__UWP_PROPERTIES__" ${theProjTmpl} "${uwp_properties}" theProjTmpl
3583 regsub -all -- "${format_template}__UWP_GENERATE_METADATA__" ${theProjTmpl} "${uwp_generate_metadata}" theProjTmpl
3585 return ${theProjTmpl}
3588 # Report all files found in package directory but not listed in FILES
3589 proc osutils:checksrcfiles { theUnit theSrcDir} {
3591 set aCasRoot [file normalize ${path}]
3593 if {![file isdirectory ${aCasRoot}]} {
3594 puts "OCCT directory is not defined correctly: ${aCasRoot}"
3598 set anUnitAbsPath [file normalize "${aCasRoot}/$theSrcDir/${theUnit}"]
3600 if {[file exists "${anUnitAbsPath}/FILES"]} {
3601 set aFilesFile [open "${anUnitAbsPath}/FILES" rb]
3602 set aFilesFileList [split [read ${aFilesFile}] "\n"]
3605 set aFilesFileList [lsearch -inline -all -not -exact ${aFilesFileList} ""]
3607 # report all files not listed in FILES
3608 set anAllFiles [glob -tails -nocomplain -dir ${anUnitAbsPath} "*"]
3609 foreach aFile ${anAllFiles} {
3610 if { "${aFile}" == "FILES" } {
3613 if { "${aFile}" == "icons" } {
3616 if { [lsearch -exact ${aFilesFileList} ${aFile}] == -1 } {
3617 puts "Warning: file ${anUnitAbsPath}/${aFile} is not listed in ${anUnitAbsPath}/FILES!"