From 40aa5448043ad25631842a9dcf2ce28e97dc08ff Mon Sep 17 00:00:00 2001 From: Natalie Wolfe Date: Mon, 3 Apr 2017 20:04:18 -0700 Subject: [PATCH 1/3] Prefix build targets with /t: on Windows Currently, on non-Windows platforms, it is possible to have a multi-target native module and specify building just some of the targets using `node-gyp build my_target`. On Windows, however, specifying the target(s) to build requires the [`/t:` or `/target:` flag](https://msdn.microsoft.com/en-us/library/ms164311.aspx). Without this change you will get the error `MSB1008` because MSBuild things you are trying to specify multiple solutions. --- lib/build.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/build.js b/lib/build.js index 5253109857..d0a1370d1d 100644 --- a/lib/build.js +++ b/lib/build.js @@ -24,6 +24,10 @@ function build (gyp, argv, callback) { platformMake = 'gmake' } else if (process.platform.indexOf('bsd') !== -1) { platformMake = 'gmake' + } else if (win && argv.length > 0) { + argv = argv.map(function(target) { + return '/t:' + target + }) } var release = processRelease(argv, gyp, process.version, process.release) From 967674bc8c82e00390a1c37fd64b39f2e6e72ee5 Mon Sep 17 00:00:00 2001 From: Natalie Wolfe Date: Wed, 5 Apr 2017 11:20:04 -0700 Subject: [PATCH 2/3] Add test for specifying target to build --- test/test-addon.js | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/test/test-addon.js b/test/test-addon.js index c2a71f4498..dad49da461 100644 --- a/test/test-addon.js +++ b/test/test-addon.js @@ -9,9 +9,7 @@ var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') test('build simple addon', function (t) { t.plan(3) - // Set the loglevel otherwise the output disappears when run via 'npm test' - var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { + exec(t, ['rebuild'], [], function (err, stdout, stderr) { var logLines = stderr.toString().trim().split(/\r?\n/) var lastLine = logLines[logLines.length-1] t.strictEqual(err, null) @@ -23,6 +21,38 @@ test('build simple addon', function (t) { t.error(error, 'load module') } }) +}) + +test('build specific addon', function (t) { + t.plan(4) + + exec(t, ['clean', 'configure'], [], function (err) { + t.error(err, 'clean build') + + exec(t, ['build'], ['hello'], function (err, stdout, stderr) { + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length-1] + t.strictEqual(err, null) + t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + try { + var binding = require('hello_world') + t.strictEqual(binding.hello(), 'world') + } catch (error) { + t.error(error, 'load module') + } + }) + }) +}) + +function exec(t, cmd, args, cb) { + // Set the loglevel otherwise the output disappears when run via 'npm test' + var toExec = [nodeGyp] + .concat(cmd) + .concat(['-C', addonPath, '--loglevel=verbose']) + .concat(args) + + t.comment(toExec.join(' ')) + var proc = execFile(process.execPath, toExec, cb) proc.stdout.setEncoding('utf-8') proc.stderr.setEncoding('utf-8') -}) +} From 424b24165065d14aea53ee0018743f521be124b5 Mon Sep 17 00:00:00 2001 From: Natalie Wolfe Date: Mon, 10 Apr 2017 10:37:13 -0700 Subject: [PATCH 3/3] Add second target to hello_world module --- .gitignore | 4 +- test/node_modules/hello_world/binding.gyp | 6 +++ test/node_modules/hello_world/world.cc | 12 ++++++ test/node_modules/hello_world/world.js | 3 ++ test/test-addon.js | 34 +++++----------- test/test-specific-addon.js | 48 +++++++++++++++++++++++ 6 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 test/node_modules/hello_world/world.cc create mode 100644 test/node_modules/hello_world/world.js create mode 100644 test/test-specific-addon.js diff --git a/.gitignore b/.gitignore index 6748492014..f0dbe3cbc4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ gyp/test -node_modules +node_modules/* +!test/node_modules/hello_world +build test/.node-gyp diff --git a/test/node_modules/hello_world/binding.gyp b/test/node_modules/hello_world/binding.gyp index 75ca71e090..909c879e4f 100644 --- a/test/node_modules/hello_world/binding.gyp +++ b/test/node_modules/hello_world/binding.gyp @@ -6,6 +6,12 @@ "include_dirs": [ " + +void Method(const Nan::FunctionCallbackInfo& info) { + info.GetReturnValue().Set(Nan::New("hello").ToLocalChecked()); +} + +void Init(v8::Local exports) { + exports->Set(Nan::New("world").ToLocalChecked(), + Nan::New(Method)->GetFunction()); +} + +NODE_MODULE(world, Init) diff --git a/test/node_modules/hello_world/world.js b/test/node_modules/hello_world/world.js new file mode 100644 index 0000000000..9cf58c1fc0 --- /dev/null +++ b/test/node_modules/hello_world/world.js @@ -0,0 +1,3 @@ +'use strict' +var addon = require('bindings')('world'); +exports.world = function() { return addon.world() } diff --git a/test/test-addon.js b/test/test-addon.js index dad49da461..f5c29860df 100644 --- a/test/test-addon.js +++ b/test/test-addon.js @@ -7,40 +7,26 @@ var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') test('build simple addon', function (t) { - t.plan(3) + t.plan(4) - exec(t, ['rebuild'], [], function (err, stdout, stderr) { + exec(t, ['clean', 'rebuild'], [], function (err, stdout, stderr) { var logLines = stderr.toString().trim().split(/\r?\n/) var lastLine = logLines[logLines.length-1] t.strictEqual(err, null) t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') try { - var binding = require('hello_world') - t.strictEqual(binding.hello(), 'world') + var hello = require('hello_world/hello') + t.strictEqual(hello.hello(), 'world') } catch (error) { t.error(error, 'load module') } - }) -}) - -test('build specific addon', function (t) { - t.plan(4) - exec(t, ['clean', 'configure'], [], function (err) { - t.error(err, 'clean build') - - exec(t, ['build'], ['hello'], function (err, stdout, stderr) { - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length-1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - try { - var binding = require('hello_world') - t.strictEqual(binding.hello(), 'world') - } catch (error) { - t.error(error, 'load module') - } - }) + try { + var world = require('hello_world/world') + t.strictEqual(world.world(), 'hello') + } catch (error) { + t.error(error, 'load module') + } }) }) diff --git a/test/test-specific-addon.js b/test/test-specific-addon.js new file mode 100644 index 0000000000..3ddb7b3edf --- /dev/null +++ b/test/test-specific-addon.js @@ -0,0 +1,48 @@ +'use strict' + +var test = require('tape') +var execFile = require('child_process').execFile +var path = require('path') +var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') +var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') + +test('build specific addon', function (t) { + t.plan(5) + + exec(t, ['clean', 'configure'], [], function (err) { + t.error(err, 'clean build') + + exec(t, ['build'], ['hello'], function (err, stdout, stderr) { + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length-1] + t.strictEqual(err, null) + t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + try { + var hello = require('hello_world/hello') + t.strictEqual(hello.hello(), 'world') + } catch (error) { + t.error(error, 'load module') + } + + try { + var world = require('hello_world/world') + t.fail('should not have loaded unbuilt module') + } catch (e) { + t.ok(/Could not locate the bindings file/.test(e), 'should not build world') + } + }) + }) +}) + +function exec(t, cmd, args, cb) { + // Set the loglevel otherwise the output disappears when run via 'npm test' + var toExec = [nodeGyp] + .concat(cmd) + .concat(['-C', addonPath, '--loglevel=verbose']) + .concat(args) + + t.comment(toExec.join(' ')) + var proc = execFile(process.execPath, toExec, cb) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') +}