summary refs log tree commit diff stats
path: root/tools/vccexe
diff options
context:
space:
mode:
authorFredrik Høisæther Rasch <fredrik.rasch@gmail.com>2017-03-26 17:08:41 +0200
committerFredrik Høisæther Rasch <fredrik.rasch@gmail.com>2017-03-26 17:14:02 +0200
commit3d21e2ab668c1bf2df58829185507bc739440526 (patch)
tree165c4ff160da388b15edc2e5fa1edd5715a94cd6 /tools/vccexe
parent24f07d9b71a5302047fa0183318d35fbc74222b4 (diff)
downloadNim-3d21e2ab668c1bf2df58829185507bc739440526.tar.gz
Added documentation and explanatory comments to vccexe
Diffstat (limited to 'tools/vccexe')
-rw-r--r--tools/vccexe/vccdiscover.nim32
-rw-r--r--tools/vccexe/vccenv.nim40
-rw-r--r--tools/vccexe/vccexe.nim14
-rw-r--r--tools/vccexe/vcvarsall.nim67
4 files changed, 117 insertions, 36 deletions
diff --git a/tools/vccexe/vccdiscover.nim b/tools/vccexe/vccdiscover.nim
index 88dfd1999..f20bf2441 100644
--- a/tools/vccexe/vccdiscover.nim
+++ b/tools/vccexe/vccdiscover.nim
@@ -1,15 +1,33 @@
+## VCC compiler backend discovery Utility
+##
+## Module to discover the path to the vcvarsall utility of a VCC compiler backend.
+## The module supports discovery for either the latest recognizable version (default)
+## or discovery of a specific VCC compiler backend version.
+##
+## This module can also produce a standalone command-line executable.
+## It supports a `--help` command-line argument. Refer to its output for further
+## documentation on the `vccdiscover` standalone command-line application.
+
 import strutils, os, vccenv
 
 type
-  VccVersion* = enum
-    vccUndefined = (0, ""),
-    vcc90  =  vs90, # Visual Studio 2008
-    vcc100 = vs100, # Visual Studio 2010
-    vcc110 = vs110, # Visual Studio 2012
-    vcc120 = vs120, # Visual Studio 2013
-    vcc140 = vs140  # Visual Studio 2015
+  VccVersion* = enum ## VCC compiler backend versions
+    vccUndefined = (0, ""), ## VCC version undefined, resolves to the latest recognizable VCC version
+    vcc90  =  vs90, ## Visual Studio 2008 (Version 9.0)
+    vcc100 = vs100, ## Visual Studio 2010 (Version 10.0)
+    vcc110 = vs110, ## Visual Studio 2012 (Version 11.0)
+    vcc120 = vs120, ## Visual Studio 2013 (Version 12.0)
+    vcc140 = vs140  ## Visual Studio 2015 (Version 14.0)
 
 proc discoverVccVcVarsAllPath*(version: VccVersion = vccUndefined): string =
+  ## Returns the path to the vcvarsall utility of the specified VCC compiler backend.
+  ##
+  ## version
+  ##   The specific version of the VCC compiler backend to discover.
+  ##   Defaults to the latest recognized VCC compiler backend that is found on the system.
+  ##
+  ## Returns `nil` if the VCC compiler backend discovery failed.
+
   # TODO: Attempt discovery using vswhere utility.
 
   # Attempt discovery through VccEnv 
diff --git a/tools/vccexe/vccenv.nim b/tools/vccexe/vccenv.nim
index addf77e38..6ddf2e29a 100644
--- a/tools/vccexe/vccenv.nim
+++ b/tools/vccexe/vccenv.nim
@@ -1,18 +1,40 @@
+## VCC compiler backend installation discovery using Visual Studio common tools
+## environment variables.
+
 import os
 
 type
-  VccEnvVersion* = enum
-    vsUndefined = (0, ""),
-    vs90  = (90,   "VS90COMNTOOLS"), # Visual Studio 2008
-    vs100 = (100, "VS100COMNTOOLS"), # Visual Studio 2010
-    vs110 = (110, "VS110COMNTOOLS"), # Visual Studio 2012
-    vs120 = (120, "VS120COMNTOOLS"), # Visual Studio 2013
-    vs140 = (140, "VS140COMNTOOLS")  # Visual Studio 2015
+  VccEnvVersion* = enum ## The version of the Visual Studio C/C++ Developer Environment to load
+                        ## Valid versions are Versions of Visual Studio that permanently set a COMNTOOLS
+                        ## environment variable. That includes Visual Studio version up to and including
+                        ## Visual Studio 2015
+    vsUndefined = (0, ""), ## Version not specified, use latest recogized version on the system
+    vs90  = (90,   "VS90COMNTOOLS"), ## Visual Studio 2008
+    vs100 = (100, "VS100COMNTOOLS"), ## Visual Studio 2010
+    vs110 = (110, "VS110COMNTOOLS"), ## Visual Studio 2012
+    vs120 = (120, "VS120COMNTOOLS"), ## Visual Studio 2013
+    vs140 = (140, "VS140COMNTOOLS")  ## Visual Studio 2015
 
 const
