Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect VS2017 #1103

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
gyp/test
node_modules
test/.node-gyp
!test/node_modules
build/
76 changes: 14 additions & 62 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ var fs = require('graceful-fs')
, mkdirp = require('mkdirp')
, exec = require('child_process').exec
, processRelease = require('./process-release')
, win = process.platform === 'win32'
, win = process.platform === 'win32';
if (win)
var findVS = require('windows-autoconf')

exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'

Expand Down Expand Up @@ -106,7 +108,7 @@ function build (gyp, argv, callback) {
which(command, function (err, execPath) {
if (err) {
if (win && /not found/.test(err.message)) {
// On windows and no 'msbuild' found. Let's guess where it is
log.verbose('could not find "msbuild.exe" in PATH - finding location in registry')
findMsbuild()
} else {
// Some other error or 'make' not found on Unix, report that to the user
Expand All @@ -122,68 +124,18 @@ function build (gyp, argv, callback) {
/**
* Search for the location of "msbuild.exe" file on Windows.
*/

function findMsbuild () {
if (config.variables.msbuild_path) {
command = config.variables.msbuild_path
log.verbose('using MSBuild:', command)
copyNodeLib()
return
}

log.verbose('could not find "msbuild.exe" in PATH - finding location in registry')
var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?'
var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s'
if (process.arch !== 'ia32')
cmd += ' /reg:32'
exec(cmd, function (err, stdout, stderr) {
if (err) {
return callback(new Error(err.message + '\n' + notfoundErr))
var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio installed?'
try {
var msbuild_path = findVS.locateMsbuild()
if (!msbuild_path) {
return callback(new Error(notfoundErr))
}
var reVers = /ToolsVersions\\([^\\]+)$/i
, rePath = /\r\n[ \t]+MSBuildToolsPath[ \t]+REG_SZ[ \t]+([^\r]+)/i
, msbuilds = []
, r
, msbuildPath
stdout.split('\r\n\r\n').forEach(function(l) {
if (!l) return
l = l.trim()
if (r = reVers.exec(l.substring(0, l.indexOf('\r\n')))) {
var ver = parseFloat(r[1], 10)
if (ver >= 3.5) {
if (r = rePath.exec(l)) {
msbuilds.push({
version: ver,
path: r[1]
})
}
}
}
})
msbuilds.sort(function (x, y) {
return (x.version < y.version ? -1 : 1)
})
;(function verifyMsbuild () {
if (!msbuilds.length) return callback(new Error(notfoundErr))
msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe')
fs.stat(msbuildPath, function (err, stat) {
if (err) {
if (err.code == 'ENOENT') {
if (msbuilds.length) {
return verifyMsbuild()
} else {
callback(new Error(notfoundErr))
}
} else {
callback(err)
}
return
}
command = msbuildPath
copyNodeLib()
})
})()
})
} catch (e) {
return callback(new Error(err.message + '\n' + notfoundErr))
}
command = msbuild_path
copyNodeLib()
}

/**
Expand Down
57 changes: 26 additions & 31 deletions lib/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var fs = require('graceful-fs')
, findNodeDirectory = require('./find-node-directory')
, msgFormat = require('util').format
if (win)
var findVS2017 = require('./find-vs2017')
var findVS = require('windows-autoconf')

exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module'

Expand All @@ -41,15 +41,13 @@ function configure (gyp, argv, callback) {
callback(err)
} else {
python = found
// 'python' should be set by now
process.env.PYTHON = python
getNodeDir()
}
})

function getNodeDir () {

// 'python' should be set by now
process.env.PYTHON = python

if (gyp.opts.nodedir) {
// --nodedir was specified. use that for the dev files
nodeDir = gyp.opts.nodedir.replace(/^~/, osenv.home())
Expand Down Expand Up @@ -88,22 +86,29 @@ function configure (gyp, argv, callback) {
mkdirp(buildDir, function (err, isNew) {
if (err) return callback(err)
log.verbose('build dir', '"build" dir needed to be created?', isNew)
if (win && (!gyp.opts.msvs_version || gyp.opts.msvs_version === '2017')) {
findVS2017(function (err, vsSetup) {
if (err) {
log.verbose('Not using VS2017:', err.message)
createConfigFile()
} else {
createConfigFile(null, vsSetup)
}
})
} else {
createConfigFile()
}
createConfigFile()
})
}

function createConfigFile (err, vsSetup) {
function findVisualStudio2017 (defaults) {
if (gyp.opts.msvs_version && gyp.opts.msvs_version !== '2017')
return

try {
var vsSetup = findVS.getVS2017Setup()
if (!vsSetup || !vsSetup.InstallationPath) return
} catch (_) {
return
}

gyp.opts.msvs_version = '2015'
process.env['GYP_MSVS_VERSION'] = 2015
process.env['GYP_MSVS_OVERRIDE_PATH'] = vsSetup.InstallationPath
defaults['msbuild_toolset'] = 'v141'
defaults['msvs_windows_target_platform_version'] = vsSetup.SDK
}

function createConfigFile (err) {
if (err) return callback(err)

var configFilename = 'config.gypi'
Expand Down Expand Up @@ -150,18 +155,8 @@ function configure (gyp, argv, callback) {
// disable -T "thin" static archives by default
variables.standalone_static_library = gyp.opts.thin ? 0 : 1

if (vsSetup) {
// GYP doesn't (yet) have support for VS2017, so we force it to VS2015
// to avoid pulling a floating patch that has not landed upstream.
// Ref: https://chromium-review.googlesource.com/#/c/433540/
gyp.opts.msvs_version = '2015'
process.env['GYP_MSVS_VERSION'] = 2015
process.env['GYP_MSVS_OVERRIDE_PATH'] = vsSetup.path
defaults['msbuild_toolset'] = 'v141'
defaults['msvs_windows_target_platform_version'] = vsSetup.sdk
variables['msbuild_path'] = path.join(vsSetup.path, 'MSBuild', '15.0',
'Bin', 'MSBuild.exe')
}
if (win)
findVisualStudio2017(defaults)

// loop through the rest of the opts and add the unknown ones as variables.
// this allows for module-specific configure flags like:
Expand Down Expand Up @@ -227,7 +222,7 @@ function configure (gyp, argv, callback) {
}

function hasMsvsVersion () {
return argv.some(function (arg) {
return argv.find(function (arg) {
return arg.indexOf('msvs_version') === 0
})
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"rimraf": "2",
"semver": "~5.3.0",
"tar": "^2.0.0",
"windows-autoconf": "^1.10.0",
"which": "1"
},
"engines": {
Expand Down