mirror of
https://github.com/ilammy/msvc-dev-cmd.git
synced 2026-09-07 06:07:19 +08:00
840499b504
Recently added Visual Studio location with "vswhere" seems to be very slow when using "-find" with path patterns. As in, 5 minutes slow. vswhere does not provide much insight into why this happens, but I guess that's because filesystem operations (and search in particular) are not very fast on Windows. Improve the search performance by combining vswhere with probing. Use vswhere to locate the installation root, and then probe around for the batch script we need. Also, don't use vswhere for Visual Studio 2015 as it does not seem to work. Rely only on probing here. And also, add some debug logs so that it's possible to track which path has been used, if you're interested in it.
111 lines
3.4 KiB
JavaScript
111 lines
3.4 KiB
JavaScript
const core = require('@actions/core')
|
|
const child_process = require('child_process')
|
|
const exec = require('util').promisify(child_process.exec)
|
|
const fs = require('fs')
|
|
const process = require('process')
|
|
|
|
const EDITIONS = ['Enterprise', 'Professional', 'Community']
|
|
const VERSIONS = ['2019', '2017']
|
|
|
|
const InterestingVariables = [
|
|
'INCLUDE',
|
|
'LIB',
|
|
'LIBPATH',
|
|
'Path',
|
|
'Platform',
|
|
'VisualStudioVersion',
|
|
/^VCTools/,
|
|
/^VSCMD_/,
|
|
/^WindowsSDK/i,
|
|
]
|
|
|
|
function findWithVswhere(pattern) {
|
|
try {
|
|
let installationPath = child_process.execSync(`vswhere -products * -latest -prerelease -property installationPath`).toString().trim()
|
|
return installationPath + '\\' + pattern
|
|
} catch (e) {
|
|
core.warn(`vswhere failed: ${e}`)
|
|
}
|
|
return null
|
|
}
|
|
|
|
function findVcvarsall() {
|
|
// If vswhere is available, ask it about the location of the latest Visual Studio.
|
|
let path = findWithVswhere('VC\\Auxiliary\\Build\\vcvarsall.bat')
|
|
if (path && fs.existsSync(path)) {
|
|
core.debug(`found with vswhere: ${path}`)
|
|
return path
|
|
}
|
|
|
|
// If that does not work, try the standard installation locations,
|
|
// starting with the latest and moving to the oldest.
|
|
const programFiles = process.env['ProgramFiles(x86)']
|
|
for (const ver of VERSIONS) {
|
|
for (const ed of EDITIONS) {
|
|
path = `${programFiles}\\Microsoft Visual Studio\\${ver}\\${ed}\\VC\\Auxiliary\\Build\\vcvarsall.bat`
|
|
if (fs.existsSync(path)) {
|
|
core.debug(`found standard location: ${path}`)
|
|
return path
|
|
}
|
|
}
|
|
}
|
|
|
|
// Special case for Visual Studio 2015 (and maybe earlier), try it out too.
|
|
path = `${programFiles}\\Microsoft Visual C++ Build Tools\\vcbuildtools.bat`
|
|
if (fs.existsSync(path)) {
|
|
core.debug(`found VS 2015: ${path}`)
|
|
return path
|
|
}
|
|
|
|
throw new Error('Microsoft Visual Studio not found')
|
|
}
|
|
|
|
async function main() {
|
|
if (process.platform != 'win32') {
|
|
core.info('This is not a Windows virtual environment, bye!')
|
|
return
|
|
}
|
|
|
|
const arch = core.getInput('arch')
|
|
const sdk = core.getInput('sdk')
|
|
const toolset = core.getInput('toolset')
|
|
const uwp = core.getInput('uwp')
|
|
const spectre = core.getInput('spectre')
|
|
|
|
// Due to the way Microsoft Visual C++ is configured, we have to resort to the following hack:
|
|
// Call the configuration batch file and then output *all* the environment variables.
|
|
|
|
var args = [arch]
|
|
if (uwp == 'true') {
|
|
args.push('uwp')
|
|
}
|
|
if (sdk) {
|
|
args.push(sdk)
|
|
}
|
|
if (toolset) {
|
|
args.push(`-vcvars_ver=${toolset}`)
|
|
}
|
|
if (spectre == 'true') {
|
|
args.push('-vcvars_spectre_libs=spectre')
|
|
}
|
|
|
|
const command = `"${findVcvarsall()}" ${args.join(' ')} && set`
|
|
core.debug(`Running: ${command}`)
|
|
const { stdout } = await exec(command, {shell: "cmd"})
|
|
const environment = stdout.split('\r\n')
|
|
|
|
for (let string of environment) {
|
|
const [name, value] = string.split('=')
|
|
for (let pattern of InterestingVariables) {
|
|
if (name.match(pattern)) {
|
|
core.exportVariable(name, value)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
core.info(`Configured Developer Command Prompt`)
|
|
}
|
|
|
|
main().catch((e) => core.setFailed('Could not setup Developer Command Prompt: ' + e.message))
|