summary refs log tree commit diff stats
path: root/tools/vccexe
diff options
context:
space:
mode:
Diffstat (limited to 'tools/vccexe')
-rw-r--r--tools/vccexe/vccexe.nim82
-rw-r--r--tools/vccexe/vccvswhere.nim4
-rw-r--r--tools/vccexe/vcvarsall.nim7
3 files changed, 65 insertions, 28 deletions
diff --git a/tools/vccexe/vccexe.nim b/tools/vccexe/vccexe.nim
index e78f9da5e..2a43f7422 100644
--- a/tools/vccexe/vccexe.nim
+++ b/tools/vccexe/vccexe.nim
@@ -32,7 +32,7 @@ proc discoverVccVcVarsAllPath*(version: VccVersion = vccUndefined): string =
 
   # All attempts to discover vcc failed
 
-const 
+const
   vccversionPrefix = "--vccversion"
   printPathPrefix = "--printPath"
   vcvarsallPrefix = "--vcvarsall"
@@ -41,6 +41,7 @@ const
   platformPrefix = "--platform"
   sdktypePrefix = "--sdktype"
   sdkversionPrefix = "--sdkversion"
+  vctoolsetPrefix = "--vctoolset"
   verbosePrefix = "--verbose"
 
   vccversionSepIdx = vccversionPrefix.len
@@ -49,7 +50,8 @@ const
   platformSepIdx = platformPrefix.len
   sdktypeSepIdx = sdktypePrefix.len
   sdkversionSepIdx = sdkversionPrefix.len
-  
+  vctoolsetSepIdx = vctoolsetPrefix.len
+
   vcvarsallDefaultPath = "vcvarsall.bat"
 
   helpText = """
@@ -93,10 +95,12 @@ Options:
   --sdktype:<type>    Specify the SDK flavor to use. Defaults to the Desktop SDK.
                       <type>: {empty} | store | uwp | onecore
   --sdkversion:<v>    Use a specific Windows SDK version:
-                      <v> is either the full Windows 10 SDK version number or 
+                      <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.
+  --vctoolset         Optionally specifies the Visual Studio compiler toolset to use. 
+                      By default, the environment is set to use the current Visual Studio compiler toolset.
 
 Other command line arguments are passed on to the
 secondary command specified by --command or to the
@@ -104,28 +108,29 @@ Microsoft (R) C/C++ Optimizing Compiler if no secondary
 command was specified
 """
 
-when isMainModule:
-  var vccversionArg: seq[string] = @[]
-  var printPathArg: bool = false
-  var vcvarsallArg: string
-  var commandArg: string
-  var noCommandArg: bool = false
-  var platformArg: VccArch
-  var sdkTypeArg: VccPlatformType
-  var sdkVersionArg: string
-  var verboseArg: bool = false
-
-  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:
+proc parseVccexeCmdLine(argseq: seq[string],
+    vccversionArg: var seq[string], printPathArg: var bool,
+    vcvarsallArg: var string, commandArg: var string, noCommandArg: var bool,
+    platformArg: var VccArch, sdkTypeArg: var VccPlatformType,
+    sdkVersionArg: var string,  vctoolsetArg: var string, verboseArg: var bool,
+    clArgs: var seq[string]) =
+  ## 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.
+  for wargv in argseq:
     # Check whether the current argument contains -- prefix
-    if wargv.startsWith(vccversionPrefix): # Check for vccversion
+    if wargv.startsWith("@"): # Check for response file prefix
+      let
+        responsefilename = wargv.substr(1)
+        responsefilehandle = open(responsefilename)
+        responsecontent = responsefilehandle.readAll()
+        responseargs = parseCmdLine(responsecontent)
+      parseVccexeCmdLine(responseargs, vccversionArg, printPathArg,
+        vcvarsallArg, commandArg, noCommandArg, platformArg, sdkTypeArg,
+        sdkVersionArg, vctoolsetArg, verboseArg, clArgs)
+    elif wargv.startsWith(vccversionPrefix): # Check for vccversion
       vccversionArg.add(wargv.substr(vccversionSepIdx + 1))
     elif wargv.cmpIgnoreCase(printPathPrefix) == 0: # Check for printPath
       printPathArg = true
@@ -141,6 +146,8 @@ when isMainModule:
       sdkTypeArg = parseEnum[VccPlatformType](wargv.substr(sdktypeSepIdx + 1))
     elif wargv.startsWith(sdkversionPrefix): # Check for sdkversion
       sdkVersionArg = wargv.substr(sdkversionSepIdx + 1)
