Skip to content

Commit

Permalink
Support specifying the visual studio version (#52)
Browse files Browse the repository at this point in the history
* feat: support specifying the visual studio version

* fix: add upper bound for vswhere -version
  • Loading branch information
aminya committed Aug 28, 2022
1 parent 9f8ae83 commit 357f053
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ jobs:
- `uwp` – set `true` to build for Universal Windows Platform (i.e., for Windows Store)
- `spectre` – set `true` to use Visual Studio libraries with [Spectre](https://meltdownattack.com) mitigations

- `vsversion` - The Visual Studio version to use. This can be the version number (e.g. 16.0 for 2019) or the year (e.g. "2019").

## Caveats

### Name conflicts with `shell: bash`
Expand Down
2 changes: 2 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ inputs:
description: VC++ compiler toolset version
uwp:
description: Build for Universal Windows Platform
vsversion:
description: The Visual Studio version to use. This can be the version number (e.g. 16.0 for 2019) or the year (e.g. "2019").
runs:
using: node12
main: index.js
Expand Down
65 changes: 56 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,67 @@ const PROGRAM_FILES = [process.env['ProgramFiles(x86)'], process.env['ProgramFil


const EDITIONS = ['Enterprise', 'Professional', 'Community']
const VERSIONS = ['2022', '2019', '2017']
const YEARS = ['2022', '2019', '2017']

const VsYearVersion = {
'2022': '17.0',
'2019': '16.0',
'2017': '15.0',
'2015': '14.0',
'2013': '12.0',
}

function vsversion_to_versionnumber(vsversion) {
if (Object.values(VsYearVersion).includes(vsversion)) {
return vsversion
} else {
if (vsversion in VsYearVersion) {
return VsYearVersion[vsversion]
}
}
return vsversion
}
exports.vsversion_to_versionnumber = vsversion_to_versionnumber

function vsversion_to_year(vsversion) {
if (Object.keys(VsYearVersion).includes(vsversion)) {
return vsversion
} else {
for (const [year, ver] of Object.entries(VsYearVersion)) {
if (ver === vsversion) {
return year
}
}
}
return vsversion
}
exports.vsversion_to_year = vsversion_to_year

const VSWHERE_PATH = `${PROGRAM_FILES_X86}\\Microsoft Visual Studio\\Installer`

function findWithVswhere(pattern) {
function findWithVswhere(pattern, version_pattern) {
try {
let installationPath = child_process.execSync(`vswhere -products * -latest -prerelease -property installationPath`).toString().trim()
let installationPath = child_process.execSync(`vswhere -products * ${version_pattern} -prerelease -property installationPath`).toString().trim()
return installationPath + '\\' + pattern
} catch (e) {
core.warning(`vswhere failed: ${e}`)
}
return null
}
exports.findWithVswhere = findWithVswhere

function findVcvarsall(vsversion) {
const vsversion_number = vsversion_to_versionnumber(vsversion)
let version_pattern
if (vsversion_number) {
const upper_bound = vsversion_number.split('.')[0] + '.9'
version_pattern = `-version "${vsversion_number},${upper_bound}"`
} else {
version_pattern = "-latest"
}

function findVcvarsall() {
// If vswhere is available, ask it about the location of the latest Visual Studio.
let path = findWithVswhere('VC\\Auxiliary\\Build\\vcvarsall.bat')
let path = findWithVswhere('VC\\Auxiliary\\Build\\vcvarsall.bat', version_pattern)
if (path && fs.existsSync(path)) {
core.info(`Found with vswhere: ${path}`)
return path
Expand All @@ -34,8 +78,9 @@ function findVcvarsall() {

// If that does not work, try the standard installation locations,
// starting with the latest and moving to the oldest.
const years = vsversion ? [vsversion_to_year(vsversion)] : YEARS
for (const prog_files of PROGRAM_FILES) {
for (const ver of VERSIONS) {
for (const ver of years) {
for (const ed of EDITIONS) {
path = `${prog_files}\\Microsoft Visual Studio\\${ver}\\${ed}\\VC\\Auxiliary\\Build\\vcvarsall.bat`
core.info(`Trying standard location: ${path}`)
Expand All @@ -58,6 +103,7 @@ function findVcvarsall() {

throw new Error('Microsoft Visual Studio not found')
}
exports.findVcvarsall = findVcvarsall

function isPathVariable(name) {
const pathLikeVariables = ['PATH', 'INCLUDE', 'LIB', 'LIBPATH']
Expand All @@ -75,7 +121,7 @@ function filterPathValue(path) {
}

/** See https://github.com/ilammy/msvc-dev-cmd#inputs */
function setupMSVCDevCmd(arch, sdk, toolset, uwp, spectre) {
function setupMSVCDevCmd(arch, sdk, toolset, uwp, spectre, vsversion) {
if (process.platform != 'win32') {
core.info('This is not a Windows virtual environment, bye!')
return
Expand Down Expand Up @@ -114,7 +160,7 @@ function setupMSVCDevCmd(arch, sdk, toolset, uwp, spectre) {
args.push('-vcvars_spectre_libs=spectre')
}

const vcvars = `"${findVcvarsall()}" ${args.join(' ')}`
const vcvars = `"${findVcvarsall(vsversion)}" ${args.join(' ')}`
core.debug(`vcvars command-line: ${vcvars}`)

const cmd_output_string = child_process.execSync(`set && cls && ${vcvars} && cls && set`, {shell: "cmd"}).toString()
Expand Down Expand Up @@ -184,8 +230,9 @@ function main() {
const toolset = core.getInput('toolset')
const uwp = core.getInput('uwp')
const spectre = core.getInput('spectre')
const vsversion = core.getInput('vsversion')

setupMSVCDevCmd(arch, sdk, toolset, uwp, spectre)
setupMSVCDevCmd(arch, sdk, toolset, uwp, spectre, vsversion)
}

try {
Expand Down

0 comments on commit 357f053

Please sign in to comment.