0028701: Configuration - add support of VS 2017
authorabv <abv@opencascade.com>
Tue, 2 May 2017 05:36:49 +0000 (08:36 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 13 Jul 2017 14:29:45 +0000 (17:29 +0300)
Added support of Visual Studio 2017 (15) in CMake build procedure.
CMake 3.7.2 or above is required to generate projects for VS 2017.

Since version of compiler and toolset remained at 14 (now they are 14.1), and they use the same run-time, the same third-party products as for VS 2015 (14) can be used.
Also the name of the folder for installation of OCCT binaries in OCCT-standard layout (default on Windows) remains "vc14".

Support of Visual Studio 2017 is added in genproj generator and relevant environment, with format specifier "vc141".

The syntax of the genproj command is revised:
- UWP is considered as separate platform ("uwp" alternative to "wnt"), not part of IDE specification
- Option "IDE" is renamed to "Format"
- Obsolete name of local variable "aWokStation" is replaced by equivalent "theFormat"

In environment scripts, additional variables are defined (derived from VCVER, see adm/vcver.bat):
- VCLIB defines name of the subdirectory specific to VS version; it is the same as VCVER except that for VCVER=vc141 VCLIB=vc14 and for VCVER=141-uwp VCLIB=vc14-uwp
- VCFMT is VCVER without optional suffix "-uwp"
- VCPROP is "NativeDesktop" for normal builds or "Universal" for UWP builds

Command genconf is amended to:
- Detect presence of VS 2017 (separately for desktop and UWP)
- Use only two first digits after "vc" in format specification for search of third-party libs
- Have more space in user interface for VS specification

All supported variants of VCVER variable are documented in dev guides / buiding / msvc

13 files changed:
adm/cmake/occt_macros.cmake
adm/genconf.tcl
adm/genconfdeps.tcl
adm/genproj.tcl
adm/templates/env.bat
adm/templates/msvc.bat
adm/vcver.bat [new file with mode: 0644]
dox/dev_guides/building/msvc.md
genconf.bat
genproj.bat
src/QANCollection/QANCollection_Stl.cxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_CmdParser.cxx

index 2385743..7c73c2c 100644 (file)
@@ -74,6 +74,11 @@ macro (OCCT_MAKE_COMPILER_SHORT_NAME)
       set (COMPILER vc12)
     elseif (MSVC14)
       set (COMPILER vc14)
+    elseif (MSVC15)
+      # Since Visual Studio 15 (2017), its version diverged from version of
+      # compiler which is 14.1; as that compiler uses the same run-time as 14.0,
+      # we keep its id as "vc14" to be compatibille
+      set (COMPILER vc14)
     endif()
   elseif (DEFINED CMAKE_COMPILER_IS_GNUCC)
     set (COMPILER gcc)
index 703928e..f7717ec 100644 (file)
@@ -38,39 +38,50 @@ set SYS_VS_LIST {}
 set SYS_VC_LIST {}
 set SYS_VCVARS_LIST {}
 
-# detect installed Visual Studio instances from global environment
-if { [info exists ::env(VS150COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 201x (vc15)"
-  lappend ::SYS_VC_LIST "vc15"
-  lappend ::SYS_VCVARS_LIST "%VS150COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
+# detect installed Visual Studio 2017 instances by running vswhere.exe
+if { ! [catch {exec vswhere.exe -version "\[15.0,15.99\]" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath} res] } {
+  lappend ::SYS_VS_LIST "Visual Studio 2017 (15, toolset v141)"
+  lappend ::SYS_VC_LIST "vc141"
+  lappend ::SYS_VCVARS_LIST "$res\\VC\\vcvarsall.bat"
+}
+if { ! [catch {exec vswhere.exe -version "\[15.0,15.99\]" -latest -requires Microsoft.VisualStudio.Workload.Universal -property installationPath} res] } {
+  lappend ::SYS_VS_LIST "Visual Studio 2017 (15, toolset v141) UWP"
+  lappend ::SYS_VC_LIST "vc141-uwp"
+  lappend ::SYS_VCVARS_LIST "$res\\VC\\vcvarsall.bat"
 }
+
+# detect installed Visual Studio instances from global environment
 if { [info exists ::env(VS140COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 2015 (vc14)"
+  lappend ::SYS_VS_LIST "Visual Studio 2015 (14, toolset v140)"
   lappend ::SYS_VC_LIST "vc14"
   lappend ::SYS_VCVARS_LIST "%VS140COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
+
+  lappend ::SYS_VS_LIST "Visual Studio 2015 (14, toolset v140) UWP"
+  lappend ::SYS_VC_LIST "vc14-uwp"
+  lappend ::SYS_VCVARS_LIST "%VS140COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
 }
 if { [info exists ::env(VS120COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 2013 (vc12)"
+  lappend ::SYS_VS_LIST "Visual Studio 2013 (12, toolset v120)"
   lappend ::SYS_VC_LIST "vc12"
   lappend ::SYS_VCVARS_LIST "%VS120COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
 }
 if { [info exists ::env(VS110COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 2012 (vc11)"
+  lappend ::SYS_VS_LIST "Visual Studio 2012 (11, toolset v110)"
   lappend ::SYS_VC_LIST "vc11"
   lappend ::SYS_VCVARS_LIST "%VS110COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
 }
 if { [info exists ::env(VS100COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 2010 (vc10)"
+  lappend ::SYS_VS_LIST "Visual Studio 2010 (10, toolset v100)"
   lappend ::SYS_VC_LIST "vc10"
   lappend ::SYS_VCVARS_LIST "%VS100COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
 }
 if { [info exists ::env(VS90COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 2008 (vc9)"
+  lappend ::SYS_VS_LIST "Visual Studio 2008 (9, toolset v90)"
   lappend ::SYS_VC_LIST "vc9"
   lappend ::SYS_VCVARS_LIST "%VS90COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
 }
 if { [info exists ::env(VS80COMNTOOLS)] } {
-  lappend ::SYS_VS_LIST "Visual Studio 2005 (vc8)"
+  lappend ::SYS_VS_LIST "Visual Studio 2005 (8, toolset v80)"
   lappend ::SYS_VC_LIST "vc8"
   lappend ::SYS_VCVARS_LIST "%VS80COMNTOOLS%..\\..\\VC\\vcvarsall.bat"
 }
@@ -129,10 +140,10 @@ proc wokdep:gui:UpdateList {} {
   wokdep:SearchX11       anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
   if { "$::HAVE_GLES2" == "true" } {
     if { "$::HAVE_GL2PS" == "true" } {
-      lappend anIncErrs "Error: gl2ps can not be used within OpenGL ES"
+      lappend anIncErrs "Error: gl2ps can not be used with OpenGL ES"
     }
     if { "$::HAVE_D3D" == "true" } {
-      lappend anIncErrs "Error: Direct3D can not be used within OpenGL ES"
+      lappend anIncErrs "Error: Direct3D can not be used with OpenGL ES"
     }
     wokdep:SearchEGL     anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
     wokdep:SearchGLES    anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
@@ -388,10 +399,10 @@ proc wokdep:gui:Show64Bitness { theRowIter } {
 }
 
 # Header
-ttk::label    .myFrame.myVsFrame.myVsLbl       -text "Visual Studio configuration:" -padding {5 5 80 5}
-ttk::combobox .myFrame.myVsFrame.myVsCombo     -values $SYS_VS_LIST -state readonly -textvariable VSVER -width 30
+ttk::label    .myFrame.myVsFrame.myVsLbl       -text "Visual Studio configuration:" -padding {5 5 20 5}
+ttk::combobox .myFrame.myVsFrame.myVsCombo     -values $SYS_VS_LIST -state readonly -textvariable VSVER -width 40
 ttk::combobox .myFrame.myVsFrame.myArchCombo   -values { {32} {64} } -textvariable ARCH -state readonly -width 6
-entry         .myFrame.myVcEntry     -textvariable VCVER  -width 6
+entry         .myFrame.myVcEntry     -textvariable VCVER  -width 10
 entry         .myFrame.myVcVarsEntry -textvariable VCVARS -width 70
 ttk::button   .myFrame.myVcBrowseBtn -text "Browse" -command wokdep:gui:BrowseVcVars
 ttk::label    .myFrame.myHxxChecks.myRelDebInfoLbl   -text "Release with Debug info"
index ae61a6f..7accc56 100644 (file)
@@ -204,9 +204,14 @@ proc wokdep:Preferred {theList theCmpl theArch} {
     return ""
   }
 
+  # keep only two first digits in "vc141"
+  if { ! [regexp {^vc[0-9][0-9]} $theCmpl aCmpl] } {
+    set aCmpl $theCmpl
+  }
+
   set aShortList {}
   foreach aPath $theList {
-    if { [string first "$theCmpl" "$aPath"] != "-1" } {
+    if { [string first "$aCmpl" "$aPath"] != "-1" } {
       lappend aShortList "$aPath"
     }
   }
@@ -589,6 +594,11 @@ proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64
   upvar $theErrBin32 anErrBin32
   upvar $theErrBin64 anErrBin64
 
+  # keep only two first digits in "vc141"
+  if { ! [regexp {^vc[0-9][0-9]} ${::VCVER} aVcLib] } {
+    set aVcLib ${::VCVER}
+  }
+
   set isFound "true"
   set aTbbHPath [wokdep:SearchHeader "tbb/scalable_allocator.h"]
   if { "$aTbbHPath"  == "" } {
@@ -609,8 +619,8 @@ proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64
 
     set aTbbLibPath [wokdep:SearchLib "tbb" "$anArchIter"]
     if { "$aTbbLibPath" == "" } {
-      set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] "$::VCVER" "$anArchIter" ]
-      set aTbbLibPath [wokdep:SearchLib "tbb" "$anArchIter" "$aPath/lib/$aSubDir/${::VCVER}"]
+      set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] $aVcLib "$anArchIter" ]
+      set aTbbLibPath [wokdep:SearchLib "tbb" "$anArchIter" "$aPath/lib/$aSubDir/$aVcLib"]
       if { "$aTbbLibPath" == "" } {
         # Set the path to the TBB library for Linux
         if { "$::tcl_platform(platform)" != "windows" } {
@@ -621,7 +631,7 @@ proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64
           lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/$aSubDir"
         }
       } else {
-        lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/$aSubDir/${::VCVER}"
+        lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/$aSubDir/$aVcLib"
       }
       if { "$aTbbLibPath" == "" } {
         lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}tbb.${::SYS_LIB_SUFFIX}' not found (Intel TBB)"
@@ -631,10 +641,10 @@ proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64
     if { "$::tcl_platform(platform)" == "windows" } {
       set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter"]
       if { "$aTbbDllPath" == "" } {
-        set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] "$::VCVER" "$anArchIter" ]
-        set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter" "$aPath/bin/$aSubDir/${::VCVER}"]
+        set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] $aVcLib "$anArchIter" ]
+        set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter" "$aPath/bin/$aSubDir/$aVcLib"]
         if { "$aTbbDllPath" != "" } {
-          lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin/$aSubDir/${::VCVER}"
+          lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin/$aSubDir/$aVcLib"
         } else {
           lappend anErrBin$anArchIter "Error: 'tbb.dll' not found (Intel TBB)"
           if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
index ef2f7e3..b8e8240 100644 (file)
@@ -255,16 +255,16 @@ proc genAllResources {} {
 }
 
 # Wrapper-function to generate VS project files
-proc genproj {theIDE args} {
-  set aSupportedIDEs { "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "vc14-uwp" "cbp" "xcd"}
-  set aSupportedPlatforms { "wnt" "lin" "mac" "ios" "qnx" }
+proc genproj {theFormat args} {
+  set aSupportedFormats { "vc7" "vc8" "vc9" "vc10" "vc11" "vc12" "vc14" "vc141" "cbp" "xcd"}
+  set aSupportedPlatforms { "wnt" "uwp" "lin" "mac" "ios" "qnx" }
   set isHelpRequire false
 
-  # check IDE argument
-  if { $theIDE == "-h" || $theIDE == "-help" || $theIDE == "--help" } {
+  # check format argument
+  if { $theFormat == "-h" || $theFormat == "-help" || $theFormat == "--help" } {
     set isHelpRequire true
-  } elseif { [lsearch -exact $aSupportedIDEs $theIDE] < 0 } {
-    puts "Error: genproj: unrecognized IDE \"$theIDE\""
+  } elseif { [lsearch -exact $aSupportedFormats $theFormat] < 0 } {
+    puts "Error: genproj: unrecognized project format \"$theFormat\""
     set isHelpRequire true
   }
 
@@ -272,9 +272,9 @@ proc genproj {theIDE args} {
   set aCmpl "gcc"
 
   # Determine default platform: wnt for vc*, mac for xcd, current for cbp
-  if { [regexp "^vc" $theIDE] } {
+  if { [regexp "^vc" $theFormat] } {
     set aPlatform "wnt"
-  } elseif { $theIDE == "xcd" || $::tcl_platform(os) == "Darwin" } {
+  } elseif { $theFormat == "xcd" || $::tcl_platform(os) == "Darwin" } {
     set aPlatform "mac"
   } elseif { $::tcl_platform(platform) == "windows" } {
     set aPlatform "wnt"
@@ -302,21 +302,22 @@ proc genproj {theIDE args} {
   }
 
   if {  $isHelpRequire == true } {
-    puts "usage: genproj IDE \[Platform\] \[-static\] \[-h|-help|--help\]
+    puts "usage: genproj Format \[Platform\] \[-static\] \[-h|-help|--help\]
 
-    IDE must be one of:
+    Format must be one of:
       vc8      -  Visual Studio 2005
       vc9      -  Visual Studio 2008
       vc10     -  Visual Studio 2010
       vc11     -  Visual Studio 2012
       vc12     -  Visual Studio 2013
       vc14     -  Visual Studio 2015
-      vc14-uwp -  Visual Studio 2015 for Universal Windows Platform project
+      vc141    -  Visual Studio 2017
       cbp      -  CodeBlocks
       xcd      -  XCode
 
-    Platform (optional, only for CodeBlocks and XCode):
-      wnt   -  Windows
+    Platform (optional):
+      wnt   -  Windows Desktop
+      uwp   -  Universal Windows Platform
       lin   -  Linux
       mac   -  OS X
       ios   -  iOS
@@ -332,24 +333,24 @@ proc genproj {theIDE args} {
     return
   }
 
-  puts "Preparing to generate $theIDE projects for $aPlatform platform..."
+  puts "Preparing to generate $theFormat projects for $aPlatform platform..."
 
-  # path to where to generate projects, hardcoded from current dir
+  # base path to where to generate projects, hardcoded from current dir
   set anAdmPath [file normalize "${::path}/adm"]
 
-  OS:MKPRC "$anAdmPath" "$theIDE" "$aLibType" "$aPlatform" "$aCmpl"
+  OS:MKPRC "$anAdmPath" "$theFormat" "$aLibType" "$aPlatform" "$aCmpl"
 
-  genprojbat "$theIDE" $aPlatform
+  genprojbat "$theFormat" "$aPlatform"
   genAllResources
 }
 
-proc genprojbat {theIDE thePlatform} {
+proc genprojbat {theFormat thePlatform} {
   set aTargetPlatformExt sh
-  if { $thePlatform == "wnt" } {
+  if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
     set aTargetPlatformExt bat
   }
 
-  if {"$theIDE" != "cmake"} {
+  if {"$theFormat" != "cmake"} {
     # copy env.bat/sh only if not yet present
     if { ! [file exists "$::path/env.${aTargetPlatformExt}"] } {
       set anEnvTmplFile [open "$::THE_CASROOT/adm/templates/env.${aTargetPlatformExt}" "r"]
@@ -371,10 +372,10 @@ proc genprojbat {theIDE thePlatform} {
     file copy -force -- "$::THE_CASROOT/adm/templates/draw.${aTargetPlatformExt}" "$::path/draw.${aTargetPlatformExt}"
   }
 
-  if {[regexp {(vc)[0-9]*$} $theIDE] == 1 || [regexp {(vc)[0-9]*-uwp$} $theIDE] == 1} {
+  if { [regexp {^vc} $theFormat] } {
     file copy -force -- "$::THE_CASROOT/adm/templates/msvc.bat" "$::path/msvc.bat"
   } else {
-    switch -exact -- "$theIDE" {
+    switch -exact -- "$theFormat" {
       "cbp"   {
         file copy -force -- "$::THE_CASROOT/adm/templates/codeblocks.sh"  "$::path/codeblocks.sh"
         file copy -force -- "$::THE_CASROOT/adm/templates/codeblocks.bat" "$::path/codeblocks.bat"
@@ -399,13 +400,13 @@ proc removeAllOccurrencesOf { theObject theList } {
 set aTKNullKey "TKNull"
 set THE_GUIDS_LIST($aTKNullKey) "{00000000-0000-0000-0000-000000000000}"
 
-# Entry function to generate project files and solutions for IDE
+# Entry function to generate project files
 # @param theOutDir   Root directory for project files
-# @param theIDE      IDE code name (vc10 for Visual Studio 2010, cbp for Code::Blocks, xcd for XCode)
+# @param theFormat   Project format name (vc.. for Visual Studio projects, cbp for Code::Blocks, xcd for XCode)
 # @param theLibType  Library type - dynamic or static
 # @param thePlatform Optional target platform for cross-compiling, e.g. ios for iOS
 # @param theCmpl     Compiler option (msvc or gcc)
-proc OS:MKPRC { theOutDir theIDE theLibType thePlatform theCmpl } {
+proc OS:MKPRC { theOutDir theFormat theLibType thePlatform theCmpl } {
   global path
   set anOutRoot $theOutDir
   if { $anOutRoot == "" } {
@@ -414,14 +415,19 @@ proc OS:MKPRC { theOutDir theIDE theLibType thePlatform theCmpl } {
 
   # Create output directory
   set aWokStation "$thePlatform"
-  if { [lsearch -exact {vc7 vc8 vc9 vc10 vc11 vc12 vc14 vc14-uwp} $theIDE] != -1 } {
+  if { [regexp {^vc} $theFormat] } {
     set aWokStation "msvc"
   }
-
-  set anOutDir "${anOutRoot}/${aWokStation}/${theIDE}"
+  set aSuffix ""
+  set isUWP 0
+  if { $thePlatform == "uwp" } {
+    set aSuffix "-uwp"
+    set isUWP 1
+  }
+  set anOutDir "${anOutRoot}/${aWokStation}/${theFormat}${aSuffix}"
 
   # read map of already generated GUIDs
-  set aGuidsFilePath [file join $anOutDir "wok_${theIDE}_guids.txt"]
+  set aGuidsFilePath [file join $anOutDir "wok_${theFormat}_guids.txt"]
   if [file exists "$aGuidsFilePath"] {
     set aFileIn [open "$aGuidsFilePath" r]
     set aFileDataRaw [read $aFileIn]
@@ -443,7 +449,7 @@ proc OS:MKPRC { theOutDir theIDE theLibType thePlatform theCmpl } {
   }
 
   # Draw module is turned off due to it is not supported on UWP
-  if { [regexp {(vc)[0-9]*-uwp$} $theIDE] == 1 } {
+  if { $isUWP } {
     set aDrawIndex [lsearch -exact ${aModules} "Draw"]
     if { ${aDrawIndex} != -1 } {
       set aModules [lreplace ${aModules} ${aDrawIndex} ${aDrawIndex}]
@@ -469,8 +475,8 @@ proc OS:MKPRC { theOutDir theIDE theLibType thePlatform theCmpl } {
   puts "Collecting required header files into $path/inc ..."
   osutils:collectinc $aModules $path/inc
 
-  # Generating project files for the selected IDE
-  switch -exact -- "$theIDE" {
+  # Generating project files for the selected format
+  switch -exact -- "$theFormat" {
     "vc7"   -
     "vc8"   -
     "vc9"   -
@@ -478,7 +484,7 @@ proc OS:MKPRC { theOutDir theIDE theLibType thePlatform theCmpl } {
     "vc11"  -
     "vc12"  -
     "vc14"  -
-    "vc14-uwp" { OS:MKVC  $anOutDir $aModules $anAllSolution $theIDE }
+    "vc141"    { OS:MKVC  $anOutDir $aModules $anAllSolution $theFormat $isUWP}
     "cbp"      { OS:MKCBP $anOutDir $aModules $anAllSolution $thePlatform $theCmpl }
     "xcd"      {
       set ::THE_GUIDS_LIST($::aTKNullKey) "000000000000000000000000"
@@ -497,14 +503,14 @@ proc OS:MKPRC { theOutDir theIDE theLibType thePlatform theCmpl } {
 }
 
 # Function to generate Visual Studio solution and project files
-proc OS:MKVC { theOutDir {theModules {}} {theAllSolution ""} {theVcVer "vc8"} } {
+proc OS:MKVC { theOutDir theModules theAllSolution theVcVer isUWP } {
 
   puts stderr "Generating VS project files for $theVcVer"
 
   # generate projects for toolkits and separate solution for each module
   foreach aModule $theModules {
     OS:vcsolution $theVcVer $aModule $aModule $theOutDir ::THE_GUIDS_LIST
-    OS:vcproj     $theVcVer $aModule          $theOutDir ::THE_GUIDS_LIST
+    OS:vcproj     $theVcVer $isUWP   $aModule $theOutDir ::THE_GUIDS_LIST
   }
 
   # generate single solution "OCCT" containing projects from all modules
@@ -749,8 +755,8 @@ proc LocateRecur {theName} {
   return ""
 }
 
-proc OS:genGUID { {theIDE "vc"} } {
-  if { "$theIDE" == "vc" } {
+proc OS:genGUID { {theFormat "vc"} } {
+  if { "$theFormat" == "vc" } {
     set p1 "[format %07X [expr { int(rand() * 268435456) }]][format %X [expr { int(rand() * 16) }]]"
     set p2 "[format %04X [expr { int(rand() * 6536) }]]"
     set p3 "[format %04X [expr { int(rand() * 6536) }]]"
@@ -931,9 +937,9 @@ proc osutils:vcsolution:header { vcversion } {
       "# Visual Studio 2012\n"
   } elseif { "$vcversion" == "vc12" } {
     append var \
-      "Microsoft Visual Studio Solution File, Format Version 13.00\n" \
+      "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
       "# Visual Studio 2013\n"
-  } elseif { "$vcversion" == "vc14"  || "$vcversion" == "vc14-uwp"} {
+  } elseif { "$vcversion" == "vc14"  || "$vcversion" == "vc141"} {
     append var \
       "Microsoft Visual Studio Solution File, Format Version 12.00\n" \
       "# Visual Studio 14\n"
@@ -1142,36 +1148,42 @@ proc OS:vcsolution { theVcVer theSolName theModules theOutDir theGuidsMap } {
 }
 # Generate Visual Studio projects for specified version
 
-proc OS:vcproj { theVcVer theModules theOutDir theGuidsMap } {
+proc OS:vcproj { theVcVer isUWP theModules theOutDir theGuidsMap } {
   upvar $theGuidsMap aGuidsMap
 
   set aProjectFiles {}
 
   foreach aModule $theModules {
     foreach aToolKit [${aModule}:toolkits] {
-      lappend aProjectFiles [osutils:vcproj  $theVcVer $theOutDir $aToolKit     aGuidsMap]
+      lappend aProjectFiles [osutils:vcproj  $theVcVer $isUWP $theOutDir $aToolKit     aGuidsMap]
     }
     foreach anExecutable [OS:executable ${aModule}] {
-      lappend aProjectFiles [osutils:vcprojx $theVcVer $theOutDir $anExecutable aGuidsMap]
+      lappend aProjectFiles [osutils:vcprojx $theVcVer $isUWP $theOutDir $anExecutable aGuidsMap]
     }
   }
   return $aProjectFiles
 }
 # generate template name and load it for given version of Visual Studio and platform
 
-proc osutils:vcproj:readtemplate {theVcVer isexec} {
+proc osutils:vcproj:readtemplate {theVcVer isUWP isExec} {
   set anExt $theVcVer
   if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
     set anExt vc10
   }
 
+  # determine versions of runtime and toolset
+  set aVCRTVer $theVcVer 
+  set aToolset "v[string range $theVcVer 2 3]0"
+  if { $theVcVer == "vc141" } {
+    set aVCRTVer "vc14"
+    set aToolset "v141"
+  }
+
   set what "$theVcVer"
-  set aVerExt [string range $theVcVer 2 end]
-  set aVerExt "v${aVerExt}0"
   set aCmpl32 ""
   set aCmpl64 ""
   set aCharSet "Unicode"
-  if { $isexec } {
+  if { $isExec } {
     set anExt "${anExt}x"
     set what "$what executable"
   }
@@ -1181,8 +1193,7 @@ proc osutils:vcproj:readtemplate {theVcVer isexec} {
   }
   set aTmpl [osutils:readtemplate $anExt "MS VC++ project ($what)"]
 
-  if { $theVcVer == "vc14-uwp" } {
-    set aVerExt "v140"
+  if { $isUWP } {
     set UwpWinRt "<CompileAsWinRT>false</CompileAsWinRT>"
     foreach bitness {32 64} {
       set indent ""
@@ -1209,8 +1220,8 @@ proc osutils:vcproj:readtemplate {theVcVer isexec} {
     set aReleaseLnk "\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>"
   }
 
-  regsub -all -- {__VCVER__}     $aTmpl $theVcVer aTmpl
-  regsub -all -- {__VCVEREXT__}  $aTmpl $aVerExt  aTmpl
+  regsub -all -- {__VCVER__}     $aTmpl $aVCRTVer aTmpl
+  regsub -all -- {__VCVEREXT__}  $aTmpl $aToolset aTmpl
   regsub -all -- {__VCCHARSET__} $aTmpl $aCharSet aTmpl
   regsub -all -- {__VCReleasePDB__} $aTmpl $aDebugInfo aTmpl
   regsub -all -- "${format_template}__VCLNKREL__" $aTmpl "${aReleaseLnk}" aTmpl
@@ -1528,7 +1539,7 @@ proc wokUtils:FILES:wtail { f n } {
 }
 
 # Generate entry for one source file in Visual Studio 10 project file
-proc osutils:vcxproj:file { vcversion file params } {
+proc osutils:vcxproj:file { file params } {
   append text "    <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
   if { $params != "" } {
     append text "      <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}]  %(AdditionalOptions)</AdditionalOptions>\n"
@@ -1654,8 +1665,8 @@ proc osutils:readtemplate:rc {theOutDir theToolKit} {
 }
 
 # Generate Visual Studio project file for ToolKit
-proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
-  if { $theProjTmpl == {} } {set theProjTmpl [osutils:vcproj:readtemplate $theVcVer 0]}
+proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
+  set theProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 0]
 
   set l_compilable [osutils:compilable wnt]
   regsub -all -- {__TKNAM__} $theProjTmpl $theToolKit theProjTmpl
@@ -1666,11 +1677,11 @@ proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {}
   }
   regsub -all -- {__PROJECT_GUID__} $theProjTmpl $aGuidsMap($theToolKit) theProjTmpl
 
-  set theProjTmpl [osutils:uwp:proj ${theVcVer} ${theProjTmpl}]
+  set theProjTmpl [osutils:uwp:proj $isUWP ${theProjTmpl}]
 
   set aUsedLibs [list]
 
-  if { "$theVcVer" == "vc14-uwp" } {
+  if { $isUWP } {
     lappend aUsedLibs "WindowsApp.lib"
   }
 
@@ -1685,7 +1696,8 @@ proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {}
 
   # correct names of referred third-party libraries that are named with suffix
   # depending on VC version
-  regsub -all -- {vc[0-9]+} $aUsedLibs $theVcVer aUsedLibs
+  set aVCRTVer [string range $theVcVer 0 3]
+  regsub -all -- {vc[0-9]+} $aUsedLibs $aVCRTVer aUsedLibs
 
   # and put this list to project file
   #puts "$theToolKit requires  $aUsedLibs"
@@ -1739,7 +1751,7 @@ proc osutils:vcproj { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {}
       foreach aSrcFile [lsort $aSrcFiles] {
         if { ![info exists written([file tail $aSrcFile])] } {
           set written([file tail $aSrcFile]) 1
-          append aFilesSection [osutils:vcxproj:file $theVcVer $aSrcFile $needparam]
+          append aFilesSection [osutils:vcxproj:file $aSrcFile $needparam]
         } else {
           puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
         }
@@ -1858,14 +1870,11 @@ proc osutils:tk:files { tkloc thePlatform } {
 }
 
 # Generate Visual Studio project file for executable
-proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {} } } {
+proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
   set aVcFiles {}
   foreach f [osutils:tk:files $theToolKit wnt] {
-    if { $theProjTmpl == {} } {
-      set aProjTmpl [osutils:vcproj:readtemplate $theVcVer 1]
-    } else {
-      set aProjTmpl $theProjTmpl
-    }
+    set aProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 1]
+
     set aProjName [file rootname [file tail $f]]
     set l_compilable [osutils:compilable wnt]
     regsub -all -- {__XQTNAM__} $aProjTmpl $aProjName aProjTmpl
@@ -1888,7 +1897,8 @@ proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {}
 
     # correct names of referred third-party libraries that are named with suffix
     # depending on VC version
-    regsub -all -- {vc[0-9]+} $aUsedLibs $theVcVer aUsedLibs
+    set aVCRTVer [string range $theVcVer 0 3]
+    regsub -all -- {vc[0-9]+} $aUsedLibs $aVCRTVer aUsedLibs
 
 #    puts "$aProjName requires  $aUsedLibs"
     if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
@@ -1903,7 +1913,7 @@ proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {}
       set written([file tail $f]) 1
 
       if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
-        append aFilesSection [osutils:vcxproj:file $theVcVer $f ""]
+        append aFilesSection [osutils:vcxproj:file $f ""]
         if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
         lappend aVcFilesX($theToolKit) $f
       } else {
@@ -1948,7 +1958,7 @@ proc osutils:vcprojx { theVcVer theOutDir theToolKit theGuidsMap {theProjTmpl {}
       set aCommonSettingsFileTmpl [wokUtils:FILES:FileToString "$::THE_CASROOT/adm/templates/vcxproj.user.vc10x"]
     }
     if { "$aCommonSettingsFileTmpl" != "" } {
-      regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $theVcVer aCommonSettingsFileTmpl
+      regsub -all -- {__VCVER__} $aCommonSettingsFileTmpl $aVCRTVer aCommonSettingsFileTmpl
 
       set aFile [open [set aVcFilePath "$aCommonSettingsFile"] w]
       fconfigure $aFile -translation crlf
@@ -2113,7 +2123,7 @@ proc osutils:cbptk { theCmpl theOutDir theToolKit thePlatform} {
     set listloc $theToolKit
   }
 
-  if { $thePlatform == "wnt" } {
+  if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
     set resultloc [osutils:justwnt  $listloc]
   } else {
     set resultloc [osutils:justunix $listloc]
@@ -2132,7 +2142,7 @@ proc osutils:cbptk { theCmpl theOutDir theToolKit thePlatform} {
     }
 
     # macros for correct DLL exports
-    if { $thePlatform == "wnt" } {
+    if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
       lappend aTKDefines "__${xlo}_DLL"
     }
   }
@@ -2251,7 +2261,7 @@ proc osutils:cbpx { theCmpl theOutDir theToolKit thePlatform } {
     }
 
     # macros for correct DLL exports
-    if { $thePlatform == "wnt" } {
+    if { $thePlatform == "wnt" || $thePlatform == "uwp" } {
       lappend aTKDefines "__${theToolKit}_DLL"
     }
 
@@ -2275,7 +2285,6 @@ proc osutils:cbpx { theCmpl theOutDir theToolKit thePlatform } {
 # @param theDefines    - compiler macro definitions
 # @param theIsExe      - flag to indicate executable / library target
 proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibsList theFrameworks theIncPaths theDefines {theIsExe "false"} } {
-  set aWokStation $thePlatform
   set aWokArch    "$::env(ARCH)"
 
   set aCmplCbp "gcc"
@@ -2284,7 +2293,7 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
   set aCmplFlagsDebug   [list]
   set toPassArgsByFile 0
   set aLibPrefix "lib"
-  if { "$aWokStation" == "wnt" || "$aWokStation" == "qnx" } {
+  if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" || "$thePlatform" == "qnx" } {
     set toPassArgsByFile 1
   }
   if { "$theCmpl" == "msvc" } {
@@ -2299,12 +2308,12 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
     lappend aCmplFlags    "-D_CRT_SECURE_NO_WARNINGS"
     lappend aCmplFlags    "-D_CRT_NONSTDC_NO_DEPRECATE"
   } elseif { "$theCmpl" == "gcc" } {
-    if { "$aWokStation" != "qnx" } {
+    if { "$thePlatform" != "qnx" } {
       set aCmplFlags      "-mmmx -msse -msse2 -mfpmath=sse"
     }
     set aCmplFlagsRelease "-O2"
     set aCmplFlagsDebug   "-O0 -g"
-    if { "$aWokStation" == "wnt" } {
+    if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
       lappend aCmplFlags "-std=gnu++0x"
       lappend aCmplFlags "-D_WIN32_WINNT=0x0501"
     } else {
@@ -2318,7 +2327,7 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
   lappend aCmplFlagsRelease "-DNDEBUG"
   lappend aCmplFlagsRelease "-DNo_Exception"
   lappend aCmplFlagsDebug   "-D_DEBUG"
-  if { "$aWokStation" == "qnx" } {
+  if { "$thePlatform" == "qnx" } {
     lappend aCmplFlags "-D_QNX_SOURCE"
   }
 
@@ -2340,20 +2349,20 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
   # Release target configuration
   puts $aFile "\t\t\t<Target title=\"Release\">"
   if { "$theIsExe" == "true" } {
-    puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
+    puts $aFile "\t\t\t\t<Option output=\"../../../${thePlatform}/cbp/bin/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
     puts $aFile "\t\t\t\t<Option type=\"1\" />"
   } else {
-    if { "$aWokStation" == "wnt" } {
-      puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bin/${aLibPrefix}${theProjName}\" imp_lib=\"../../../${aWokStation}/cbp/lib/\$(TARGET_OUTPUT_BASENAME)\" prefix_auto=\"1\" extension_auto=\"1\" />"
+    if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
+      puts $aFile "\t\t\t\t<Option output=\"../../../${thePlatform}/cbp/bin/${aLibPrefix}${theProjName}\" imp_lib=\"../../../${thePlatform}/cbp/lib/\$(TARGET_OUTPUT_BASENAME)\" prefix_auto=\"1\" extension_auto=\"1\" />"
     } else {
-      puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/lib/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
+      puts $aFile "\t\t\t\t<Option output=\"../../../${thePlatform}/cbp/lib/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
     }
     puts $aFile "\t\t\t\t<Option type=\"3\" />"
   }
-  puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/obj\" />"
+  puts $aFile "\t\t\t\t<Option object_output=\"../../../${thePlatform}/cbp/obj\" />"
   puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
   puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
-  if { "$aWokStation" == "wnt" } {
+  if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
     puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
   } else {
     puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
@@ -2373,15 +2382,15 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
   if { $toPassArgsByFile == 1 } {
     puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkFileName\" />"
   }
-  puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/lib\" />"
-  if { "$aWokStation" == "mac" } {
+  puts $aFile "\t\t\t\t\t<Add directory=\"../../../${thePlatform}/cbp/lib\" />"
+  if { "$thePlatform" == "mac" } {
     if { [ lsearch $theLibsList X11 ] >= 0} {
       puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
     }
   }
   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch})\" />"
-  if { "$aWokStation" == "lin" } {
-    puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aWokStation}/cbp/lib\" />"
+  if { "$thePlatform" == "lin" } {
+    puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${thePlatform}/cbp/lib\" />"
   }
   puts $aFile "\t\t\t\t</Linker>"
 
@@ -2390,20 +2399,20 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
   # Debug target configuration
   puts $aFile "\t\t\t<Target title=\"Debug\">"
   if { "$theIsExe" == "true" } {
-    puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
+    puts $aFile "\t\t\t\t<Option output=\"../../../${thePlatform}/cbp/bind/${theProjName}\" prefix_auto=\"0\" extension_auto=\"0\" />"
     puts $aFile "\t\t\t\t<Option type=\"1\" />"
   } else {
-    if { "$aWokStation" == "wnt" } {
-      puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/bind/${aLibPrefix}${theProjName}\" imp_lib=\"../../../${aWokStation}/cbp/libd/\$(TARGET_OUTPUT_BASENAME)\" prefix_auto=\"1\" extension_auto=\"1\" />"
+    if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
+      puts $aFile "\t\t\t\t<Option output=\"../../../${thePlatform}/cbp/bind/${aLibPrefix}${theProjName}\" imp_lib=\"../../../${thePlatform}/cbp/libd/\$(TARGET_OUTPUT_BASENAME)\" prefix_auto=\"1\" extension_auto=\"1\" />"
     } else {
-      puts $aFile "\t\t\t\t<Option output=\"../../../${aWokStation}/cbp/libd/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
+      puts $aFile "\t\t\t\t<Option output=\"../../../${thePlatform}/cbp/libd/lib${theProjName}.so\" prefix_auto=\"0\" extension_auto=\"0\" />"
     }
     puts $aFile "\t\t\t\t<Option type=\"3\" />"
   }
-  puts $aFile "\t\t\t\t<Option object_output=\"../../../${aWokStation}/cbp/objd\" />"
+  puts $aFile "\t\t\t\t<Option object_output=\"../../../${thePlatform}/cbp/objd\" />"
   puts $aFile "\t\t\t\t<Option compiler=\"$aCmplCbp\" />"
   puts $aFile "\t\t\t\t<Option createDefFile=\"0\" />"
-  if { "$aWokStation" == "wnt" } {
+  if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
     puts $aFile "\t\t\t\t<Option createStaticLib=\"1\" />"
   } else {
     puts $aFile "\t\t\t\t<Option createStaticLib=\"0\" />"
@@ -2423,15 +2432,15 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
   if { $toPassArgsByFile == 1 } {
     puts $aFile "\t\t\t\t\t<Add option=\"\@$aLnkDebFileName\" />"
   }
-  puts $aFile "\t\t\t\t\t<Add directory=\"../../../${aWokStation}/cbp/libd\" />"
-  if { "$aWokStation" == "mac" } {
+  puts $aFile "\t\t\t\t\t<Add directory=\"../../../${thePlatform}/cbp/libd\" />"
+  if { "$thePlatform" == "mac" } {
     if { [ lsearch $theLibsList X11 ] >= 0} {
       puts $aFile "\t\t\t\t\t<Add directory=\"/usr/X11/lib\" />"
     }
   }
   puts $aFile "\t\t\t\t\t<Add option=\"\$(CSF_OPT_LNK${aWokArch}D)\" />"
-  if { "$aWokStation" == "lin" } {
-    puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${aWokStation}/cbp/libd\" />"
+  if { "$thePlatform" == "lin" } {
+    puts $aFile "\t\t\t\t\t<Add option=\"-Wl,-rpath-link=../../../${thePlatform}/cbp/libd\" />"
   }
   puts $aFile "\t\t\t\t</Linker>"
 
@@ -2452,7 +2461,7 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
 
   # COMMON linker options
   puts $aFile "\t\t<Linker>"
-  if { "$aWokStation" == "wnt" && "$theCmpl" == "gcc" } {
+  if { "$thePlatform" == "wnt" && "$theCmpl" == "gcc" } {
     puts $aFile "\t\t\t<Add option=\"-Wl,--export-all-symbols\" />"
   }
   foreach aFrameworkName $theFrameworks {
@@ -2498,8 +2507,8 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
       puts $aFile "\t\t\t<Option link=\"0\" />"
       puts $aFile "\t\t</Unit>"
 
-      set aFileObj  [string map {.cxx .o} [string map [list "/src/" "/$aWokStation/cbp/obj/src/"]  $aSrcFile]]
-      set aFileObjd [string map {.cxx .o} [string map [list "/src/" "/$aWokStation/cbp/objd/src/"] $aSrcFile]]
+      set aFileObj  [string map {.cxx .o} [string map [list "/src/" "/$thePlatform/cbp/obj/src/"]  $aSrcFile]]
+      set aFileObjd [string map {.cxx .o} [string map [list "/src/" "/$thePlatform/cbp/objd/src/"] $aSrcFile]]
       puts -nonewline $aFileLnkObj  "$aFileObj "
       puts -nonewline $aFileLnkObjd "$aFileObjd "
     } else {
@@ -2508,7 +2517,7 @@ proc osutils:cbp { theCmpl theOutDir theProjName thePlatform theSrcFiles theLibs
     }
   }
 
-  if { "$aWokStation" == "wnt" } {
+  if { "$thePlatform" == "wnt" || "$thePlatform" == "uwp" } {
     close $aFileLnkObj
     close $aFileLnkObjd
   }
@@ -3326,7 +3335,7 @@ proc osutils:sdk { theSdkMajorVer {isQuietMode false} {theSdkDirectories {}} } {
 }
 
 # Generate global properties to Visual Studio project file for UWP solution
-proc osutils:uwp:proj { theVcVer theProjTmpl } {
+proc osutils:uwp:proj { isUWP theProjTmpl } {
 
   set uwp_properties ""
   set uwp_generate_metadata ""
@@ -3334,7 +3343,7 @@ proc osutils:uwp:proj { theVcVer theProjTmpl } {
 
   set format_template ""
 
-  if { ${theVcVer} == "vc14-uwp" } {
+  if { $isUWP } {
     set sdk_versions [osutils:sdk 10]
     set sdk_max_ver [lindex ${sdk_versions} end]
 
index ac7a4a6..dfc842a 100644 (file)
@@ -49,6 +49,9 @@ if /I ["%3"]     == ["d"]     set "CASDEB=d"
 if /I ["%3"]     == ["i"]     set "CASDEB=i"
 if /I ["%3"]     == ["relwithdeb"] set "CASDEB=i"
 
+rem Decode VCVER
+call "%~dp0adm\vcver.bat"
+
 set "CSF_OPT_LIB32D=%CSF_OPT_LIB32%"
 set "CSF_OPT_LIB64D=%CSF_OPT_LIB64%"
 set "CSF_OPT_BIN32D=%CSF_OPT_BIN32%"
@@ -111,8 +114,8 @@ if "%CSF_OCCTResourcePath%" == "" set "CSF_OCCTResourcePath=%CASROOT%\src"
 if "%CSF_OCCTSamplesPath%" == "" set "CSF_OCCTSamplesPath=%CASROOT%\samples"
 if "%CSF_OCCTDataPath%" == "" set "CSF_OCCTDataPath=%CASROOT%\data"
 if "%CSF_OCCTTestsPath%" == "" set "CSF_OCCTTestsPath=%CASROOT%\tests"
-if "%CSF_OCCTBinPath%" == "" set "CSF_OCCTBinPath=%CASROOT%\win%ARCH%\%VCVER%\bin%CASDEB%"
-if "%CSF_OCCTLibPath%" == "" set "CSF_OCCTLibPath=%CASROOT%\win%ARCH%\%VCVER%\lib%CASDEB%"
+if "%CSF_OCCTBinPath%" == "" set "CSF_OCCTBinPath=%CASROOT%\win%ARCH%\%VCLIB%\bin%CASDEB%"
+if "%CSF_OCCTLibPath%" == "" set "CSF_OCCTLibPath=%CASROOT%\win%ARCH%\%VCLIB%\lib%CASDEB%"
 
 rem ----- Set path to 3rd party and OCCT libraries -----
 set "PATH=%CSF_OCCTBinPath%;%PATH%"
index c2fa75b..72f4360 100644 (file)
@@ -12,24 +12,28 @@ if not "%4" == "" (
 
 set "VisualStudioExpressName=VCExpress"
 
-if /I "%VCVER%" == "vc8" (
+if not "%DevEnvDir%" == "" (
+  rem If DevEnvDir is already defined (e.g. in custom.bat), use that value
+) else if /I "%VCFMT%" == "vc8" (
   set "DevEnvDir=%VS80COMNTOOLS%..\IDE"
-) else if /I "%VCVER%" == "vc9" (
+) else if /I "%VCFMT%" == "vc9" (
   set "DevEnvDir=%VS90COMNTOOLS%..\IDE"
-) else if /I "%VCVER%" == "vc10" (
+) else if /I "%VCFMT%" == "vc10" (
   set "DevEnvDir=%VS100COMNTOOLS%..\IDE"
-) else if /I "%VCVER%" == "vc11" (
+) else if /I "%VCFMT%" == "vc11" (
   set "DevEnvDir=%VS110COMNTOOLS%..\IDE"
   rem Visual Studio Express starting from VS 2012 is called "for Windows Desktop"
   rem and has a new name for executable - WDExpress
   set "VisualStudioExpressName=WDExpress"
-) else if /I "%VCVER%" == "vc12" (
+) else if /I "%VCFMT%" == "vc12" (
   set "DevEnvDir=%VS120COMNTOOLS%..\IDE"
   set "VisualStudioExpressName=WDExpress"
-) else if /I "%VCVER%" == "vc14" (
-  set "DevEnvDir=%VS140COMNTOOLS%..\IDE"
-) else if /I "%VCVER%" == "vc14-uwp" (
+) else if /I "%VCFMT%" == "vc14" (
   set "DevEnvDir=%VS140COMNTOOLS%..\IDE"
+) else if /I "%VCFMT%" == "vc141" (
+  for /f "usebackq delims=" %%i in (`vswhere.exe -version "[15.0,15.99]" -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
+    set DevEnvDir=%%i\Common7\IDE
+  )
 ) else (
   echo Error: wrong VS identifier
   exit /B
@@ -42,5 +46,5 @@ if exist "%DevEnvDir%\devenv.exe"  (
   start "" "%DevEnvDir%\%VisualStudioExpressName%.exe" "%PRJFILE%"
 ) else (
   echo Error: Could not find MS Visual Studio ^(%VCVER%^)
-  echo Check relevant environment variable ^(e.g. VS80COMNTOOLS for vc8^)
+  echo For VS 2010-2015, check relevant environment variable ^(e.g. VS100COMNTOOLS^)
 )
diff --git a/adm/vcver.bat b/adm/vcver.bat
new file mode 100644 (file)
index 0000000..61ca6e6
--- /dev/null
@@ -0,0 +1,30 @@
+@echo off
+rem Decode VCVER variable and define related ones:
+rem
+rem VCFMT - "vc" followed by full version number of Visual Studio toolset
+rem         (same as VCVER without optional suffix "-uwp")
+rem VCLIB - name of folder contining binaries
+rem         (same as VCVER except without third version in number)
+rem VCPROP - name of required Visual Studion Workload (starting with VS 2017)
+rem
+rem Note that for VS before 2015 (vc14) always
+rem VCFMT=VCLIB=VCVER and VCPROP=NativeDesktop
+
+rem Since VS 2017, environment variables like VS100COMNTOOLS are not defined 
+rem any more, we can only use vswhere.exe tool to find Visual Studio.
+rem Add path to vswhere.exe
+set "PATH=%PATH%;%ProgramFiles(x86)%\Microsoft Visual Studio\Installer"
+
+rem for vc10-12, interpretation is trivial
+set VCFMT=%VCVER%
+set VCLIB=%VCVER:~0,4%
+set VCPROP=NativeDesktop
+
+rem vc14 and later can have optional suffix "-uwp"
+if "%VCVER:~-4%" == "-uwp" (
+  set VCFMT=%VCVER:~0,-4%
+  set VCLIB=%VCLIB%-uwp
+  set VCPROP=Universal
+)
+
+rem echo VCVER=%VCVER% VCFMT=%VCFMT% VCLIB=%VCLIB% VCPROP=%VCPROP%
index ac5bde6..397d259 100644 (file)
@@ -26,7 +26,18 @@ You can also build third-party libraries from their sources, see @ref occt_dev_g
 
 If you have Visual Studio projects already available (pre-installed or generated), you can edit file *custom.bat* manually to adjust the environment:
 
-* *VCVER* -- version of Visual Studio (vc10, vc11, vc12, or vc14), and relevant *VCVARS* path
+* *VCVER* -- specification of format of project files, defining also version of Visual Studio to be used, and default name of the sub-folder for binaries:
+
+| VCVER     | Visual Studio version | Windows Platform                 | Binaries folder name |
+|-----------|-----------------------|----------------------------------|----------------------|
+| vc10      | 2010 (10)             | Desktop (Windows API)            | vc10 |
+| vc11      | 2012 (11)             | Desktop (Windows API)            | vc11 |
+| vc12      | 2013 (12)             | Desktop (Windows API)            | vc12 |
+| vc14      | 2015 (14)             | Desktop (Windows API)            | vc14 |
+| vc14-uwp  | 2015 (14)             | UWP (Universal Windows Platform) | vc14-uwp |
+| vc141     | 2017 (15)             | Desktop (Windows API)            | vc14 |
+| vc141-uwp | 2017 (15)             | UWP (Universal Windows Platform) | vc14-uwp |
+
 * *ARCH* -- architecture (32 or 64), affects only *PATH* variable for execution
 * <i>HAVE_*</i> -- flags to enable or disable use of optional third-party products
 * <i>CSF_OPT_*</i> -- paths to search for includes and binaries of all used  third-party products
index ab7b6d6..b6a0e7a 100644 (file)
@@ -6,11 +6,10 @@ rem Running it requires that Tcl should be in the PATH
 SET "OLD_PATH=%PATH%"
 
 rem create env.bat if it does not exist yet
-if exist "%~dp0env.bat" (
-  call "%~dp0env.bat"
-) else (
+if not exist "%~dp0env.bat" (
   type "%~dp0adm\templates\env.bat" | findstr /i /v "__CASROOT__" > "%~dp0env.bat"
 )
+call "%~dp0env.bat"
 
 rem  find Tcl
 set "TCL_EXEC=tclsh.exe"
@@ -53,7 +52,7 @@ if not defined TCL_FOUND (
   goto :eof
 ) 
 
-:: run GUI tool
+rem run GUI tool
 "%TCL_FOUND%" %~dp0adm/genconf.tcl
 
 SET "PATH=%OLD_PATH%"
index aa4296a..1e25640 100644 (file)
@@ -2,9 +2,9 @@
 
 rem Helper script to run generation of VS projects on Windows.
 rem Running it requires that Tcl should be in the PATH
-rem Optional arguments: IDE OS
-rem IDE can be vc10, vc11, vc12, vc14, cbp, or xcd
-rem OS can be wnt, mac, or lin
+rem Optional arguments: Format OS
+rem Format can be vc10, vc11, vc12, vc14, vc141, cbp, or xcd
+rem OS can be wnt, uwp, mac, or lin
 
 SET "OLD_PATH=%PATH%"
 
@@ -41,6 +41,14 @@ if not defined TCL_FOUND (
   goto :eof
 ) 
 
+set aPlatform=%2
+if "%aPlatform%" == "" (
+  set aPlatform=wnt
+  if "%VCPROP%" == "Universal" (
+    set aPlatform=uwp
+  )
+)
+
 cd %~dp0
-%TCL_EXEC% %~dp0adm/start.tcl genproj %VCVER% %2 %3 %4 %5
+%TCL_EXEC% %~dp0adm/start.tcl genproj %VCFMT% %aPlatform% %3 %4 %5
 SET "PATH=%OLD_PATH%"
index a2af124..c40c421 100644 (file)
@@ -32,6 +32,7 @@
 #include <Standard_Assert.hxx>
 #include <OSD_Timer.hxx>
 #include <OSD_Parallel.hxx>
+
 #include <algorithm>
 #include <list>
 #include <set>
@@ -45,7 +46,7 @@ namespace {
   // Auxiliary class to use in std::random_shuffle()
   struct RandomGenerator {
     RandomGenerator () { srand(1); }
-    int operator () (int upper) const { return rand() % upper; }
+    ptrdiff_t operator () (ptrdiff_t upper) const { return rand() % upper; }
   };
 }
 
index 7ef669c..83e71c5 100644 (file)
@@ -5669,7 +5669,7 @@ static int VBsdf (Draw_Interpretor& theDI,
     if (aCmd.HasOption (aFresnel, 4)) // Schlick: type R G B
     {
       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
-      std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::tolower);
+      std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
 
       if (aFresnelType == "schlick")
       {
@@ -5691,7 +5691,7 @@ static int VBsdf (Draw_Interpretor& theDI,
     else if (aCmd.HasOption (aFresnel, 3)) // Conductor: type N K
     {
       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
-      std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::tolower);
+      std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
 
       if (aFresnelType == "conductor")
       {
@@ -5708,7 +5708,7 @@ static int VBsdf (Draw_Interpretor& theDI,
     else if (aCmd.HasOption (aFresnel, 2)) // Dielectric or Constant: type N|C
     {
       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
-      std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::tolower);
+      std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
 
       if (aFresnelType == "constant")
       {
index d20def4..a53c059 100644 (file)
@@ -48,7 +48,7 @@ void ViewerTest_CmdParser::AddOption (const std::string& theOptionNames, const s
   std::string anItem;
   while (std::getline (aStream, anItem, '|'))
   {
-    std::transform (anItem.begin(), anItem.end(), anItem.begin(), ::tolower);
+    std::transform (anItem.begin(), anItem.end(), anItem.begin(), ::LowerCase);
     if (!anItem.empty())
     {
       aNames.push_back (anItem);
@@ -98,7 +98,7 @@ void ViewerTest_CmdParser::Parse (Standard_Integer theArgsNb, const char** theAr
     if (theArgVec[anIter][0] == '-' && !std::isdigit (theArgVec[anIter][1]))
     {
       std::string anOptionName (&theArgVec[anIter][1]);
-      std::transform (anOptionName.begin(), anOptionName.end(), anOptionName.begin(), ::tolower);
+      std::transform (anOptionName.begin(), anOptionName.end(), anOptionName.begin(), ::LowerCase);
 
       std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (anOptionName);
       if (aMapIter != myArgumentLists.end())
@@ -126,7 +126,7 @@ void ViewerTest_CmdParser::Parse (Standard_Integer theArgsNb, const char** theAr
 Standard_Boolean ViewerTest_CmdParser::HasOption (const std::string& theOptionName, Standard_Integer theMandatoryArgsNb /*= 0*/, Standard_Boolean isFatal /*= Standard_False*/)
 {
   std::string aLowerName = theOptionName;
-  std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::tolower);
+  std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::LowerCase);
 
   Standard_Boolean aResult = Standard_False;
   std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (aLowerName);
@@ -152,7 +152,7 @@ Standard_Boolean ViewerTest_CmdParser::HasOption (const std::string& theOptionNa
 std::string ViewerTest_CmdParser::Arg (const std::string& theOptionName, Standard_Integer theArgumentIndex)
 {
   std::string aLowerName = theOptionName;
-  std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::tolower);
+  std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::LowerCase);
 
   std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (aLowerName);
   if (aMapIter != myArgumentLists.end())