+    elif wargv.startsWith(vctoolsetPrefix): # Check for vctoolset
+      vctoolsetArg = wargv.substr(vctoolsetSepIdx + 1)
     elif wargv.startsWith(verbosePrefix):
       verboseArg = true
     else: # Regular cl.exe argument -> store for final cl.exe invocation
@@ -148,6 +155,26 @@ when isMainModule:
         echo helpText
       clArgs.add(wargv)
 
+when isMainModule:
+  var vccversionArg: seq[string] = @[]
+  var printPathArg: bool = false
+  var vcvarsallArg: string
+  var commandArg: string
+  var noCommandArg: bool = false
+  var platformArg: VccArch
+  var sdkTypeArg: VccPlatformType
+  var sdkVersionArg: string
+  var vctoolsetArg: string
+  var verboseArg: bool = false
+
+  var clArgs: seq[string] = @[]
+
+  let wrapperArgs = commandLineParams()
+  parseVccexeCmdLine(wrapperArgs, vccversionArg, printPathArg, vcvarsallArg,
+    commandArg, noCommandArg, platformArg, sdkTypeArg, sdkVersionArg, vctoolsetArg,
+    verboseArg,
+    clArgs)
+
   # Support for multiple specified versions. Attempt VCC discovery for each version
   # specified, first successful discovery wins
   var vccversionValue: VccVersion = vccUndefined
@@ -175,7 +202,7 @@ when isMainModule:
     echo "$1: $2" % [head, vcvarsallArg]
 
   # Call vcvarsall to get the appropriate VCC process environment
-  var vcvars = vccVarsAll(vcvarsallArg, platformArg, sdkTypeArg, sdkVersionArg, verboseArg)
+  var vcvars = vccVarsAll(vcvarsallArg, platformArg, sdkTypeArg, sdkVersionArg, vctoolsetArg, verboseArg)
   if vcvars != nil:
     for vccEnvKey, vccEnvVal in vcvars:
       putEnv(vccEnvKey, vccEnvVal)
@@ -184,6 +211,11 @@ when isMainModule:
   if verboseArg:
     vccOptions.incl poEchoCmd
 
+  let currentDir = getCurrentDir()
+  for arg in clArgs.mitems:
+    if fileExists(arg):
+      arg = relativePath(arg, currentDir)
+
   # Default to the cl.exe command if no secondary command was specified
   if commandArg.len < 1:
     commandArg = "cl.exe"
diff --git a/tools/vccexe/vccvswhere.nim b/tools/vccexe/vccvswhere.nim
index 11ad39ce9..8f62f06ca 100644
--- a/tools/vccexe/vccvswhere.nim
+++ b/tools/vccexe/vccvswhere.nim
@@ -18,7 +18,7 @@ proc vccVswhereExtractVcVarsAllPath(vswherePath: string): string =
   let vsPath = execProcess(&"\"{vswherePath}\" {vswhereArgs}").strip()
   if vsPath.len > 0:
     let vcvarsallPath = joinPath(vsPath, vcvarsRelativePath)
-    if existsFile(vcvarsallPath):
+    if fileExists(vcvarsallPath):
       return vcvarsallPath
 
 proc vccVswhereGeneratePath(envName: string): string =
@@ -41,7 +41,7 @@ proc vccVswhereVcVarsAllPath*(): string =
 
   for tryEnv in ["ProgramFiles(x86)", "ProgramFiles"]:
     let vswherePath = vccVswhereGeneratePath(tryEnv)
-    if vswherePath.len > 0 and existsFile(vswherePath):
+    if vswherePath.len > 0 and fileExists(vswherePath):
       let vcVarsAllPath = vccVswhereExtractVcVarsAllPath(vswherePath)
       if vcVarsAllPath.len > 0:
         return vcVarsAllPath
diff --git a/tools/vccexe/vcvarsall.nim b/tools/vccexe/vcvarsall.nim
index 29d13cc7e..73b103e3c 100644
--- a/tools/vccexe/vcvarsall.nim
+++ b/tools/vccexe/vcvarsall.nim
@@ -33,7 +33,7 @@ type
     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 = "", verbose: bool = false): StringTableRef =
+proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type: VccPlatformType = vccplatEmpty, sdk_version, vctoolset: string = "", 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
@@ -44,6 +44,8 @@ proc vccVarsAll*(path: string, arch: VccArch = 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.
+  ## vctoolset
+  ##  Visual Studio compiler toolset to use.
   ## verbose
   ##   Echo the command-line passed on to the system to load the VCC environment. Defaults to `false`.
 
@@ -63,6 +65,9 @@ proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type
 
   if sdk_version.len > 0:
     args.add(sdk_version)
+  
+  if vctoolset.len > 0:
+    args.add("-vcvars_ver="&vctoolset)
 
   let argStr = args.join " "