resolve merge conflicts

This commit is contained in:
Araq
2018-12-12 18:16:53 +01:00
9 changed files with 367 additions and 147 deletions

2
.gitignore vendored
View File

@@ -19,6 +19,8 @@ dnimcache/
*.zip
*.iss
*.log
*.ilk
*.pdb
mapping.txt
tags

View File

@@ -134,7 +134,7 @@ compiler vcc:
result = (
name: "vcc",
objExt: "obj",
optSpeed: " /Ogityb2 /G7 /arch:SSE2 ",
optSpeed: " /Ogityb2 /G7 ",
optSize: " /O1 /G7 ",
compilerExe: "cl",
cppCompiler: "cl",

View File

@@ -23,7 +23,7 @@ hint[LineTooLong]=off
arm.linux.gcc.exe = "arm-linux-gnueabihf-gcc"
arm.linux.gcc.linkerexe = "arm-linux-gnueabihf-gcc"
# For OpenWRT, you will also need to adjust PATH to point to your toolchain.
# For OpenWRT, you will also need to adjust PATH to point to your toolchain.
mips.linux.gcc.exe = "mips-openwrt-linux-gcc"
mips.linux.gcc.linkerexe = "mips-openwrt-linux-gcc"
@@ -225,9 +225,13 @@ clang.options.speed = "-O3"
clang.options.size = "-Os"
# Configuration for the Visual C/C++ compiler:
vcc.exe = "vccexe.exe"
# VCCEXE is a tool that invokes the Visual Studio Developer Command Prompt
# before calling the compiler.
# Please make sure either Visual Studio or C++ Build SKU is installed when using the vcc compiler backend.
vcc.exe = "vccexe.exe"
vcc.cpp.exe = "vccexe.exe"
vcc.linkerexe = "vccexe.exe"
vcc.linkerexe = "vccexe.exe"
vcc.cpp.linkerexe = "vccexe.exe"
# set the options for specific platforms:
@@ -238,30 +242,35 @@ vcc.options.always = "/nologo"
vcc.options.always %= "${vcc.options.always} /Z7" # Get VCC to output full debug symbols in the obj file
@end
vcc.cpp.options.always %= "${vcc.options.always} /EHsc"
vcc.options.linker = "/nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
vcc.options.linker = "/nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
vcc.cpp.options.linker %= "${vcc.options.linker}"
@if i386:
vcc.options.always %= "--platform:x86 ${vcc.options.always}"
vcc.cpp.options.always %= "--platform:x86 ${vcc.cpp.options.always}"
vcc.options.linker %= "--platform:x86 ${vcc.options.linker}"
vcc.cpp.options.linker %= "--platform:x86 ${vcc.cpp.options.linker}"
vcc.options.always = "--platform:x86 /nologo"
vcc.cpp.options.always = "--platform:x86 /nologo /EHsc"
vcc.options.linker = "--platform:x86 /nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
vcc.cpp.options.linker = "--platform:x86 /nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
@elif amd64:
vcc.options.always %= "--platform:amd64 ${vcc.options.always}"
vcc.cpp.options.always %= "--platform:amd64 ${vcc.cpp.options.always}"
vcc.options.linker %= "--platform:amd64 ${vcc.options.linker}"
vcc.cpp.options.linker %= "--platform:amd64 ${vcc.cpp.options.linker}"
vcc.options.always = "--platform:amd64 /nologo"
vcc.cpp.options.always = "--platform:amd64 /nologo /EHsc"
vcc.options.linker = "--platform:amd64 /nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
vcc.cpp.options.linker = "--platform:amd64 /nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
@elif arm:
vcc.options.always %= "--platform:arm ${vcc.options.always}"
vcc.cpp.options.always %= "--platform:arm ${vcc.cpp.options.always}"
vcc.options.linker %= "--platform:arm ${vcc.options.linker}"
vcc.cpp.options.linker %= "--platform:arm ${vcc.cpp.options.linker}"
vcc.options.always = "--platform:arm /nologo"
vcc.cpp.options.always = "--platform:arm /nologo /EHsc"
vcc.options.linker = "--platform:arm /nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
vcc.cpp.options.linker = "--platform:arm /nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
@else:
vcc.options.always = "/nologo"
vcc.cpp.options.always = "/nologo /EHsc"
vcc.options.linker = "/nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
vcc.cpp.options.linker = "/nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB
@end
vcc.options.debug = "/Od"
vcc.cpp.options.debug = "/Od"
vcc.options.speed = "/O2"
vcc.options.debug = "/Zi /FS /Od"
vcc.cpp.options.debug = "/Zi /FS /Od"
vcc.options.speed = "/O2"
vcc.cpp.options.speed = "/O2"
vcc.options.size = "/O1"
vcc.options.size = "/O1"
vcc.cpp.options.size = "/O1"
# Configuration for the Tiny C Compiler:

View File

@@ -154,7 +154,7 @@ proc bundleNimsuggest() =
nimCompile("nimsuggest/nimsuggest.nim", options = "-d:release")
proc buildVccTool() =
nimCompile("tools/vccenv/vccexe.nim")
nimCompile("tools/vccexe/vccexe.nim")
proc bundleWinTools() =
# TODO: consider building under `bin` instead of `.`

View File

@@ -1,59 +0,0 @@
import strtabs, os, osproc, streams, strutils
const
comSpecEnvKey = "ComSpec"
vsComnToolsEnvKeys = [
"VS150COMNTOOLS",
"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 = ""): 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)]

View File

@@ -1,66 +0,0 @@
import strutils, strtabs, os, osproc, vccenv
when defined(release):
let vccOptions = {poParentStreams}
else:
let vccOptions = {poEchoCmd, poParentStreams}
const
platformPrefix = "--platform"
winstorePrefix = "--winstore"
sdkversionPrefix = "--sdkversion"
platformSepIdx = platformPrefix.len
sdkversionSepIdx = sdkversionPrefix.len
HelpText = """
+-----------------------------------------------------------------+
| Microsoft C/C++ compiler wrapper for Nim |
| (c) 2016 Fredrik Høisæther Rasch |
+-----------------------------------------------------------------+
Usage:
vccexe [options] [compileroptions]
Options:
--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
--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
"""
when isMainModule:
var platformArg: string = ""
var sdkVersionArg: string = ""
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
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 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()

47
tools/vccexe/vccenv.nim Normal file
View File

@@ -0,0 +1,47 @@
## VCC compiler backend installation discovery using Visual Studio common tools
## environment variables.
import os
type
VccEnvVersion* = enum ## The version of the Visual Studio C/C++ Developer Environment to load
## Valid versions are Versions of Visual Studio that permanently set a COMNTOOLS
## environment variable. That includes Visual Studio version up to and including
## Visual Studio 2015
vsUndefined = (0, ""), ## Version not specified, use latest recogized version on the system
vs90 = (90, "VS90COMNTOOLS"), ## Visual Studio 2008
vs100 = (100, "VS100COMNTOOLS"), ## Visual Studio 2010
vs110 = (110, "VS110COMNTOOLS"), ## Visual Studio 2012
vs120 = (120, "VS120COMNTOOLS"), ## Visual Studio 2013
vs140 = (140, "VS140COMNTOOLS") ## Visual Studio 2015
const
vcvarsallRelativePath = joinPath("..", "..", "VC", "vcvarsall") ## Relative path from the COMNTOOLS path to the vcvarsall file.
proc vccEnvVcVarsAllPath*(version: VccEnvVersion = vsUndefined): string =
## Returns the path to the VCC Developer Command Prompt executable for the specified VCC version.
##
## Returns `nil` if the specified VCC compiler backend installation was not found.
##
## If the `version` parameter is omitted or set to `vsUndefined`, `vccEnvVcVarsAllPath` searches
## for the latest recognizable version of the VCC tools it can find.
##
## `vccEnvVcVarsAllPath` uses the COMNTOOLS environment variables to find the Developer Command Prompt
## executable path. The COMNTOOLS environment variable are permanently set when Visual Studio is installed.
## Each version of Visual Studio has its own COMNTOOLS environment variable. E.g.: Visual Studio 2015 sets
## The VS140COMNTOOLS environment variable.
##
## Note: Beginning with Visual Studio 2017, the installers no longer set environment variables to allow for
## multiple side-by-side installations of Visual Studio. Therefore, `vccEnvVcVarsAllPath` cannot be used
## to detect the VCC Developer Command Prompt executable path for Visual Studio 2017 and later.
if version == vsUndefined:
for tryVersion in [vs140, vs120, vs110, vs100, vs90]:
let tryPath = vccEnvVcVarsAllPath(tryVersion)
if tryPath.len > 0:
result = tryPath
else: # Specific version requested
let key = $version
let val = getEnv key
if val.len > 0:
result = expandFilename(val & vcvarsallRelativePath)

188
tools/vccexe/vccexe.nim Normal file
View File

@@ -0,0 +1,188 @@
import strutils, strtabs, os, osproc, vcvarsall, vccenv
type
VccVersion* = enum ## VCC compiler backend versions
vccUndefined = (0, ""), ## VCC version undefined, resolves to the latest recognizable VCC version
vcc90 = vs90, ## Visual Studio 2008 (Version 9.0)
vcc100 = vs100, ## Visual Studio 2010 (Version 10.0)
vcc110 = vs110, ## Visual Studio 2012 (Version 11.0)
vcc120 = vs120, ## Visual Studio 2013 (Version 12.0)
vcc140 = vs140 ## Visual Studio 2015 (Version 14.0)
proc discoverVccVcVarsAllPath*(version: VccVersion = vccUndefined): string =
## Returns the path to the vcvarsall utility of the specified VCC compiler backend.
##
## version
## The specific version of the VCC compiler backend to discover.
## Defaults to the latest recognized VCC compiler backend that is found on the system.
##
## Returns `nil` if the VCC compiler backend discovery failed.
# TODO: Attempt discovery using vswhere utility.
# Attempt discovery through VccEnv
# (Trying Visual Studio Common Tools Environment Variables)
result = vccEnvVcVarsAllPath(cast[VccEnvVersion](version))
if result.len > 0:
return
# All attempts to dicover vcc failed
const
vccversionPrefix = "--vccversion"
printPathPrefix = "--printPath"
vcvarsallPrefix = "--vcvarsall"
commandPrefix = "--command"
noCommandPrefix = "--noCommand"
platformPrefix = "--platform"
sdktypePrefix = "--sdktype"
sdkversionPrefix = "--sdkversion"
verbosePrefix = "--verbose"
vccversionSepIdx = vccversionPrefix.len
vcvarsallSepIdx = vcvarsallPrefix.len
commandSepIdx = commandPrefix.len
platformSepIdx = platformPrefix.len
sdktypeSepIdx = sdktypePrefix.len
sdkversionSepIdx = sdkversionPrefix.len
helpText = """
+-----------------------------------------------------------------+
| Microsoft C/C++ compiler wrapper for Nim |
| & |
| Microsoft C/C++ Compiler Discovery Utility |
| (c) 2017 Fredrik Hoeisaether Rasch |
+-----------------------------------------------------------------+
Usage:
vccexe [options] [compileroptions]
Options:
--vccversion:<v> Optionally specify the VCC version to discover
<v>: 0, 90, 100, 110, 120, 140
If <v> is omitted, attempts to discover the latest
installed version. <v>: 0, 90, 100, 110, 120, 140
A value of 0 will discover the latest installed SDK
Multiple values can be specified, separated by ,
--printPath Print the discovered path of the vcvarsall utility
of the VCC version specified with the --vccversion argument.
For each specified version the utility prints a line with the
following format: <version>: <path>
--noCommand Flag to supress VCC secondary command execution
Useful in conjuction with --vccversion and --printPath to
only perfom VCC discovery, but without executing VCC tools
--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
--verbose Echoes the command line for loading the Developer Command Prompt
and the command line passed on to the secondary command.
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 vccversionArg: seq[string] = @[]
var printPathArg: bool = false
var vcvarsallArg: string = nil
var commandArg: string = nil
var noCommandArg: bool = false
var platformArg: VccArch
var sdkTypeArg: VccPlatformType
var sdkVersionArg: string = nil
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:
# Check whether the current argument contains -- prefix
if wargv.startsWith(vccversionPrefix): # Check for vccversion
vccversionArg.add(wargv.substr(vccversionSepIdx + 1))
elif wargv.cmpIgnoreCase(printPathPrefix) == 0: # Check for printPath
printPathArg = true
elif 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.cmpIgnoreCase(noCommandPrefix) == 0: # Check for noCommand
noCommandArg = true
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)
elif wargv.startsWith(verbosePrefix):
verboseArg = true
else: # Regular cl.exe argument -> store for final cl.exe invocation
if (wargv.len == 2) and (wargv[1] == '?'):
echo helpText
clArgs.add(wargv)
# Support for multiple specified versions. Attempt VCC discovery for each version
# specified, first successful discovery wins
var vccversionValue: VccVersion = vccUndefined
for vccversionItem in vccversionArg:
try:
vccversionValue = cast[VccVersion](parseInt(vccversionItem))
except ValueError:
continue
vcvarsallArg = discoverVccVcVarsAllPath(vccversionValue)
if vcvarsallArg.len > 0:
break
# VCC version not specified, discover latest (call discover without args)
if vcvarsallArg.len < 1 and vccversionArg.len < 1:
vccversionValue = vccUndefined
vcvarsallArg = discoverVccVcVarsAllPath()
if printPathArg:
var head = $vccversionValue
if head.len < 1:
head = "latest"
echo "$1: $2" % [head, vcvarsallArg]
# Call vcvarsall to get the appropiate VCC process environment
var vcvars = vccVarsAll(vcvarsallArg, platformArg, sdkTypeArg, sdkVersionArg, verboseArg)
if vcvars != nil:
for vccEnvKey, vccEnvVal in vcvars:
putEnv(vccEnvKey, vccEnvVal)
var vccOptions = {poParentStreams}
if verboseArg:
vccOptions.incl poEchoCmd
# Default to the cl.exe command if no secondary command was specified
if commandArg.len < 1:
commandArg = "cl.exe"
if not noCommandArg:
# Run VCC command with the VCC process environment
let vccProcess = startProcess(
commandArg,
args = clArgs,
options = vccOptions
)
quit vccProcess.waitForExit()

View File

@@ -0,0 +1,99 @@
## VCC Developer Command Prompt Loader
##
## In order for the VCC compiler backend to work properly, it requires numerous
## environment variables to be set properly for the desired architecture and compile target.
## For that purpose the VCC compiler ships with the vcvarsall utility which is an executable
## batch script that can be used to properly set up an Command Prompt environment.
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 ## The VCC compile target architectures
vccarchUnspecified = "",
vccarchX86 = "x86", ## VCC for compilation against the x86 architecture.
vccarchAmd64 = "amd64", ## VCC for compilation against the amd64 architecture.
vccarchX86Amd64 = "x86_amd64", ## VCC cross-compilation tools using x86 VCC for compilation against the amd64 architecture.
vccarchX86Arm = "x86_arm", ## VCC cross-compilation tools using x86 VCC for compilation against the ARM architecture.
vccarchX86Arm64 = "x86_arm64", ## VCC cross-compilation tools using x86 VCC for compilation against the ARM (64-bit) architecture.
vccarchAmd64X86 = "amd64_x86", ## VCC cross-compilation tools using amd64 VCC for compilation against the x86 architecture.
vccarchAmd64Arm = "amd64_arm", ## VCC cross-compilation tools using amd64 VCC for compilation against the ARM architecture.
vccarchAmd64Arm64 = "amd64_arm64", ## VCC cross-compilation tools using amd64 VCC for compilation against the ARM (64-bit) architecture.
vccarchX64 = "x64", ## VCC for compilation against the x64 architecture.
vccarchX64X86 = "x64_x86", ## VCC cross-compilation tools using x64 VCC for compilation against the x86 architecture.
vccarchX64Arm = "x64_arm", ## VCC cross-compilation tools using x64 VCC for compilation against the ARM architecture.
vccarchX64Arm64 = "x64_arm64" ## VCC cross-compilation tools using x64 VCC for compilation against the ARM (64-bit) architecture.
VccPlatformType* = enum ## The VCC platform type of the compile target
vccplatEmpty = "", ## Default (i.e. Desktop) Platfor Type
vccplatStore = "store", ## Windows Store Application
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 = nil, 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
## The path to the vcvarsall utility for VCC compiler backend.
## arch
## The compile target CPU architecture. Starting with Visual Studio 2017, this value must be specified and must not be set to `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.
## verbose
## Echo the command-line passed on to the system to load the VCC environment. Defaults to `false`.
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"
# Run the Windows Command Prompt with the /C argument
# Execute vcvarsall with its command-line arguments
# and then execute the SET command to list all environment variables
let comSpecExec = "\"$1\" /C \"$2 && SET\"" % [comSpecCmd, vcvarsExec]
var comSpecOpts = {poEvalCommand, poDemon, poStdErrToStdOut}
if verbose:
comSpecOpts.incl poEchoCmd
let comSpecOut = execProcess(comSpecExec, options = comSpecOpts)
result = newStringTable(modeCaseInsensitive)
# Parse the output of the final SET command to construct a String Table
# with the appropiate environment variables
for line in comSpecOut.splitLines:
let idx = line.find('=')
if idx > 0:
result[line[0..(idx - 1)]] = line[(idx + 1)..(line.len - 1)]
elif verbose:
echo line