-  vcvarsallRelativePath = joinPath("..", "..", "VC", "vcvarsall")
+  vcvarsallRelativePath = joinPath("..", "..", "VC", "vcvarsall") ## Relative path from the COMNTOOLS path to the vcvarsall file.
+
+proc vccEnvVcVarsAllPath*(version: VccEnvVersion = vsUndefined): string = 
+  ## Returns the path to the VCC Developer Command Prompt executable for the specified VCC version.
+  ##
+  ## Returns `nil` if the specified VCC compiler backend installation was not found.
+  ## 
+  ## If the `version` parameter is omitted or set to `vsUndefined`, `vccEnvVcVarsAllPath` searches 
+  ## for the latest recognizable version of the VCC tools it can find.
+  ## 
+  ## `vccEnvVcVarsAllPath` uses the COMNTOOLS environment variables to find the Developer Command Prompt
+  ## executable path. The COMNTOOLS environment variable are permanently set when Visual Studio is installed.
+  ## Each version of Visual Studio has its own COMNTOOLS environment variable. E.g.: Visual Studio 2015 sets
+  ## The VS140COMNTOOLS environment variable.
+  ##
+  ## Note: Beginning with Visual Studio 2017, the installers no longer set environment variables to allow for
+  ## multiple side-by-side installations of Visual Studio. Therefore, `vccEnvVcVarsAllPath` cannot be used
+  ## to detect the VCC Developer Command Prompt executable path for Visual Studio 2017 and later.
 
-proc vccEnvVcVarsAllPath*(version: VccEnvVersion = vsUndefined): string =
   if version == vsUndefined:
     for tryVersion in [vs140, vs120, vs110, vs100, vs90]:
       let tryPath = vccEnvVcVarsAllPath(tryVersion)
diff --git a/tools/vccexe/vccexe.nim b/tools/vccexe/vccexe.nim
index 4dec0db04..86ad86d97 100644
--- a/tools/vccexe/vccexe.nim
+++ b/tools/vccexe/vccexe.nim
@@ -47,6 +47,8 @@ Options:
   --sdkversion:<v>    Use a specific Windows SDK version:
                       <v> is either the full Windows 10 SDK version number or 
                       "8.1" to use the windows 8.1 SDK
+  --verbose           Echoes the command line for loading the Developer Command Prompt
+                      and the command line passed on to the secondary command.
 
 Other command line arguments are passed on to the
 secondary command specified by --command or to the
@@ -65,6 +67,11 @@ when isMainModule:
 
   var clArgs: seq[TaintedString] = @[]
 
+  # Cannot use usual command-line argument parser here
+  # Since vccexe command-line arguments are intermingled
+  # with the secondary command-line arguments which have
+  # a syntax that is not supported by the default nim
+  # argument parser.
   var wrapperArgs = commandLineParams()
   for wargv in wrapperArgs:
     # Check whether the current argument contains -- prefix
@@ -87,6 +94,8 @@ when isMainModule:
         echo HelpText
       clArgs.add(wargv)
 
+  # Support for multiple specified versions. Attempt VCC discovery for each version
+  # specified, first successful discovery wins
   for vccversionItem in vccversionArg:
     var vccversionValue: VccVersion
     try:
@@ -96,9 +105,11 @@ when isMainModule:
     vcvarsallArg = discoverVccVcVarsAllPath(vccversionValue)
     if vcvarsallArg.len > 0:
       break
+  # VCC version not specified, discover latest (call discover without args)
   if vcvarsallArg.len < 1 and vccversionArg.len < 1:
     vcvarsallArg = discoverVccVcVarsAllPath()
 
+  # Call vcvarsall to get the appropiate VCC process environment
   var vcvars = vccVarsAll(vcvarsallArg, platformArg, sdkTypeArg, sdkVersionArg, verboseArg)
   if vcvars != nil:
     for vccEnvKey, vccEnvVal in vcvars:
@@ -108,8 +119,11 @@ when isMainModule:
   if verboseArg:
     vccOptions.incl poEchoCmd
 
+  # Default to the cl.exe command if no secondary command was specified
   if commandArg.len < 1:
     commandArg = "cl.exe"
