summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFredrik Høisæther Rasch <fredrik.h.rasch@uit.no>2017-03-20 16:23:54 +0100
committerFredrik Høisæther Rasch <fredrik.h.rasch@uit.no>2017-03-21 12:17:09 +0100
commit9446ae5576e43285a28c4b1705a139d317867328 (patch)
tree5220d2a0980f8b7a5edf995d2c15e5737cd89490
parent93e03144fc769e95a92fcf91c34f40610b754a3a (diff)
downloadNim-9446ae5576e43285a28c4b1705a139d317867328.tar.gz
Moved vccenv over to vcvarsall
Updated vccexe with new command-line arguments
-rw-r--r--tools/vccenv/vccenv.nim58
-rw-r--r--tools/vccenv/vccexe.nim57
-rw-r--r--tools/vccenv/vcvarsall.nim73
3 files changed, 116 insertions, 72 deletions
diff --git a/tools/vccenv/vccenv.nim b/tools/vccenv/vccenv.nim
deleted file mode 100644
index a335efd10..000000000
--- a/tools/vccenv/vccenv.nim
+++ /dev/null
@@ -1,58 +0,0 @@
-import strtabs, os, osproc, streams, strutils
-
-const
-  comSpecEnvKey = "ComSpec"
-  vsComnToolsEnvKeys = [
-    "VS140COMNTOOLS",
-    "VS130COMNTOOLS",
-    "VS120COMNTOOLS",
-    "VS110COMNTOOLS",
-    "VS100COMNTOOLS",
-    "VS90COMNTOOLS"
-  ]
-  vcvarsallRelativePath = joinPath("..", "..", "VC", "vcvarsall")
-
-proc getVsComnToolsPath*(): TaintedString =
-  for vsComnToolsEnvKey in vsComnToolsEnvKeys:
-    let vsComnToolsEnvVal = getEnv vsComnToolsEnvKey
-    if vsComnToolsEnvVal.len > 0:
-      return vsComnToolsEnvVal
-
-proc getVccEnv*(platform: string, windowsStoreSdk: bool = false,
-                sdkVersion: string = nil): StringTableRef =
-  var comSpecCommandString = getEnv comSpecEnvKey
-  if comSpecCommandString.len == 0:
-    comSpecCommandString = "cmd"
-
-  let vsComnToolsPath = getVsComnToolsPath()
-  if vsComnToolsPath.len < 1:
-    return nil
-  let vcvarsallPath = expandFilename joinPath(vsComnToolsPath, vcvarsallRelativePath)
-
-  var vcvarsallArgs: seq[string] = @[]
-  if platform.len > 0:
-    vcvarsallArgs.add(platform)
-  if windowsStoreSdk:
-    vcvarsallArgs.add("store")
-  if sdkVersion.len > 0:
-    vcvarsallArgs.add(sdkVersion)
-  let vcvarsallArgString = vcvarsallArgs.join(" ")
-
-  var vcvarsallCommandString: string
-  if vcvarsallArgString.len > 0:
-    vcvarsallCommandString = "\"$1\" $2" % [vcvarsallPath, vcvarsallArgString]
-  else:
-    vcvarsallCommandString = vcvarsallPath
-
-  let vcvarsallExecCommand = "\"$1\" /C \"$2 && SET\"" %
-                             [comSpecCommandString, vcvarsallCommandString]
-  when defined(release):
-    let vccvarsallOptions = {poEvalCommand, poDemon}
-  else:
-    let vccvarsallOptions = {poEchoCmd, poEvalCommand, poDemon}
-  let vcvarsallStdOut = execProcess(vcvarsallExecCommand, options = vccvarsallOptions)
-  result = newStringTable(modeCaseInsensitive)
-  for line in vcvarsallStdOut.splitLines:
-    let idx = line.find('=')
-    if idx > 0:
-      result[line[0..(idx - 1)]] = line[(idx + 1)..(line.len - 1)]
diff --git a/tools/vccenv/vccexe.nim b/tools/vccenv/vccexe.nim
index 892246830..4ecbfe50e 100644
--- a/tools/vccenv/vccexe.nim
+++ b/tools/vccenv/vccexe.nim
@@ -1,4 +1,4 @@
-import strutils, strtabs, os, osproc, vccenv
+import strutils, strtabs, os, osproc, vcvarsall
 
 when defined(release):
   let vccOptions = {poParentStreams}
@@ -6,47 +6,73 @@ else:
   let vccOptions = {poEchoCmd, poParentStreams}
 
 const 
+  vcvarsallPrefix = "--vcvarsall"
+  commandPrefix = "--command"
   platformPrefix = "--platform"
-  winstorePrefix = "--winstore"
+  sdktypePrefix = "--sdktype"
   sdkversionPrefix = "--sdkversion"
 
+  vcvarsallSepIdx = vcvarsallPrefix.len
+  commandSepIdx = commandPrefix.len
   platformSepIdx = platformPrefix.len
+  sdktypeSepIdx = sdktypePrefix.len
   sdkversionSepIdx = sdkversionPrefix.len
   
   HelpText = """
 +-----------------------------------------------------------------+
 |         Microsoft C/C++ compiler wrapper for Nim                |
-|             (c) 2016 Fredrik Høisæther Rasch                    |
+|            (c) 2017 Fredrik Hoeisaether Rasch                   |
 +-----------------------------------------------------------------+
 
 Usage:
   vccexe [options] [compileroptions]
 Options:
+  --vcvarsall:<path>  Path to the Developer Command Prompt utility vcvarsall.bat that selects
+                      the appropiate devlopment settings.
+                      Usual path for Visual Studio 2015 and below:
+                        %VSInstallDir%\VC\vcvarsall
+                      Usual path for Visual Studio 2017 and above:
+                        %VSInstallDir%\VC\Auxiliary\Build\vcvarsall
+  --command:<exec>    Specify the command to run once the development environment is loaded.
+                      <exec> can be any command-line argument. Any arguments not recognized by vccexe
+                      are passed on as arguments to this command.
+                      cl.exe is invoked by default if this argument is omitted.
   --platform:<arch>   Specify the Compiler Platform Tools architecture
                       <arch>: x86 | amd64 | arm | x86_amd64 | x86_arm | amd64_x86 | amd64_arm
-  --winstore          Use Windows Store (rather than desktop) development tools
+                      Values with two architectures (like x86_amd64) specify the architecture
+                      of the cross-platform compiler (e.g. x86) and the target it compiles to (e.g. amd64).
+  --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 
                       "8.1" to use the windows 8.1 SDK
 
 Other command line arguments are passed on to the
-Microsoft C/C++ compiler for the specified SDK toolset
+secondary command specified by --command or to the
+Microsoft (R) C/C++ Optimizing Compiler if no secondary
+command was specified
 """
 
 when isMainModule:
-  var platformArg: string = nil
+  var vcvarsallArg: string = nil
+  var commandArg: string = nil
+  var platformArg: VccArch
+  var sdkTypeArg: VccPlatformType
   var sdkVersionArg: string = nil
-  var storeArg: bool = false
 
   var clArgs: seq[TaintedString] = @[]
 
   var wrapperArgs = commandLineParams()
   for wargv in wrapperArgs:
     # Check whether the current argument contains -- prefix
-    if wargv.startsWith(platformPrefix): # Check for platform
-      platformArg = wargv.substr(platformSepIdx + 1)
-    elif wargv == winstorePrefix: # Check for winstore
-      storeArg = true
+    if wargv.startsWith(vcvarsallPrefix): # Check for vcvarsall
+      vcvarsallArg = wargv.substr(vcvarsallSepIdx + 1)
+    elif wargv.startsWith(commandPrefix): # Check for command
+      commandArg = wargv.substr(commandSepIdx + 1)
+    elif wargv.startsWith(platformPrefix): # Check for platform
+      platformArg = parseEnum[VccArch](wargv.substr(platformSepIdx + 1))
+    elif wargv.startsWith(sdktypePrefix): # Check for sdktype
+      sdkTypeArg = parseEnum[VccPlatformType](wargv.substr(sdktypeSepIdx + 1))
     elif wargv.startsWith(sdkversionPrefix): # Check for sdkversion
       sdkVersionArg = wargv.substr(sdkversionSepIdx + 1)
     else: # Regular cl.exe argument -> store for final cl.exe invocation
@@ -54,10 +80,13 @@ when isMainModule:
         echo HelpText
       clArgs.add(wargv)
 
-  var vccEnvStrTab = getVccEnv(platformArg, storeArg, sdkVersionArg)  
-  if vccEnvStrTab != nil:
-    for vccEnvKey, vccEnvVal in vccEnvStrTab:
+  var vcvars = vccVarsAll(vcvarsallArg, platformArg, sdkTypeArg, sdkVersionArg)
+  if vcvars != nil:
+    for vccEnvKey, vccEnvVal in vcvars:
       putEnv(vccEnvKey, vccEnvVal)
+
+  if commandArg.len < 1:
+    commandArg = "cl.exe"
   let vccProcess = startProcess(
       "cl.exe",
       args = clArgs,
diff --git a/tools/vccenv/vcvarsall.nim b/tools/vccenv/vcvarsall.nim
new file mode 100644
index 000000000..db97177b0
--- /dev/null
+++ b/tools/vccenv/vcvarsall.nim
@@ -0,0 +1,73 @@
+import strtabs, strutils, os, osproc
+
+const
+  comSpecEnvKey = "ComSpec" # Environment Variable that specifies the command-line application path in Windows
+                            # Usually set to cmd.exe
+  vcvarsallDefaultPath = "vcvarsall.bat"
+
+type
+  VccArch* = enum
+    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"
+
+  VccPlatformType* = enum
+    vccplatEmpty = "",
+    vccplatStore = "store",
+    vccplatUWP = "uwp",
+    vccplatOneCore = "onecore"
+
+proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type: VccPlatformType = vccplatEmpty, sdk_version: string = nil): StringTableRef =
+  var vccvarsallpath = path
+  # Assume that default executable is in current directory or in PATH
+  if path == nil or path.len < 1:
+    vccvarsallpath = vcvarsallDefaultPath
+  
+  var args: seq[string] = @[]
+  
+  let archStr: string = $arch
+  if archStr.len > 0:
+    args.add(archStr)
+  
+  let platStr: string = $platform_type
+  if platStr.len > 0:
+    args.add(platStr)
+
+  if sdk_version.len > 0:
+    args.add(sdk_version)
+
+  let argStr = args.join " "
+  
+  var vcvarsExec: string
+  if argStr.len > 0:
+    vcvarsExec = "\"$1\" $2" % [vccvarsallpath, argStr]
+  else:
+    vcvarsExec = "\"$1\"" % vccvarsallpath
+
+  var comSpecCmd = getenv comSpecEnvKey
+  if comSpecCmd.len < 1:
+    comSpecCmd = "cmd"
+  
+  let comSpecExec = "\"$1\" /C \"$2 && SET\"" % [comSpecCmd, vcvarsExec]
+  when defined(release):
+    let comSpecOpts = {poEvalCommand, poDemon, poStdErrToStdOut}
+  else:
+    let comSpecOpts = {poEchoCmd, poEvalCommand, poDemon, poStdErrToStdOut}
+  let comSpecOut = execProcess(comSpecExec, options = comSpecOpts)
+  result = newStringTable(modeCaseInsensitive)
+  for line in comSpecOut.splitLines:
+    when not defined(release) or defined(debug):
+      echo line
+    let idx = line.find('=')
+    if idx > 0:
+      result[line[0..(idx - 1)]] = line[(idx + 1)..(line.len - 1)]