From ab7b3d6876705eca6f9530750685a844fa5f23b6 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Thu, 2 Feb 2017 11:12:16 -0500 Subject: [PATCH] Use minimal EXE tool to extract VS2017 location and version --- lib/find-vs2017.js | 151 +++++++------------------------ tools/Setup.Configuration.VC.exe | Bin 0 -> 30720 bytes 2 files changed, 34 insertions(+), 117 deletions(-) create mode 100644 tools/Setup.Configuration.VC.exe diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js index 6464c3f6a0..3e1aa38e63 100644 --- a/lib/find-vs2017.js +++ b/lib/find-vs2017.js @@ -1,7 +1,5 @@ module.exports = { locateMsbuild: locateMsbuild, - locateVS2017: locateVS2017, - getVS2017WinSDKVersion: getVS2017WinSDKVersion, setGypVS2017Env: setGypVS2017Env } @@ -9,130 +7,49 @@ var log = require('npmlog') , fs = require('fs') , path = require('path') , cp = require('child_process') - , win = process.platform == 'win32' - , msgFormat = require('util').format - , findPython = require('./find-python') -var vs2017_install_path - , vs2017_win_sdk_ver - -function run_locate(gyp, callback) { - if (!win) { - return callback(null, '', '') +var vs2017Setup + +function tryVS7 (gyp) { + if (vs2017Setup) return vs2017Setup; + try { + const regQuery = path.join(__dirname, '..', 'tools', 'Setup.Configuration.VC.exe'); + const vsSetupRaw = cp.execSync(regQuery).toString(); + if (!vsSetupRaw) return; + const vsSetup = vsSetupRaw.split(/[\r|\n]/g).reduce((s, l) => { + const lParts = l.split(': '); + if (lParts.length > 1) s[lParts[0]] = lParts[1]; + return s; + }, {}); + return vs2017Setup = vsSetup; + } catch (e) { + gyp.log.verbose('try VS7', 'Couldn\'t find VS2017 :('); } - - if (vs2017_install_path || vs2017_install_path === '') { - return callback(null, vs2017_install_path, vs2017_win_sdk_ver) - } - - var python = gyp.opts.python || process.env.PYTHON || 'python2' - , findvc_path = path.join(__dirname, '..', 'find_vs2017.py') - - findPython(python, locate_vc); - - function locate_vc(err, python_bin) { - if (err) { - return callback(err) - } - - log.verbose('find vs2017', 'obtaining vs2017 install path using script %s', - findvc_path) - cp.execFile(python_bin, [findvc_path], function(err, stdout, stderr) { - if (err) { - return callback(err) - } - if (stdout) { - vs2017_install_path = stdout.split('\r\n')[0] - log.verbose('find vs2017', 'found Visual Studio 2017 in %s', vs2017_install_path) - get_sdk_version(python_bin) - } else { - log.verbose('find vs2017', - 'no valid Visual Studio 2017 installation found') - vs2017_install_path = '' - vs2017_win_sdk_ver = '' - } - }) - } - - function get_sdk_version(python_bin) { - log.verbose('find vs2017', 'obtaining installed Windows SDKs') - cp.execFile(python_bin, [findvc_path, vs2017_install_path], - function(err, stdout, stderr) { - if (err) { - return callback(err) - } - if (stdout) { - vs2017_win_sdk_ver = stdout.split('\r\n')[0] - log.verbose('find vs2017', 'found VS2017 WinSDK %s', vs2017_win_sdk_ver) - } else { - log.verbose('find vs2017', 'no installed sdks found') - } - - callback(null, vs2017_install_path, vs2017_win_sdk_ver) - }) - } - } + function locateMsbuild(gyp, callback) { - run_locate(gyp, function(err, vs_path, sdk) { - if (err) { - return callback(err) - } - if (vs_path === '') { - return callback() - } - var msbuild_location = path.join(vs_path, 'MSBuild', - '15.0', 'Bin', 'MSBuild.exe') - log.verbose('find vs2017', 'looking for msbuild in %s', msbuild_location) - fs.access(msbuild_location, function(err) { - callback(null, err ? null : msbuild_location) - }) - }) -} + var vsSetup = tryVS7(gyp) + if (!vsSetup)return callback() -function locateVS2017(gyp, callback) { - run_locate(gyp, function(err, vs_path, sdk) { - if (err) { - callback(err) - } else { - callback(null, vs_path === '' ? null : vs_path) - } + var msbuild_location = path.join(vsSetup.InstallationPath, 'MSBuild', + '15.0', 'Bin', 'MSBuild.exe') + log.verbose('find vs2017', 'looking for msbuild in %s', msbuild_location) + fs.access(msbuild_location, function(err) { + callback(null, err ? null : msbuild_location) }) } -function getVS2017WinSDKVersion(gyp, callback) { - run_locate(gyp, function(err, vs_path, sdk) { - if (err) { - callback(err) - } else { - callback(null, sdk === '' ? null : sdk) - } - }) -} function setGypVS2017Env(gyp, callback) { - locateVS2017(gyp, setPath) - - function setPath(err, vs_path) { - if (err) { - return callback(err) - } - if (vs_path) { - process.env['vs2017_install'] = vs_path - getVS2017WinSDKVersion(gyp, setSDK) - } else { - callback() - } - } - - function setSDK(err, sdk) { - if (err) { - return callback(err) - } - if (sdk) { - process.env['vs2017_sdk'] = sdk - } - callback() - } + var vsSetup = tryVS7(gyp); + if (!vsSetup)return callback() + + gyp.opts.msvs_version = '2017'; + process.env['vs2017_install'] = vsSetup.InstallationPath; + var sdkRaw = Object.keys(vsSetup).find(k => ~k.indexOf('SDK') && ~k.indexOf('10.')); + var sdkVerbose = sdkRaw.split('_').pop(); + var sdk = sdkVerbose.replace(/\d+$/, '0') + process.env['vs2017_sdk'] = sdk + callback(); } diff --git a/tools/Setup.Configuration.VC.exe b/tools/Setup.Configuration.VC.exe new file mode 100644 index 0000000000000000000000000000000000000000..5cb5bb963708c26c1708ba065249bca30303a357 GIT binary patch literal 30720 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 YOna!fP}5e_vR`#v)q^?+^xy6Jzd|!nIsgCw literal 0 HcmV?d00001