diff options
author | Fredrik Høisæther Rasch <fredrik.h.rasch@uit.no> | 2017-03-20 16:36:16 +0100 |
---|---|---|
committer | Fredrik Høisæther Rasch <fredrik.h.rasch@uit.no> | 2017-03-21 12:17:09 +0100 |
commit | 45f61ad0466d317bb77b151ed633389fd0eeac22 (patch) | |
tree | cb61b9039ebb2353f2d0f1344e48cfab070de8e0 /tools/vccexe | |
parent | 9446ae5576e43285a28c4b1705a139d317867328 (diff) | |
download | Nim-45f61ad0466d317bb77b151ed633389fd0eeac22.tar.gz |
Moved vccexe to a more logical place (vccexe)
Diffstat (limited to 'tools/vccexe')
-rw-r--r-- | tools/vccexe/vccexe.nim | 95 | ||||
-rw-r--r-- | tools/vccexe/vcvarsall.nim | 73 |
2 files changed, 168 insertions, 0 deletions
diff --git a/tools/vccexe/vccexe.nim b/tools/vccexe/vccexe.nim new file mode 100644 index 000000000..4ecbfe50e --- /dev/null +++ b/tools/vccexe/vccexe.nim @@ -0,0 +1,95 @@ +import strutils, strtabs, os, osproc, vcvarsall + +when defined(release): + let vccOptions = {poParentStreams} +else: + let vccOptions = {poEchoCmd, poParentStreams} + +const + vcvarsallPrefix = "--vcvarsall" + commandPrefix = "--command" + platformPrefix = "--platform" + 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) 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 + 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 +secondary command specified by --command or to the +Microsoft (R) C/C++ Optimizing Compiler if no secondary +command was specified +""" + +when isMainModule: + var vcvarsallArg: string = nil + var commandArg: string = nil + var platformArg: VccArch + var sdkTypeArg: VccPlatformType + var sdkVersionArg: string = nil + + var clArgs: seq[TaintedString] = @[] + + var wrapperArgs = commandLineParams() + for wargv in wrapperArgs: + # Check whether the current argument contains -- prefix + 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 + if (wargv.len == 2) and (wargv[1] == '?'): + echo HelpText + clArgs.add(wargv) + + 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, + options = vccOptions + ) + quit vccProcess.waitForExit() diff --git a/tools/vccexe/vcvarsall.nim b/tools/vccexe/vcvarsall.nim new file mode 100644 index 000000000..db97177b0 --- /dev/null +++ b/tools/vccexe/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)] |