Moved vccenv over to vcvarsall

Updated vccexe with new command-line arguments
This commit is contained in:
Fredrik Høisæther Rasch 2017-03-20 16:23:54 +01:00
commit 9446ae5576
3 changed files with 116 additions and 72 deletions

View file

@ -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)]

View file

@ -1,4 +1,4 @@
import strutils, strtabs, os, osproc, vccenv import strutils, strtabs, os, osproc, vcvarsall
when defined(release): when defined(release):
let vccOptions = {poParentStreams} let vccOptions = {poParentStreams}
@ -6,47 +6,73 @@ else:
let vccOptions = {poEchoCmd, poParentStreams} let vccOptions = {poEchoCmd, poParentStreams}
const const
vcvarsallPrefix = "--vcvarsall"
commandPrefix = "--command"
platformPrefix = "--platform" platformPrefix = "--platform"
winstorePrefix = "--winstore" sdktypePrefix = "--sdktype"
sdkversionPrefix = "--sdkversion" sdkversionPrefix = "--sdkversion"
vcvarsallSepIdx = vcvarsallPrefix.len
commandSepIdx = commandPrefix.len
platformSepIdx = platformPrefix.len platformSepIdx = platformPrefix.len
sdktypeSepIdx = sdktypePrefix.len
sdkversionSepIdx = sdkversionPrefix.len sdkversionSepIdx = sdkversionPrefix.len
HelpText = """ HelpText = """
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
| Microsoft C/C++ compiler wrapper for Nim | | Microsoft C/C++ compiler wrapper for Nim |
| (c) 2016 Fredrik Høisæther Rasch | | (c) 2017 Fredrik Hoeisaether Rasch |
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
Usage: Usage:
vccexe [options] [compileroptions] vccexe [options] [compileroptions]
Options: 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 --platform:<arch> Specify the Compiler Platform Tools architecture
<arch>: x86 | amd64 | arm | x86_amd64 | x86_arm | amd64_x86 | amd64_arm <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: --sdkversion:<v> Use a specific Windows SDK version:
<v> is either the full Windows 10 SDK version number or <v> is either the full Windows 10 SDK version number or
"8.1" to use the windows 8.1 SDK "8.1" to use the windows 8.1 SDK
Other command line arguments are passed on to the 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: 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 sdkVersionArg: string = nil
var storeArg: bool = false
var clArgs: seq[TaintedString] = @[] var clArgs: seq[TaintedString] = @[]
var wrapperArgs = commandLineParams() var wrapperArgs = commandLineParams()
for wargv in wrapperArgs: for wargv in wrapperArgs:
# Check whether the current argument contains -- prefix # Check whether the current argument contains -- prefix
if wargv.startsWith(platformPrefix): # Check for platform if wargv.startsWith(vcvarsallPrefix): # Check for vcvarsall
platformArg = wargv.substr(platformSepIdx + 1) vcvarsallArg = wargv.substr(vcvarsallSepIdx + 1)
elif wargv == winstorePrefix: # Check for winstore elif wargv.startsWith(commandPrefix): # Check for command
storeArg = true 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 elif wargv.startsWith(sdkversionPrefix): # Check for sdkversion
sdkVersionArg = wargv.substr(sdkversionSepIdx + 1) sdkVersionArg = wargv.substr(sdkversionSepIdx + 1)
else: # Regular cl.exe argument -> store for final cl.exe invocation else: # Regular cl.exe argument -> store for final cl.exe invocation
@ -54,10 +80,13 @@ when isMainModule:
echo HelpText echo HelpText
clArgs.add(wargv) clArgs.add(wargv)
var vccEnvStrTab = getVccEnv(platformArg, storeArg, sdkVersionArg) var vcvars = vccVarsAll(vcvarsallArg, platformArg, sdkTypeArg, sdkVersionArg)
if vccEnvStrTab != nil: if vcvars != nil:
for vccEnvKey, vccEnvVal in vccEnvStrTab: for vccEnvKey, vccEnvVal in vcvars:
putEnv(vccEnvKey, vccEnvVal) putEnv(vccEnvKey, vccEnvVal)
if commandArg.len < 1:
commandArg = "cl.exe"
let vccProcess = startProcess( let vccProcess = startProcess(
"cl.exe", "cl.exe",
args = clArgs, args = clArgs,

View file

@ -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)]