+
+  # Run VCC command with the VCC process environment
   let vccProcess = startProcess(
       commandArg,
       args = clArgs,
diff --git a/tools/vccexe/vcvarsall.nim b/tools/vccexe/vcvarsall.nim
index dcd7ef868..e7a55069c 100644
--- a/tools/vccexe/vcvarsall.nim
+++ b/tools/vccexe/vcvarsall.nim
@@ -1,33 +1,53 @@
+## VCC Developer Command Prompt Loader
+## 
+## In order for the VCC compiler backend to work properly, it requires numerous
+## environment variables to be set properly for the desired architecture and compile target.
+## For that purpose the VCC compiler ships with the vcvarsall utility which is an executable
+## batch script that can be used to properly set up an Command Prompt environment.
+
 import strtabs, strutils, os, osproc
 
 const
-  comSpecEnvKey = "ComSpec" # Environment Variable that specifies the command-line application path in Windows
-                            # Usually set to cmd.exe
+  comSpecEnvKey = "ComSpec" ## Environment Variable that specifies the command-line application path in Windows
+                            ## Usually set to cmd.exe
   vcvarsallDefaultPath = "vcvarsall.bat"
 
 type
-  VccArch* = enum
+  VccArch* = enum ## The VCC compile target architectures
     vccarchUnspecified = "",
-    vccarchX86 = "x86",
-    vccarchAmd64 = "amd64",
-    vccarchX86Amd64 = "x86_amd64",
-    vccarchX86Arm = "x86_arm",
-    vccarchX86Arm64 = "x86_arm64",
-    vccarchAmd64X86 = "amd64_x86",
-    vccarchAmd64Arm = "amd64_arm",
-    vccarchAmd64Arm64 = "amd64_arm64",
-    vccarchX64 = "x64",
-    vccarchX64X86 = "x64_x86",
-    vccarchX64Arm = "x64_arm",
-    vccarchX64Arm64 = "x64_arm64"
+    vccarchX86 = "x86", ## VCC for compilation against the x86 architecture.
+    vccarchAmd64 = "amd64", ## VCC for compilation against the amd64 architecture.
+    vccarchX86Amd64 = "x86_amd64", ## VCC cross-compilation tools using x86 VCC for compilation against the amd64 architecture.
+    vccarchX86Arm = "x86_arm", ## VCC cross-compilation tools using x86 VCC for compilation against the ARM architecture.
+    vccarchX86Arm64 = "x86_arm64", ## VCC cross-compilation tools using x86 VCC for compilation against the ARM (64-bit) architecture.
+    vccarchAmd64X86 = "amd64_x86", ## VCC cross-compilation tools using amd64 VCC for compilation against the x86 architecture.
+    vccarchAmd64Arm = "amd64_arm", ## VCC cross-compilation tools using amd64 VCC for compilation against the ARM architecture.
+    vccarchAmd64Arm64 = "amd64_arm64", ## VCC cross-compilation tools using amd64 VCC for compilation against the ARM (64-bit) architecture.
+    vccarchX64 = "x64", ## VCC for compilation against the x64 architecture.
+    vccarchX64X86 = "x64_x86", ## VCC cross-compilation tools using x64 VCC for compilation against the x86 architecture.
+    vccarchX64Arm = "x64_arm", ## VCC cross-compilation tools using x64 VCC for compilation against the ARM architecture.
+    vccarchX64Arm64 = "x64_arm64" ## VCC cross-compilation tools using x64 VCC for compilation against the ARM (64-bit) architecture.
 
-  VccPlatformType* = enum
-    vccplatEmpty = "",
-    vccplatStore = "store",
-    vccplatUWP = "uwp",
-    vccplatOneCore = "onecore"
+  VccPlatformType* = enum ## The VCC platform type of the compile target
+    vccplatEmpty = "", ## Default (i.e. Desktop) Platfor Type
+    vccplatStore = "store", ## Windows Store Application
+    vccplatUWP = "uwp", ## Universal Windows Platform (UWP) Application
+    vccplatOneCore = "onecore" # Undocumented platform type in the Windows SDK, probably XBox One SDK platform type.
 
 proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type: VccPlatformType = vccplatEmpty, sdk_version: string = nil, verbose: bool = false): StringTableRef =
+  ## Returns a string table containing the proper process environment to successfully execute VCC compile commands for the specified SDK version, CPU architecture and platform type.
+  ##
+  ## path
+  ##   The path to the vcvarsall utility for VCC compiler backend.
+  ## arch
+  ##   The compile target CPU architecture. Starting with Visual Studio 2017, this value must be specified and must not be set to `vccarchUnspecified`.
+  ## platform_type
+  ##   The compile target Platform Type. Defaults to the Windows Desktop platform, i.e. a regular Windows executable binary.
+  ## sdk_version
+  ##   The Windows SDK version to use.
+  ## verbose
+  ##   Echo the command-line passed on to the system to load the VCC environment. Defaults to `false`.
+
   var vccvarsallpath = path
   # Assume that default executable is in current directory or in PATH
   if path == nil or path.len < 1:
@@ -58,12 +78,19 @@ proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type
   if comSpecCmd.len < 1:
     comSpecCmd = "cmd"
   
+  # Run the Windows Command Prompt with the /C argument
+  # Execute vcvarsall with its command-line arguments
+  # and then execute the SET command to list all environment variables
   let comSpecExec = "\"$1\" /C \"$2 && SET\"" % [comSpecCmd, vcvarsExec]
   var comSpecOpts = {poEvalCommand, poDemon, poStdErrToStdOut}
   if verbose:
     comSpecOpts.incl poEchoCmd
   let comSpecOut = execProcess(comSpecExec, options = comSpecOpts)
+
   result = newStringTable(modeCaseInsensitive)
+
+  # Parse the output of the final SET command to construct a String Table
+  # with the appropiate environment variables
   for line in comSpecOut.splitLines:
     let idx = line.find('=')
     if idx > 0: