summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFredrik Høisæther Rasch <fredrik.rasch@gmail.com>2016-10-01 01:56:08 +0200
committerFredrik Høisæther Rasch <fredrik.rasch@gmail.com>2016-10-01 01:56:08 +0200
commitc93ed4858013d43d560d8deba7916b5c798e56eb (patch)
tree5002983ecaa61fb2de70f3a63381719e4c8ac53d
parentabf4e204c2f1a8a6915a8d32c970b5ce64f58e10 (diff)
downloadNim-c93ed4858013d43d560d8deba7916b5c798e56eb.tar.gz
Add VCC wrappers
Enables automatic loading of Visual Studio C/C++ Build Tools
-rw-r--r--tools/vccenv.nim67
-rw-r--r--tools/vccexe.nim25
-rw-r--r--tools/vcclinkerexe.nim25
3 files changed, 117 insertions, 0 deletions
diff --git a/tools/vccenv.nim b/tools/vccenv.nim
new file mode 100644
index 000000000..4017368a0
--- /dev/null
+++ b/tools/vccenv.nim
@@ -0,0 +1,67 @@
+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:
+    if existsEnv vsComnToolsEnvKey:
+      let vsComnToolsEnvVal = getEnv vsComnToolsEnvKey
+      if (not vsComnToolsEnvVal.isNil) and (vsComnToolsEnvVal.len > 0):
+        return vsComnToolsEnvVal
+  return nil    
+
+proc getVccEnv*(platform: string, windowsStoreSdk: bool = false, sdkVersion: string = nil): StringTableRef =
+  var comSpecCommandString: TaintedString
+  if existsEnv comSpecEnvKey:
+    comSpecCommandString = getEnv comSpecEnvKey
+  else:
+    comSpecCommandString = "cmd"
+  
+  let vsComnToolsPath = getVsComnToolsPath()
+  if (isNil vsComnToolsPath) or (vsComnToolsPath.len < 1):
+    return nil
+  let vcvarsallPath = expandFilename joinPath(vsComnToolsPath, vcvarsallRelativePath)
+
+  var vcvarsallArgs: seq[string] = @[]
+  if (not isNil platform) and (platform.len > 0):
+    vcvarsallArgs.add(platform)
+  if windowsStoreSdk:
+    vcvarsallArgs.add("store")
+  if (not isNil sdkVersion) and (sdkVersion.len > 0):
+    vcvarsallArgs.add(sdkVersion)
+  var vcvarsallArgString: string
+  if vcvarsallArgs.len > 0:
+    vcvarsallArgString = vcvarsallArgs.join(" ")
+  else:
+    vcvarsallArgString = nil
+
+  var vcvarsallCommandString: string
+  if (not isNil vcvarsallArgString) and (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)
+  let vcvarsallEnv = newStringTable(modeCaseInsensitive)   
+  for vcvarsallEnvLine in vcvarsallStdOut.splitLines:
+    let vcvarsallEqualsIndex = vcvarsallEnvLine.find('=')
+    if vcvarsallEqualsIndex > 0:
+      let vcvarsallEnvKey = vcvarsallEnvLine[0..(vcvarsallEqualsIndex - 1)]
+      let vcvarsallEnvVal = vcvarsallEnvLine[(vcvarsallEqualsIndex + 1)..(vcvarsallEnvLine.len - 1)]
+      vcvarsallEnv[vcvarsallEnvKey] = vcvarsallEnvVal
+  return vcvarsallEnv
diff --git a/tools/vccexe.nim b/tools/vccexe.nim
new file mode 100644
index 000000000..a62def77c
--- /dev/null
+++ b/tools/vccexe.nim
@@ -0,0 +1,25 @@
+import strtabs, os, osproc, vccenv
+
+when defined(release):
+  let vccOptions = { poParentStreams }
+else:
+  let vccOptions = { poEchoCmd, poParentStreams }
+
+when isMainModule:
+  var vccEnvStrTab: StringTableRef = nil
+  when defined(i386):
+    vccEnvStrTab = getVccEnv "x86"
+  when defined(amd64):
+    vccEnvStrTab = getVccEnv "amd64"
+  when defined(arm):
+    vccEnvStrTab = getVccEnv "arm"
+  if vccEnvStrTab != nil:
+    for vccEnvKey, vccEnvVal in vccEnvStrTab:
+      putEnv(vccEnvKey, vccEnvVal)
+  let vccProcess = startProcess(
+      "cl".addFileExt(ExeExt), 
+      args = commandLineParams(),
+      options = vccOptions
+    )
+  quit vccProcess.waitForExit()
+    
\ No newline at end of file
diff --git a/tools/vcclinkerexe.nim b/tools/vcclinkerexe.nim
new file mode 100644
index 000000000..2598d6312
--- /dev/null
+++ b/tools/vcclinkerexe.nim
@@ -0,0 +1,25 @@
+import strtabs, os, osproc, vccenv
+
+when defined(release):
+  let vccOptions = { poParentStreams }
+else:
+  let vccOptions = { poEchoCmd, poParentStreams }
+
+when isMainModule:
+  var vccEnvStrTab: StringTableRef = nil
+  when defined(i386):
+    vccEnvStrTab = getVccEnv "x86"
+  when defined(amd64):
+    vccEnvStrTab = getVccEnv "amd64"
+  when defined(arm):
+    vccEnvStrTab = getVccEnv "arm"
+  if vccEnvStrTab != nil:
+    for vccEnvKey, vccEnvVal in vccEnvStrTab:
+      putEnv(vccEnvKey, vccEnvVal)
+  let vccProcess = startProcess(
+      "link".addFileExt(ExeExt), 
+      args = commandLineParams(),
+      options = vccOptions
+    )
+  quit vccProcess.waitForExit()
+