mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-18 06:51:18 +00:00
Moved vccenv over to vcvarsall
Updated vccexe with new command-line arguments
This commit is contained in:
@@ -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)]
|
||||
@@ -1,4 +1,4 @@
|
||||
import strutils, strtabs, os, osproc, vccenv
|
||||
import strutils, strtabs, os, osproc, vcvarsall
|
||||
|
||||
when defined(release):
|
||||
let vccOptions = {poParentStreams}
|
||||
@@ -6,47 +6,73 @@ else:
|
||||
let vccOptions = {poEchoCmd, poParentStreams}
|
||||
|
||||
const
|
||||
vcvarsallPrefix = "--vcvarsall"
|
||||
commandPrefix = "--command"
|
||||
platformPrefix = "--platform"
|
||||
winstorePrefix = "--winstore"
|
||||
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) 2016 Fredrik Høisæther Rasch |
|
||||
| (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
|
||||
--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:
|
||||
<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
|
||||
secondary command specified by --command or to the
|
||||
Microsoft (R) C/C++ Optimizing Compiler if no secondary
|
||||
command was specified
|
||||
"""
|
||||
|
||||
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 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
|
||||
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
|
||||
@@ -54,10 +80,13 @@ when isMainModule:
|
||||
echo HelpText
|
||||
clArgs.add(wargv)
|
||||
|
||||
var vccEnvStrTab = getVccEnv(platformArg, storeArg, sdkVersionArg)
|
||||
if vccEnvStrTab != nil:
|
||||
for vccEnvKey, vccEnvVal in vccEnvStrTab:
|
||||
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,
|
||||
|
||||
73
tools/vccenv/vcvarsall.nim
Normal file
73
tools/vccenv/vcvarsall.nim
Normal 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)]
|
||||
Reference in New Issue
Block a user