summary refs log tree commit diff stats
path: root/tools/vccenv/vccexe.nim
blob: 3193dbbbaa3551c60c87d54f520648e9e64f1ad5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import strutils, strtabs, os, osproc, vccenv

when defined(release):
  let vccOptions = {poParentStreams}
else:
  let vccOptions = {poEchoCmd, poParentStreams}

const 
  vcvarsArgPrefix = "vcvars:"
  platformArgPrefix = "platform:"
  storeArgPrefix = "store"
  sdkArgPrefix = "sdk:"
  vcvarsArgIdx = 1   # vcvars comes after - or / char in argument
  argsToken1Idx = vcvarsArgIdx + vcvarsArgPrefix.len 
  platformArgValueIdx = argsToken1Idx + platformArgPrefix.len
  sdkArgValueIdx = argsToken1Idx + sdkArgPrefix.len

  HelpText = """
+-----------------------------------------------------------------+
|         Microsoft C/C++ compiler wrapper for Nim                |
|             (c) 2016 Fredrik Høisæther Rasch                    |
+-----------------------------------------------------------------+

Usage:
  vccexe [options] [compileroptions]
Options:
  /vcvars:platform:<arch>   Specify the Compiler Platform Tools architecture
                            <arch>: x86 | amd64 | arm | x86_amd64 | x86_arm | amd64_x86 | amd64_arm
  /vcvars:store             Use Windows Store (rather than desktop) development tools
  /vcvars:sdk:<version>     Use a specific Windows SDK version:
                            <version> is either the full Windows 10 SDK version number or 
                            "8.1" to use the windows 8.1 SDK
"""

when isMainModule:
  var platformArg: string = nil
  var storeArg: bool = false
  var sdkVersionArg: string = nil
  var clArgs: seq[TaintedString] = @[]
  var wrapperArgs = commandLineParams()
  for wargv in wrapperArgs:
    # Check whether the current argument contains vcvars prefix
    if cmpIgnoreCase(wargv.substr(vcvarsArgIdx, argsToken1Idx - 1), vcvarsArgPrefix) == 0:
      # Check for platform
      if cmpIgnoreCase(wargv.substr(argsToken1Idx, platformArgValueIdx - 1), platformArgPrefix) == 0:
        platformArg = wargv.substr(platformArgValueIdx)
      # Check for store
      elif cmpIgnoreCase(wargv.substr(argsToken1Idx), storeArgPrefix) == 0:
        storeArg = true
      # Check for sdk
      elif cmpIgnoreCase(wargv.substr(argsToken1Idx, sdkArgValueIdx - 1), sdkArgPrefix) == 0:
        sdkVersionArg = wargv.substr(sdkArgValueIdx)
    else: # Regular cl.exe argument -> store for final cl.exe invocation
      if (wargv.len == 2) and (wargv[1] == '?'):
        echo HelpText
      clArgs.add(wargv)

  var vccEnvStrTab = getVccEnv(platformArg, storeArg, sdkVersionArg)  
  if vccEnvStrTab != nil:
    for vccEnvKey, vccEnvVal in vccEnvStrTab:
      putEnv(vccEnvKey, vccEnvVal)
  let vccProcess = startProcess(
      "cl.exe",
      args = clArgs,
      options = vccOptions
    )
  quit vccProcess.waitForExit()