From 5f924ce62c9bca9ab9c2e547bfb87b9a391271ed Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 30 May 2017 20:52:45 -0400 Subject: [PATCH 01/46] Upgrade to tar v3 Tar version 3 performs better and is more well tested than its predecessor. npm will be using this in the near future, so there is no benefit in shipping a node-gyp that uses the slower and less reliable fstream-based tar. This drops support for node 0.x, and thus should be considered a breaking semver-major change. PR-URL: https://github.com/nodejs/node-gyp/pull/1212 Reviewed-By: Refael Ackermann Reviewed-By: Ben Noordhuis Reviewed-By: Gibson Fahnestock --- lib/install.js | 38 ++++++++++++++++---------------------- package.json | 5 ++--- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/lib/install.js b/lib/install.js index fa2e1c5430..4176a09578 100644 --- a/lib/install.js +++ b/lib/install.js @@ -15,10 +15,8 @@ var fs = require('graceful-fs') , rm = require('rimraf') , path = require('path') , crypto = require('crypto') - , zlib = require('zlib') , log = require('npmlog') , semver = require('semver') - , fstream = require('fstream') , request = require('request') , minimatch = require('minimatch') , mkdir = require('mkdirp') @@ -144,41 +142,33 @@ function install (gyp, argv, callback) { var tarPath = gyp.opts.tarball var badDownload = false , extractCount = 0 - , gunzip = zlib.createGunzip() - , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid }) var contentShasums = {} var expectShasums = {} // checks if a file to be extracted from the tarball is valid. // only .h header files and the gyp files get extracted - function isValid () { - var name = this.path.substring(devDir.length + 1) - var isValid = valid(name) - if (name === '' && this.type === 'Directory') { - // the first directory entry is ok - return true - } + function isValid (path, entry) { + var isValid = valid(path) if (isValid) { - log.verbose('extracted file from tarball', name) + log.verbose('extracted file from tarball', path) extractCount++ } else { // invalid - log.silly('ignoring from tarball', name) + log.silly('ignoring from tarball', path) } return isValid } - gunzip.on('error', cb) - extracter.on('error', cb) - extracter.on('end', afterTarball) - - // download the tarball, gunzip and extract! + // download the tarball and extract! if (tarPath) { - var input = fs.createReadStream(tarPath) - input.pipe(gunzip).pipe(extracter) - return + return tar.extract({ + file: tarPath, + strip: 1, + filter: isValid, + cwd: devDir + }).then(afterTarball, cb) } try { @@ -218,7 +208,11 @@ function install (gyp, argv, callback) { }) // start unzipping and untaring - req.pipe(gunzip).pipe(extracter) + res.pipe(tar.extract({ + strip: 1, + cwd: devDir, + filter: isValid + }).on('close', afterTarball).on('error', cb)) }) // invoked after the tarball has finished being extracted diff --git a/package.json b/package.json index a66a546889..67dafbf502 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "bin": "./bin/node-gyp.js", "main": "./lib/node-gyp.js", "dependencies": { - "fstream": "^1.0.0", "glob": "^7.0.3", "graceful-fs": "^4.1.2", "minimatch": "^3.0.2", @@ -33,11 +32,11 @@ "request": "2", "rimraf": "2", "semver": "~5.3.0", - "tar": "^2.0.0", + "tar": "^3.1.3", "which": "1" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 4.0.0" }, "devDependencies": { "tape": "~4.2.0", From 75cfae290fee1791a23fa68820ae5dd841e93e14 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Tue, 6 Jun 2017 06:58:26 -0400 Subject: [PATCH 02/46] bump to v4.0.0 * dropping support for node < 4 * signal the CI not to test node < 4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67dafbf502..29bee3d615 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "bindings", "gyp" ], - "version": "3.6.2", + "version": "4.0.0", "installVersion": 9, "author": "Nathan Rajlich (http://tootallnate.net)", "repository": { From c84a54194781410743efe353d18ca7d20fc9d3a3 Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Wed, 7 Jun 2017 17:02:57 +0100 Subject: [PATCH 03/46] configure: don't set ensure if tarball is set If you're providing a path to a header tarball to install, you probably want it to always be re-installed. PR-URL: https://github.com/nodejs/node-gyp/pull/1220 Fixes: https://github.com/nodejs/node-gyp/issues/1216 Reviewed-By: Ben Noordhuis Reviewed-By: Refael Ackermann --- lib/configure.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/configure.js b/lib/configure.js index 1351576d12..19374b7275 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -72,8 +72,10 @@ function configure (gyp, argv, callback) { return callback(new Error('Invalid version number: ' + release.version)) } - // ensure that the target node version's dev files are installed - gyp.opts.ensure = true + // If the tarball option is set, always remove and reinstall the headers + // into devdir. Otherwise only install if they're not already there. + gyp.opts.ensure = gyp.opts.tarball ? false : true + gyp.commands.install([ release.version ], function (err, version) { if (err) return callback(err) log.verbose('get node dir', 'target node version installed:', release.versionDir) From d6139b538c2219110048ac6e00b5abbe248433db Mon Sep 17 00:00:00 2001 From: Liu Chao Date: Sat, 20 May 2017 10:10:54 -0400 Subject: [PATCH 04/46] gyp: update xml string encoding conversion * test: build simple addon in path with non-ascii characters * test: add test-charmap.py PR-URL: https://github.com/nodejs/node-gyp/pull/1203 Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/easy_xml.py | 10 ++-- test/fixtures/test-charmap.py | 19 +++++++ test/test-addon.js | 95 +++++++++++++++++++++++++++++++++-- 3 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/test-charmap.py diff --git a/gyp/pylib/gyp/easy_xml.py b/gyp/pylib/gyp/easy_xml.py index 2b0bb60cb4..841f31f925 100644 --- a/gyp/pylib/gyp/easy_xml.py +++ b/gyp/pylib/gyp/easy_xml.py @@ -4,6 +4,7 @@ import re import os +import locale def XmlToString(content, encoding='utf-8', pretty=False): @@ -115,11 +116,10 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, xml_string = XmlToString(content, encoding, pretty) if win32 and os.linesep != '\r\n': xml_string = xml_string.replace('\n', '\r\n') - - try: - xml_string = xml_string.encode(encoding) - except Exception: - xml_string = unicode(xml_string, 'latin-1').encode(encoding) + + default_encoding = locale.getdefaultlocale()[1] + if default_encoding.upper() != encoding.upper(): + xml_string = xml_string.decode(default_encoding).encode(encoding) # Get the old content try: diff --git a/test/fixtures/test-charmap.py b/test/fixtures/test-charmap.py new file mode 100644 index 0000000000..43e0c5ffc8 --- /dev/null +++ b/test/fixtures/test-charmap.py @@ -0,0 +1,19 @@ +import sys +import locale + +reload(sys) + +def main(): + encoding = locale.getdefaultlocale()[1] + sys.setdefaultencoding(encoding) + textmap = { + 'cp936': u'\u4e2d\u6587', + 'cp1252': u'Lat\u012Bna', + 'cp932': u'\u306b\u307b\u3093\u3054' + } + if textmap.has_key(encoding): + print textmap[encoding] + return True + +if __name__ == '__main__': + print main() diff --git a/test/test-addon.js b/test/test-addon.js index c2a71f4498..7ace1caf6a 100644 --- a/test/test-addon.js +++ b/test/test-addon.js @@ -1,10 +1,35 @@ 'use strict' var test = require('tape') -var execFile = require('child_process').execFile var path = require('path') +var fs = require('graceful-fs') +var child_process = require('child_process') var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') +var execFileSync = child_process.execFileSync +var execFile = child_process.execFile + +function runHello() { + var testCode = "console.log(require('hello_world').hello())" + return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString() +} + +function getEncoding() { + var code = 'import locale;print locale.getdefaultlocale()[1]' + return execFileSync('python', ['-c', code]).toString().trim() +} + +function checkCharmapValid() { + var data + try { + data = execFileSync('python', ['fixtures/test-charmap.py'], + { cwd: __dirname }) + } catch (err) { + return false + } + var lines = data.toString().trim().split('\n') + return lines.pop() === 'True' +} test('build simple addon', function (t) { t.plan(3) @@ -16,12 +41,72 @@ test('build simple addon', function (t) { var lastLine = logLines[logLines.length-1] t.strictEqual(err, null) t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + t.strictEqual(runHello().trim(), 'world') + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') +}) + +test('build simple addon in path with non-ascii characters', function (t) { + t.plan(1) + + if (!checkCharmapValid()) { + return t.skip('python console app can\'t encode non-ascii character.') + } + + var testDirNames = { + 'cp936': '文件夹', + 'cp1252': 'Latīna', + 'cp932': 'フォルダ' + } + // Select non-ascii characters by current encoding + var testDirName = testDirNames[getEncoding()] + // If encoding is UTF-8 or other then no need to test + if (!testDirName) { + return t.skip('no need to test') + } + + t.plan(3) + + var data, configPath = path.join(addonPath, 'build', 'config.gypi') + try { + data = fs.readFileSync(configPath, 'utf8') + } catch (err) { + t.error(err) + return + } + var config = JSON.parse(data.replace(/\#.+\n/, '')) + var nodeDir = config.variables.nodedir + var testNodeDir = path.join(addonPath, testDirName) + // Create symbol link to path with non-ascii characters + try { + fs.symlinkSync(nodeDir, testNodeDir, 'dir') + } catch (err) { + switch (err.code) { + case 'EEXIST': break + case 'EPERM': + t.error(err, 'Please try to running console as an administrator') + return + default: + t.error(err) + return + } + } + + var cmd = [nodeGyp, 'rebuild', '-C', addonPath, + '--loglevel=verbose', '-nodedir=' + testNodeDir] + var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { try { - var binding = require('hello_world') - t.strictEqual(binding.hello(), 'world') - } catch (error) { - t.error(error, 'load module') + fs.unlink(testNodeDir) + } catch (err) { + t.error(err) } + + 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') + t.strictEqual(runHello().trim(), 'world') }) proc.stdout.setEncoding('utf-8') proc.stderr.setEncoding('utf-8') From 35e1dbb78e4c194a375bd675aa4421b21a1f4a48 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 6 Jun 2017 18:25:33 -0400 Subject: [PATCH 05/46] doc: headerify the Install instructions Enable linking to the platform specific installation instructions PR-URL: https://github.com/nodejs/node-gyp/pull/1225 Reviewed-By: Refael Ackermann --- README.md | 60 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 03db320900..5ab6b5dbda 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ node-gyp ========= -### Node.js native addon build tool +## Node.js native addon build tool `node-gyp` is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It bundles the [gyp](https://gyp.gsrc.io) @@ -14,7 +14,7 @@ Multiple target versions of node are supported (i.e. `0.8`, ..., `4`, `5`, `6`, etc.), regardless of what version of node is actually installed on your system (`node-gyp` downloads the necessary development files or headers for the target version). -#### Features: +## Features * Easy to use, consistent interface * Same commands to build your module on every platform @@ -32,29 +32,39 @@ $ npm install -g node-gyp You will also need to install: - * On Unix: - * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) - * `make` - * A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org) - * On Mac OS X: - * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on Mac OS X) - * [Xcode](https://developer.apple.com/xcode/download/) - * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` - * This step will install `gcc` and the related toolchain containing `make` - * On Windows: - * Option 1: Install all the required tools and configurations using Microsoft's [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools) using `npm install --global --production windows-build-tools` from an elevated PowerShell or CMD.exe (run as Administrator). - * Option 2: Install tools and configuration manually: - * Visual C++ Build Environment: - * Option 1: Install [Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) using the **Default Install** option. - - * Option 2: Install [Visual Studio 2015](https://www.visualstudio.com/products/visual-studio-community-vs) (or modify an existing installation) and select *Common Tools for Visual C++* during setup. This also works with the free Community and Express for Desktop editions. - - > :bulb: [Windows Vista / 7 only] requires [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773) - - * Install [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` is not supported), and run `npm config set python python2.7` (or see below for further instructions on specifying the proper Python version and path.) - * Launch cmd, `npm config set msvs_version 2015` - - If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips. +### On Unix + + * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) + * `make` + * A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org) + +### On Mac OS X + + * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on Mac OS X) + * [Xcode](https://developer.apple.com/xcode/download/) + * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` + * This step will install `gcc` and the related toolchain containing `make` + +### On Windows + +#### Option 1 + +Install all the required tools and configurations using Microsoft's [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools) using `npm install --global --production windows-build-tools` from an elevated PowerShell or CMD.exe (run as Administrator). + +#### Option 2 + +Install tools and configuration manually: + * Visual C++ Build Environment: + * Option 1: Install [Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) using the **Default Install** option. + + * Option 2: Install [Visual Studio 2015](https://www.visualstudio.com/products/visual-studio-community-vs) (or modify an existing installation) and select *Common Tools for Visual C++* during setup. This also works with the free Community and Express for Desktop editions. + + > :bulb: [Windows Vista / 7 only] requires [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773) + + * Install [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` is not supported), and run `npm config set python python2.7` (or see below for further instructions on specifying the proper Python version and path.) + * Launch cmd, `npm config set msvs_version 2015` + + If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips. If you have multiple Python versions installed, you can identify which Python version `node-gyp` uses by setting the '--python' variable: From 2e40fad2bf50dc41acdeb10edaf3b7d64b411d0b Mon Sep 17 00:00:00 2001 From: Mikeal Rogers Date: Wed, 14 Oct 2015 14:10:13 -0700 Subject: [PATCH 06/46] doc: update proposed DCO and CoC Lifted verbatim from https://github.com/nodejs/node/blob/master/CONTRIBUTING.md then `s/Node.js/node-gyp/`. PR-URL: https://github.com/nodejs/node-gyp/pull/1229 Reviewed-By: Anna Henningsen Reviewed-By: Gibson Fahnestock --- CONTRIBUTING.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..f48786bd84 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,34 @@ +# Contributing to node-gyp + +## Code of Conduct + +Please read the +[Code of Conduct](https://github.com/nodejs/TSC/blob/master/CODE_OF_CONDUCT.md) +which explains the minimum behavior expectations for node-gyp contributors. + + +## Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +* (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +* (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +* (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +* (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. From 7245415296c5f0a97e10dba6dafbaf2332a67578 Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Tue, 4 Jul 2017 07:34:08 +0100 Subject: [PATCH 07/46] doc: add github PR and Issue templates Give users reporting bugs a clearer idea of the info that will be helpful when reporting issues. PR-URL: https://github.com/nodejs/node-gyp/pull/1228 Refs: https://github.com/nodejs/node/tree/master/.github Reviewed-By: Refael Ackermann Reviewed-By: Ben Noordhuis --- .github/ISSUE_TEMPLATE.md | 26 ++++++++++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 17 +++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..dbd053a90b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,26 @@ + + +* **Node Version**: +* **Platform**: +* **Compiler**: +* **Module**: + +
Verbose output (from npm or node-gyp): + + + +``` + +``` + +
+ + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..7a61664287 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,17 @@ + + +##### Checklist + + +- [ ] `npm install && npm test` passes +- [ ] tests are included +- [ ] documentation is changed or added +- [ ] commit message follows [commit guidelines](https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#commit-message-guidelines) + +##### Description of change + + From 63f43c204e4c8958015d55dbf56619aa812327e8 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Thu, 14 Sep 2017 17:23:31 -0400 Subject: [PATCH 08/46] win: run PS with `-NoProfile` PR-URL: https://github.com/nodejs/node-gyp/pull/1292 Refs: https://github.com/nodejs/node-gyp/issues/1195#issuecomment-329574067 Reviewed-By: Ben Noordhuis --- lib/find-vs2017.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js index 8c79e9ec9b..ad46ceaf88 100644 --- a/lib/find-vs2017.js +++ b/lib/find-vs2017.js @@ -6,9 +6,9 @@ function findVS2017(callback) { var ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') var csFile = path.join(__dirname, 'Find-VS2017.cs') - var psArgs = ['-ExecutionPolicy', 'Unrestricted', '-Command', - '&{Add-Type -Path \'' + csFile + - '\'; [VisualStudioConfiguration.Main]::Query()}'] + var psArgs = ['-ExecutionPolicy', 'Unrestricted', '-NoProfile', + '-Command', '&{Add-Type -Path \'' + csFile + '\';' + + '[VisualStudioConfiguration.Main]::Query()}'] log.silly('find vs2017', 'Running', ps, psArgs) var child = execFile(ps, psArgs, { encoding: 'utf8' }, From a8ba5288cb25d4edcafdc75d0cd59b474b7225e8 Mon Sep 17 00:00:00 2001 From: John Barboza Date: Tue, 26 Sep 2017 14:11:39 -0400 Subject: [PATCH 09/46] zos: support platform Initial work to add z/OS support to node-gyp. PR-URL: https://github.com/nodejs/node-gyp/pull/1276 Reviewed-By: Refael Ackermann Reviewed-By: Ben Noordhuis --- addon.gypi | 11 +++++++++++ gyp/pylib/gyp/common.py | 4 ++++ gyp/pylib/gyp/generator/make.py | 31 ++++++++++++++++++++++++++++++- gyp/pylib/gyp/generator/ninja.py | 15 +++++++++++---- lib/configure.js | 17 ++++++++++------- test/fixtures/test-charmap.py | 3 +++ 6 files changed, 69 insertions(+), 12 deletions(-) diff --git a/addon.gypi b/addon.gypi index f2f6a7925e..878f61f3a6 100644 --- a/addon.gypi +++ b/addon.gypi @@ -89,6 +89,17 @@ '-Wl,-bimport:<(node_exp_file)' ], }], + [ 'OS=="zos"', { + 'cflags': [ + '-q64', + '-Wc,DLL', + '-qlonglong' + ], + 'ldflags': [ + '-q64', + '<(node_exp_file)' + ], + }], [ 'OS=="win"', { 'conditions': [ ['node_engine=="chakracore"', { diff --git a/gyp/pylib/gyp/common.py b/gyp/pylib/gyp/common.py index 256e3f3a6b..501118796f 100644 --- a/gyp/pylib/gyp/common.py +++ b/gyp/pylib/gyp/common.py @@ -429,6 +429,10 @@ def GetFlavor(params): return 'netbsd' if sys.platform.startswith('aix'): return 'aix' + if sys.platform.startswith('zos'): + return 'zos' + if sys.platform.startswith('os390'): + return 'zos' return 'linux' diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 64b9dd267b..334d1af726 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -227,6 +227,25 @@ def CalculateGeneratorInputInfo(params): """ +LINK_COMMANDS_OS390 = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) -Wl,DLL + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) -Wl,DLL + +""" + + # Header of toplevel Makefile. # This should go into the build tree, but it's easier to keep it here for now. SHARED_HEADER = ("""\ @@ -310,7 +329,7 @@ def CalculateGeneratorInputInfo(params): # We write to a dep file on the side first and then rename at the end # so we can't end up with a broken dep file. depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw +DEPFLAGS = %(makedep_args)s -MF $(depfile).raw # We have to fixup the deps output in a few ways. # (1) the file output should mention the proper .o file. @@ -2013,6 +2032,7 @@ def CalculateMakefilePath(build_file, base_name): flock_command= 'flock' copy_archive_arguments = '-af' + makedep_arguments = '-MMD' header_params = { 'default_target': default_target, 'builddir': builddir_name, @@ -2023,6 +2043,7 @@ def CalculateMakefilePath(build_file, base_name): 'extra_commands': '', 'srcdir': srcdir, 'copy_archive_args': copy_archive_arguments, + 'makedep_args': makedep_arguments, } if flavor == 'mac': flock_command = './gyp-mac-tool flock' @@ -2036,6 +2057,14 @@ def CalculateMakefilePath(build_file, base_name): header_params.update({ 'link_commands': LINK_COMMANDS_ANDROID, }) + elif flavor == 'zos': + copy_archive_arguments = '-fPR' + makedep_arguments = '-qmakedep=gcc' + header_params.update({ + 'copy_archive_args': copy_archive_arguments, + 'makedep_args': makedep_arguments, + 'link_commands': LINK_COMMANDS_OS390, + }) elif flavor == 'solaris': header_params.update({ 'flock': './gyp-flock-tool flock', diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index 841067ed34..4ee2bd1b4d 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -2238,15 +2238,22 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, 'stamp', description='STAMP $out', command='%s gyp-win-tool stamp $out' % sys.executable) - master_ninja.rule( - 'copy', - description='COPY $in $out', - command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) else: master_ninja.rule( 'stamp', description='STAMP $out', command='${postbuilds}touch $out') + if flavor == 'win': + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) + elif flavor == 'zos': + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='rm -rf $out && cp -fRP $in $out') + else: master_ninja.rule( 'copy', description='COPY $in $out', diff --git a/lib/configure.js b/lib/configure.js index 19374b7275..bc39302979 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -254,18 +254,21 @@ function configure (gyp, argv, callback) { // - the out/Debug directory // - the root directory var node_exp_file = undefined - if (process.platform === 'aix') { + if (process.platform === 'aix' || process.platform === 'os390') { + var ext = process.platform === 'aix' ? 'exp' : 'x' var node_root_dir = findNodeDirectory() - var candidates = ['include/node/node.exp', - 'out/Release/node.exp', - 'out/Debug/node.exp', - 'node.exp'] + var candidates = ['include/node/node', + 'out/Release/node', + 'out/Debug/node', + 'node'].map(function(file) { + return file + '.' + ext + }) var logprefix = 'find exports file' node_exp_file = findAccessibleSync(logprefix, node_root_dir, candidates) if (node_exp_file !== undefined) { log.verbose(logprefix, 'Found exports file: %s', node_exp_file) } else { - var msg = msgFormat('Could not find node.exp file in %s', node_root_dir) + var msg = msgFormat('Could not find node.%s file in %s', ext, node_root_dir) log.error(logprefix, 'Could not find exports file') return callback(new Error(msg)) } @@ -294,7 +297,7 @@ function configure (gyp, argv, callback) { argv.push('-Dlibrary=shared_library') argv.push('-Dvisibility=default') argv.push('-Dnode_root_dir=' + nodeDir) - if (process.platform === 'aix') { + if (process.platform === 'aix' || process.platform === 'os390') { argv.push('-Dnode_exp_file=' + node_exp_file) } argv.push('-Dnode_gyp_dir=' + nodeGypDir) diff --git a/test/fixtures/test-charmap.py b/test/fixtures/test-charmap.py index 43e0c5ffc8..d9fa6fb25e 100644 --- a/test/fixtures/test-charmap.py +++ b/test/fixtures/test-charmap.py @@ -5,6 +5,9 @@ def main(): encoding = locale.getdefaultlocale()[1] + if not encoding: + return False + sys.setdefaultencoding(encoding) textmap = { 'cp936': u'\u4e2d\u6587', From 05d2002258596a9693d6042d573c7fd20449ad23 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 19 Aug 2017 19:54:09 +0200 Subject: [PATCH 10/46] Fix IndexError when parsing GYP files. GYP automatically turns variables ending in _dir, _file or _path into absolute paths but didn't check for empty strings. It interacted badly with variables inherited through the environment from npm, the `scripts-prepend-node-path=false` setting in particular because it is turned into `npm_config_script_prepend_node_path=`. Fixes: https://github.com/nodejs/node-gyp/issues/1217 PR-URL: https://github.com/nodejs/node-gyp/pull/1267 Reviewed-By: Gibson Fahnestock Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index 7567d0a05b..33c5947121 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -2033,7 +2033,7 @@ def MakePathRelative(to_file, fro_file, item): gyp.common.RelativePath(os.path.dirname(fro_file), os.path.dirname(to_file)), item)).replace('\\', '/') - if item[-1] == '/': + if item[-1:] == '/': ret += '/' return ret From 6b68b605ab30fa33ff9690b8326337642812ce31 Mon Sep 17 00:00:00 2001 From: JeffAtDeere Date: Sun, 18 Feb 2018 17:47:56 -0600 Subject: [PATCH 11/46] Update README with another way to install on windows PR-URL: https://github.com/nodejs/node-gyp/pull/1352 --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ab6b5dbda..5c9a9cf418 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,14 @@ Install tools and configuration manually: * Visual C++ Build Environment: * Option 1: Install [Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) using the **Default Install** option. - * Option 2: Install [Visual Studio 2015](https://www.visualstudio.com/products/visual-studio-community-vs) (or modify an existing installation) and select *Common Tools for Visual C++* during setup. This also works with the free Community and Express for Desktop editions. + * Option 2: Install [Visual Studio 2015](https://www.visualstudio.com/products/visual-studio-community-vs) and select *Common Tools for Visual C++* during setup. This also works with the free Community and Express for Desktop editions. + + * Option 3: if you already have Visual Studio 2015 installed and did not install the + *Common Tools for Visual C++* during setup, you can `File -> New -> Project`, pick + any of the options under `Templates -> Other Languages -> Visual C++` then `Ok` + and Visual Studio will offer to install the *Common Tools for Visual C++* with a + "Install Missing Features" / "You need the Universal Windows App Development Tools + to develop Windows app projects." dialog. > :bulb: [Windows Vista / 7 only] requires [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773) From 57279a23fc332c912480b0724df397c17394458b Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 27 Jan 2018 19:04:37 +0100 Subject: [PATCH 12/46] Update `--nodedir` description in README. The description erroneously stated that it should point the node binary. It needs to point to the node source code. PR-URL: https://github.com/nodejs/node-gyp/pull/1372 Reviewed-By: Joyee Cheung Reviewed-By: Richard Lau --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c9a9cf418..cd8e4dceba 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ Command Options | `--dist-url=$url` | Download header tarball from custom URL | `--proxy=$url` | Set HTTP proxy for downloading header tarball | `--cafile=$cafile` | Override default CA chain (to download tarball) -| `--nodedir=$path` | Set the path to the node binary +| `--nodedir=$path` | Set the path to the node source code | `--python=$path` | Set path to the python (2) binary | `--msvs_version=$version` | Set Visual Studio version (win) | `--solution=$solution` | Set Visual Studio Solution version (win) From 8b7ccfec0d71be1250b906ecc4c579a52562ed8a Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 26 Feb 2018 12:13:30 +0100 Subject: [PATCH 13/46] Fix infinite install loop. Retry the download+install dance only once after encountering an EACCES. That only happens when both the devdir (usually: `$HOME/.node-gyp`) and the current working directory aren't writable. Users won't often hit that except through `sudo npm install` because npm drops privileges before executing node-gyp. Fixes: https://github.com/nodejs/node-gyp/issues/1383 PR-URL: https://github.com/nodejs/node-gyp/pull/1384 Reviewed-By: Gibson Fahnestock Reviewed-By: Richard Lau --- lib/install.js | 23 +++++++++++++++-------- test/test-install.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 test/test-install.js diff --git a/lib/install.js b/lib/install.js index 4176a09578..94991c49ad 100644 --- a/lib/install.js +++ b/lib/install.js @@ -1,7 +1,12 @@ +module.exports = exports = function (gyp, argv, callback) { + return install(fs, gyp, argv, callback) +} -module.exports = exports = install - -module.exports.test = { download: download, readCAFile: readCAFile } +module.exports.test = { + download: download, + install: install, + readCAFile: readCAFile, +} exports.usage = 'Install node development files for the specified node version.' @@ -23,7 +28,7 @@ var fs = require('graceful-fs') , processRelease = require('./process-release') , win = process.platform == 'win32' -function install (gyp, argv, callback) { +function install (fs, gyp, argv, callback) { var release = processRelease(argv, gyp, process.version, process.release) @@ -82,7 +87,7 @@ function install (gyp, argv, callback) { log.verbose('install', 'version not already installed, continuing with install', release.version) go() } else if (err.code == 'EACCES') { - eaccesFallback() + eaccesFallback(err) } else { cb(err) } @@ -127,7 +132,7 @@ function install (gyp, argv, callback) { mkdir(devDir, function (err, created) { if (err) { if (err.code == 'EACCES') { - eaccesFallback() + eaccesFallback(err) } else { cb(err) } @@ -403,7 +408,9 @@ function install (gyp, argv, callback) { * the compilation will succeed... */ - function eaccesFallback () { + function eaccesFallback (err) { + var noretry = '--node_gyp_internal_noretry' + if (-1 !== argv.indexOf(noretry)) return cb(err) var tmpdir = osenv.tmpdir() gyp.devDir = path.resolve(tmpdir, '.node-gyp') log.warn('EACCES', 'user "%s" does not have permission to access the dev dir "%s"', osenv.user(), devDir) @@ -412,7 +419,7 @@ function install (gyp, argv, callback) { log.verbose('tmpdir == cwd', 'automatically will remove dev files after to save disk space') gyp.todo.push({ name: 'remove', args: argv }) } - gyp.commands.install(argv, cb) + gyp.commands.install([noretry].concat(argv), cb) } } diff --git a/test/test-install.js b/test/test-install.js new file mode 100644 index 0000000000..f647326a7f --- /dev/null +++ b/test/test-install.js @@ -0,0 +1,37 @@ +'use strict' + +var test = require('tape') +var install = require('../lib/install').test.install + +test('EACCES retry once', function (t) { + t.plan(3) + + var fs = {} + fs.stat = function (path, cb) { + var err = new Error() + err.code = 'EACCES' + cb(err) + t.ok(true); + } + + + var gyp = {} + gyp.devDir = __dirname + gyp.opts = {} + gyp.opts.ensure = true + gyp.commands = {} + gyp.commands.install = function (argv, cb) { + install(fs, gyp, argv, cb) + } + gyp.commands.remove = function (argv, cb) { + cb() + } + + gyp.commands.install([], function (err) { + t.ok(true) + if (/"pre" versions of node cannot be installed/.test(err.message)) { + t.ok(true) + t.ok(true) + } + }) +}) From 3a52936d6cae0b35a4bd486017c7c7a88ae0b415 Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Sun, 21 Jan 2018 17:59:08 +0000 Subject: [PATCH 14/46] gyp: don't print xcodebuild not found errors As node-gyp rebuild doesn't seem to need xcodebuild, we don't need to be printing the error every time GYP is run. PR-URL: https://github.com/nodejs/node-gyp/pull/1370 Fixes: https://github.com/nodejs/node-gyp/issues/569 Refs: https://github.com/nodejs/node-gyp/pull/1057 Refs: https://chromium-review.googlesource.com/c/492046/ --- gyp/pylib/gyp/xcode_emulation.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index b06bdc4e8b..2aca1c762d 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -429,7 +429,7 @@ def _GetSdkVersionInfoItem(self, sdk, infoitem): # Since the CLT has no SDK paths anyway, returning None is the # most sensible route and should still do the right thing. try: - return GetStdout(['xcodebuild', '-version', '-sdk', sdk, infoitem]) + return GetStdoutQuiet(['xcodebuild', '-version', '-sdk', sdk, infoitem]) except: pass @@ -1251,7 +1251,7 @@ def XcodeVersion(): if XCODE_VERSION_CACHE: return XCODE_VERSION_CACHE try: - version_list = GetStdout(['xcodebuild', '-version']).splitlines() + version_list = GetStdoutQuiet(['xcodebuild', '-version']).splitlines() # In some circumstances xcodebuild exits 0 but doesn't return # the right results; for example, a user on 10.7 or 10.8 with # a bogus path set via xcode-select @@ -1301,6 +1301,17 @@ def CLTVersion(): continue +def GetStdoutQuiet(cmdlist): + """Returns the content of standard output returned by invoking |cmdlist|. + Ignores the stderr. + Raises |GypError| if the command return with a non-zero return code.""" + job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out = job.communicate()[0] + if job.returncode != 0: + raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) + return out.rstrip('\n') + + def GetStdout(cmdlist): """Returns the content of standard output returned by invoking |cmdlist|. Raises |GypError| if the command return with a non-zero return code.""" From 91789c22a4307828fbc963f5cebabb97db23b20d Mon Sep 17 00:00:00 2001 From: Josh Parnham Date: Fri, 8 Jun 2018 11:46:16 +1000 Subject: [PATCH 15/46] doc: update macOS information in README PR-URL: https://github.com/nodejs/node-gyp/pull/1323 Fixes: https://github.com/nodejs/node-gyp/issues/1295 Reviewed-By: Ben Noordhuis Reviewed-By: Gibson Fahnestock --- README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cd8e4dceba..bfb687d635 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,12 @@ You will also need to install: * `make` * A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org) -### On Mac OS X +### On macOS - * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on Mac OS X) + * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on macOS) * [Xcode](https://developer.apple.com/xcode/download/) - * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` - * This step will install `gcc` and the related toolchain containing `make` + * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` (or by running `xcode-select --install` in your Terminal) + * This step will install `gcc` and the related toolchain containing `make` ### On Windows @@ -88,10 +88,6 @@ value: $ npm config set python /path/to/executable/python2.7 ``` -Note that OS X is just a flavour of Unix and so needs `python`, `make`, and C/C++. -An easy way to obtain these is to install XCode from Apple, -and then use it to install the command line tools (under Preferences -> Downloads). - How to Use ---------- From 293092c362febffe19f72712467565045e08e8f1 Mon Sep 17 00:00:00 2001 From: Jonas Hermsmeier Date: Tue, 5 Jun 2018 14:41:17 +0200 Subject: [PATCH 16/46] gyp: fix regex to match multi-digit versions This fixes the regular expression matching in `xcode_emulation` to also handle version numbers with multiple-digit major versions which would otherwise break under use of XCode 10 Fixes: https://github.com/nodejs/node-gyp/issues/1454 PR-URL: https://github.com/nodejs/node-gyp/pull/1455 Reviewed-By: Ben Noordhuis --- gyp/pylib/gyp/xcode_emulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index 2aca1c762d..4321f60895 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -1262,7 +1262,7 @@ def XcodeVersion(): except: version = CLTVersion() if version: - version = re.match(r'(\d\.\d\.?\d*)', version).groups()[0] + version = re.match(r'(\d+\.\d+\.?\d*)', version).groups()[0] else: raise GypError("No Xcode or CLT version detected!") # The CLT has no build information, so we return an empty string. From 02ac2e775ac372f56af6b3715d654f857615c341 Mon Sep 17 00:00:00 2001 From: John Barboza Date: Tue, 29 May 2018 14:57:50 -0700 Subject: [PATCH 17/46] zos: add search locations for libnode.x Node.js on z/OS uses shared dll (libnode.so). When linking native addons, node-gyp needs to find the corresponding libnode.x during the link step. PR-URL: https://github.com/nodejs/node-gyp/pull/1451 Reviewed-By: Ben Noordhuis Reviewed-By: Refael Ackermann --- lib/configure.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/configure.js b/lib/configure.js index bc39302979..f4820b514b 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -244,25 +244,29 @@ function configure (gyp, argv, callback) { argv.push('-I', config) }) - // for AIX we need to set up the path to the exp file - // which contains the symbols needed for linking. - // The file will either be in one of the following - // depending on whether it is an installed or - // development environment: - // - the include/node directory - // - the out/Release directory - // - the out/Debug directory - // - the root directory + // For AIX and z/OS we need to set up the path to the exports file + // which contains the symbols needed for linking. var node_exp_file = undefined if (process.platform === 'aix' || process.platform === 'os390') { var ext = process.platform === 'aix' ? 'exp' : 'x' var node_root_dir = findNodeDirectory() - var candidates = ['include/node/node', - 'out/Release/node', - 'out/Debug/node', - 'node'].map(function(file) { - return file + '.' + ext - }) + var candidates = undefined + if (process.platform === 'aix') { + candidates = ['include/node/node', + 'out/Release/node', + 'out/Debug/node', + 'node' + ].map(function(file) { + return file + '.' + ext + }) + } else { + candidates = ['out/Release/obj.target/libnode', + 'out/Debug/obj.target/libnode', + 'lib/libnode' + ].map(function(file) { + return file + '.' + ext + }) + } var logprefix = 'find exports file' node_exp_file = findAccessibleSync(logprefix, node_root_dir, candidates) if (node_exp_file !== undefined) { From eaedc12711a6ea94397f15949591c5a80d077944 Mon Sep 17 00:00:00 2001 From: John Barboza Date: Wed, 30 May 2018 07:38:05 -0700 Subject: [PATCH 18/46] zos: don't use universal-new-lines mode PR-URL: https://github.com/nodejs/node-gyp/pull/1451 Reviewed-By: Ben Noordhuis Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/input.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index 33c5947121..10f6e0dba1 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -233,7 +233,12 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, # Open the build file for read ('r') with universal-newlines mode ('U') # to make sure platform specific newlines ('\r\n' or '\r') are converted to '\n' # which otherwise will fail eval() - build_file_contents = open(build_file_path, 'rU').read() + if sys.platform == 'zos': + # On z/OS, universal-newlines mode treats the file as an ascii file. But since + # node-gyp produces ebcdic files, do not use that mode. + build_file_contents = open(build_file_path, 'r').read() + else: + build_file_contents = open(build_file_path, 'rU').read() else: raise GypError("%s not found (cwd: %s)" % (build_file_path, os.getcwd())) From 206309e5bff7070784f85504b1c409597444a444 Mon Sep 17 00:00:00 2001 From: Julien Racle Date: Fri, 7 Apr 2017 14:00:47 +0200 Subject: [PATCH 19/46] gyp: add support for .mm files to msvs generator PR-URL: https://github.com/nodejs/node-gyp/pull/1167 Reviewed-By: Ben Noordhuis --- gyp/pylib/gyp/generator/msvs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py index 6bfad0f3bd..3901ba9416 100644 --- a/gyp/pylib/gyp/generator/msvs.py +++ b/gyp/pylib/gyp/generator/msvs.py @@ -2118,7 +2118,7 @@ def _MapFileToMsBuildSourceType(source, rule_dependencies, if ext in extension_to_rule_name: group = 'rule' element = extension_to_rule_name[ext] - elif ext in ['.cc', '.cpp', '.c', '.cxx']: + elif ext in ['.cc', '.cpp', '.c', '.cxx', '.mm']: group = 'compile' element = 'ClCompile' elif ext in ['.h', '.hxx']: From 4379c47357223f4227d73dbb978284b75581bef6 Mon Sep 17 00:00:00 2001 From: Natalie Wolfe Date: Mon, 3 Apr 2017 20:04:18 -0700 Subject: [PATCH 20/46] 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 targets to build requires the `/t:` or `/target:` flag. Without this change you will get an `MSB1008` error because MSBuild thinks you are trying to specify multiple solutions. PR-URL: https://github.com/nodejs/node-gyp/pull/1164 Reviewed-By: Ben Noordhuis --- lib/build.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/build.js b/lib/build.js index 0445fb6452..2f8e14c374 100644 --- a/lib/build.js +++ b/lib/build.js @@ -23,6 +23,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 fbecb3872bf81d17b0543e368ce3d70fdf93b271 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Thu, 17 Nov 2016 18:39:58 -0500 Subject: [PATCH 21/46] Fix include path when pointing to Node.js source Header files for deps are in a different location in the Node.js source tree compared to the release tarballs. PR-URL: https://github.com/nodejs/node-gyp/pull/1055 Reviewed-By: Ben Noordhuis --- addon.gypi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addon.gypi b/addon.gypi index 878f61f3a6..55fb321118 100644 --- a/addon.gypi +++ b/addon.gypi @@ -18,7 +18,10 @@ 'include_dirs': [ '<(node_root_dir)/include/node', '<(node_root_dir)/src', + '<(node_root_dir)/deps/openssl/config', + '<(node_root_dir)/deps/openssl/openssl/include', '<(node_root_dir)/deps/uv/include', + '<(node_root_dir)/deps/zlib', '<(node_root_dir)/<(node_engine_include_dir)' ], 'defines!': [ From d70513abce688b50dee94b0f8b046842c22c41ad Mon Sep 17 00:00:00 2001 From: Brian Woodward Date: Mon, 27 Mar 2017 19:44:19 -0400 Subject: [PATCH 22/46] Drop dependency on minimatch. PR-URL: https://github.com/nodejs/node-gyp/pull/1158 Reviewed-By: Ben Noordhuis Reviewed-By: Refael Ackermann --- lib/install.js | 5 ++--- package.json | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/install.js b/lib/install.js index 94991c49ad..8a615dfb38 100644 --- a/lib/install.js +++ b/lib/install.js @@ -23,7 +23,6 @@ var fs = require('graceful-fs') , log = require('npmlog') , semver = require('semver') , request = require('request') - , minimatch = require('minimatch') , mkdir = require('mkdirp') , processRelease = require('./process-release') , win = process.platform == 'win32' @@ -395,8 +394,8 @@ function install (fs, gyp, argv, callback) { function valid (file) { // header files - return minimatch(file, '*.h', { matchBase: true }) || - minimatch(file, '*.gypi', { matchBase: true }) + var extname = path.extname(file); + return extname === '.h' || extname === '.gypi'; } /** diff --git a/package.json b/package.json index 29bee3d615..a8e5fe9f27 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "dependencies": { "glob": "^7.0.3", "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", From 1cf636be3bc2a2c6fcecddb55f823060dbc84b81 Mon Sep 17 00:00:00 2001 From: Jeff Senn Date: Thu, 10 May 2018 15:21:53 -0400 Subject: [PATCH 23/46] gyp: escape spaces in filenames in make generator PR-URL: https://github.com/nodejs/node-gyp/pull/1436 Reviewed-By: Ben Noordhuis --- gyp/pylib/gyp/generator/make.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 334d1af726..8990057a04 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -642,6 +642,9 @@ def Sourceify(path): def QuoteSpaces(s, quote=r'\ '): return s.replace(' ', quote) +def SourceifyAndQuoteSpaces(path): + """Convert a path to its source directory form and quote spaces.""" + return QuoteSpaces(Sourceify(path)) # TODO: Avoid code duplication with _ValidateSourcesForMSVSProject in msvs.py. def _ValidateSourcesForOSX(spec, all_sources): @@ -1964,7 +1967,7 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name, "%(makefile_name)s: %(deps)s\n" "\t$(call do_cmd,regen_makefile)\n\n" % { 'makefile_name': makefile_name, - 'deps': ' '.join(map(Sourceify, build_files)), + 'deps': ' '.join(map(SourceifyAndQuoteSpaces, build_files)), 'cmd': gyp.common.EncodePOSIXShellList( [gyp_binary, '-fmake'] + gyp.RegenerateFlags(options) + From 50b8734a7f79c57603d4d48cb3337713de404384 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 8 Jun 2018 17:01:21 +0200 Subject: [PATCH 24/46] Remove unused gyp test scripts. Shrinks node-gyp's size by about 100 kB. PR-URL: https://github.com/nodejs/node-gyp/pull/1458 Reviewed-By: Richard Lau --- gyp/buildbot/aosp_manifest.xml | 466 ----------------------- gyp/buildbot/buildbot_run.py | 136 ------- gyp/buildbot/commit_queue/OWNERS | 6 - gyp/buildbot/commit_queue/README | 3 - gyp/buildbot/commit_queue/cq_config.json | 15 - gyp/gyptest.py | 274 ------------- 6 files changed, 900 deletions(-) delete mode 100644 gyp/buildbot/aosp_manifest.xml delete mode 100755 gyp/buildbot/buildbot_run.py delete mode 100644 gyp/buildbot/commit_queue/OWNERS delete mode 100644 gyp/buildbot/commit_queue/README delete mode 100644 gyp/buildbot/commit_queue/cq_config.json delete mode 100755 gyp/gyptest.py diff --git a/gyp/buildbot/aosp_manifest.xml b/gyp/buildbot/aosp_manifest.xml deleted file mode 100644 index bd73b303c6..0000000000 --- a/gyp/buildbot/aosp_manifest.xml +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gyp/buildbot/buildbot_run.py b/gyp/buildbot/buildbot_run.py deleted file mode 100755 index 9a2b71f1b3..0000000000 --- a/gyp/buildbot/buildbot_run.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Argument-less script to select what to run on the buildbots.""" - -import os -import shutil -import subprocess -import sys - - -BUILDBOT_DIR = os.path.dirname(os.path.abspath(__file__)) -TRUNK_DIR = os.path.dirname(BUILDBOT_DIR) -ROOT_DIR = os.path.dirname(TRUNK_DIR) -CMAKE_DIR = os.path.join(ROOT_DIR, 'cmake') -CMAKE_BIN_DIR = os.path.join(CMAKE_DIR, 'bin') -OUT_DIR = os.path.join(TRUNK_DIR, 'out') - - -def CallSubProcess(*args, **kwargs): - """Wrapper around subprocess.call which treats errors as build exceptions.""" - with open(os.devnull) as devnull_fd: - retcode = subprocess.call(stdin=devnull_fd, *args, **kwargs) - if retcode != 0: - print '@@@STEP_EXCEPTION@@@' - sys.exit(1) - - -def PrepareCmake(): - """Build CMake 2.8.8 since the version in Precise is 2.8.7.""" - if os.environ['BUILDBOT_CLOBBER'] == '1': - print '@@@BUILD_STEP Clobber CMake checkout@@@' - shutil.rmtree(CMAKE_DIR) - - # We always build CMake 2.8.8, so no need to do anything - # if the directory already exists. - if os.path.isdir(CMAKE_DIR): - return - - print '@@@BUILD_STEP Initialize CMake checkout@@@' - os.mkdir(CMAKE_DIR) - - print '@@@BUILD_STEP Sync CMake@@@' - CallSubProcess( - ['git', 'clone', - '--depth', '1', - '--single-branch', - '--branch', 'v2.8.8', - '--', - 'git://cmake.org/cmake.git', - CMAKE_DIR], - cwd=CMAKE_DIR) - - print '@@@BUILD_STEP Build CMake@@@' - CallSubProcess( - ['/bin/bash', 'bootstrap', '--prefix=%s' % CMAKE_DIR], - cwd=CMAKE_DIR) - - CallSubProcess( ['make', 'cmake'], cwd=CMAKE_DIR) - - -def GypTestFormat(title, format=None, msvs_version=None, tests=[]): - """Run the gyp tests for a given format, emitting annotator tags. - - See annotator docs at: - https://sites.google.com/a/chromium.org/dev/developers/testing/chromium-build-infrastructure/buildbot-annotations - Args: - format: gyp format to test. - Returns: - 0 for sucesss, 1 for failure. - """ - if not format: - format = title - - print '@@@BUILD_STEP ' + title + '@@@' - sys.stdout.flush() - env = os.environ.copy() - if msvs_version: - env['GYP_MSVS_VERSION'] = msvs_version - command = ' '.join( - [sys.executable, 'gyp/gyptest.py', - '--all', - '--passed', - '--format', format, - '--path', CMAKE_BIN_DIR, - '--chdir', 'gyp'] + tests) - retcode = subprocess.call(command, cwd=ROOT_DIR, env=env, shell=True) - if retcode: - # Emit failure tag, and keep going. - print '@@@STEP_FAILURE@@@' - return 1 - return 0 - - -def GypBuild(): - # Dump out/ directory. - print '@@@BUILD_STEP cleanup@@@' - print 'Removing %s...' % OUT_DIR - shutil.rmtree(OUT_DIR, ignore_errors=True) - print 'Done.' - - retcode = 0 - if sys.platform.startswith('linux'): - retcode += GypTestFormat('ninja') - retcode += GypTestFormat('make') - PrepareCmake() - retcode += GypTestFormat('cmake') - elif sys.platform == 'darwin': - retcode += GypTestFormat('ninja') - retcode += GypTestFormat('xcode') - retcode += GypTestFormat('make') - elif sys.platform == 'win32': - retcode += GypTestFormat('ninja') - if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-win64': - retcode += GypTestFormat('msvs-ninja-2013', format='msvs-ninja', - msvs_version='2013', - tests=[ - r'test\generator-output\gyptest-actions.py', - r'test\generator-output\gyptest-relocate.py', - r'test\generator-output\gyptest-rules.py']) - retcode += GypTestFormat('msvs-2013', format='msvs', msvs_version='2013') - else: - raise Exception('Unknown platform') - if retcode: - # TODO(bradnelson): once the annotator supports a postscript (section for - # after the build proper that could be used for cumulative failures), - # use that instead of this. This isolates the final return value so - # that it isn't misattributed to the last stage. - print '@@@BUILD_STEP failures@@@' - sys.exit(retcode) - - -if __name__ == '__main__': - GypBuild() diff --git a/gyp/buildbot/commit_queue/OWNERS b/gyp/buildbot/commit_queue/OWNERS deleted file mode 100644 index b269c198b4..0000000000 --- a/gyp/buildbot/commit_queue/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -set noparent -bradnelson@chromium.org -bradnelson@google.com -iannucci@chromium.org -scottmg@chromium.org -thakis@chromium.org diff --git a/gyp/buildbot/commit_queue/README b/gyp/buildbot/commit_queue/README deleted file mode 100644 index 9428497883..0000000000 --- a/gyp/buildbot/commit_queue/README +++ /dev/null @@ -1,3 +0,0 @@ -cq_config.json describes the trybots that must pass in order -to land a change through the commit queue. -Comments are here as the file is strictly JSON. diff --git a/gyp/buildbot/commit_queue/cq_config.json b/gyp/buildbot/commit_queue/cq_config.json deleted file mode 100644 index 656c21e54f..0000000000 --- a/gyp/buildbot/commit_queue/cq_config.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "trybots": { - "launched": { - "tryserver.nacl": { - "gyp-presubmit": ["defaulttests"], - "gyp-linux": ["defaulttests"], - "gyp-mac": ["defaulttests"], - "gyp-win32": ["defaulttests"], - "gyp-win64": ["defaulttests"] - } - }, - "triggered": { - } - } -} diff --git a/gyp/gyptest.py b/gyp/gyptest.py deleted file mode 100755 index 8e4fc47d5c..0000000000 --- a/gyp/gyptest.py +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -__doc__ = """ -gyptest.py -- test runner for GYP tests. -""" - -import os -import optparse -import subprocess -import sys - -class CommandRunner(object): - """ - Executor class for commands, including "commands" implemented by - Python functions. - """ - verbose = True - active = True - - def __init__(self, dictionary={}): - self.subst_dictionary(dictionary) - - def subst_dictionary(self, dictionary): - self._subst_dictionary = dictionary - - def subst(self, string, dictionary=None): - """ - Substitutes (via the format operator) the values in the specified - dictionary into the specified command. - - The command can be an (action, string) tuple. In all cases, we - perform substitution on strings and don't worry if something isn't - a string. (It's probably a Python function to be executed.) - """ - if dictionary is None: - dictionary = self._subst_dictionary - if dictionary: - try: - string = string % dictionary - except TypeError: - pass - return string - - def display(self, command, stdout=None, stderr=None): - if not self.verbose: - return - if type(command) == type(()): - func = command[0] - args = command[1:] - s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args))) - if type(command) == type([]): - # TODO: quote arguments containing spaces - # TODO: handle meta characters? - s = ' '.join(command) - else: - s = self.subst(command) - if not s.endswith('\n'): - s += '\n' - sys.stdout.write(s) - sys.stdout.flush() - - def execute(self, command, stdout=None, stderr=None): - """ - Executes a single command. - """ - if not self.active: - return 0 - if type(command) == type(''): - command = self.subst(command) - cmdargs = shlex.split(command) - if cmdargs[0] == 'cd': - command = (os.chdir,) + tuple(cmdargs[1:]) - if type(command) == type(()): - func = command[0] - args = command[1:] - return func(*args) - else: - if stdout is sys.stdout: - # Same as passing sys.stdout, except python2.4 doesn't fail on it. - subout = None - else: - # Open pipe for anything else so Popen works on python2.4. - subout = subprocess.PIPE - if stderr is sys.stderr: - # Same as passing sys.stderr, except python2.4 doesn't fail on it. - suberr = None - elif stderr is None: - # Merge with stdout if stderr isn't specified. - suberr = subprocess.STDOUT - else: - # Open pipe for anything else so Popen works on python2.4. - suberr = subprocess.PIPE - p = subprocess.Popen(command, - shell=(sys.platform == 'win32'), - stdout=subout, - stderr=suberr) - p.wait() - if stdout is None: - self.stdout = p.stdout.read() - elif stdout is not sys.stdout: - stdout.write(p.stdout.read()) - if stderr not in (None, sys.stderr): - stderr.write(p.stderr.read()) - return p.returncode - - def run(self, command, display=None, stdout=None, stderr=None): - """ - Runs a single command, displaying it first. - """ - if display is None: - display = command - self.display(display) - return self.execute(command, stdout, stderr) - - -class Unbuffered(object): - def __init__(self, fp): - self.fp = fp - def write(self, arg): - self.fp.write(arg) - self.fp.flush() - def __getattr__(self, attr): - return getattr(self.fp, attr) - -sys.stdout = Unbuffered(sys.stdout) -sys.stderr = Unbuffered(sys.stderr) - - -def is_test_name(f): - return f.startswith('gyptest') and f.endswith('.py') - - -def find_all_gyptest_files(directory): - result = [] - for root, dirs, files in os.walk(directory): - if '.svn' in dirs: - dirs.remove('.svn') - result.extend([ os.path.join(root, f) for f in files if is_test_name(f) ]) - result.sort() - return result - - -def main(argv=None): - if argv is None: - argv = sys.argv - - usage = "gyptest.py [-ahlnq] [-f formats] [test ...]" - parser = optparse.OptionParser(usage=usage) - parser.add_option("-a", "--all", action="store_true", - help="run all tests") - parser.add_option("-C", "--chdir", action="store", default=None, - help="chdir to the specified directory") - parser.add_option("-f", "--format", action="store", default='', - help="run tests with the specified formats") - parser.add_option("-G", '--gyp_option', action="append", default=[], - help="Add -G options to the gyp command line") - parser.add_option("-l", "--list", action="store_true", - help="list available tests and exit") - parser.add_option("-n", "--no-exec", action="store_true", - help="no execute, just print the command line") - parser.add_option("--passed", action="store_true", - help="report passed tests") - parser.add_option("--path", action="append", default=[], - help="additional $PATH directory") - parser.add_option("-q", "--quiet", action="store_true", - help="quiet, don't print test command lines") - opts, args = parser.parse_args(argv[1:]) - - if opts.chdir: - os.chdir(opts.chdir) - - if opts.path: - extra_path = [os.path.abspath(p) for p in opts.path] - extra_path = os.pathsep.join(extra_path) - os.environ['PATH'] = extra_path + os.pathsep + os.environ['PATH'] - - if not args: - if not opts.all: - sys.stderr.write('Specify -a to get all tests.\n') - return 1 - args = ['test'] - - tests = [] - for arg in args: - if os.path.isdir(arg): - tests.extend(find_all_gyptest_files(os.path.normpath(arg))) - else: - if not is_test_name(os.path.basename(arg)): - print >>sys.stderr, arg, 'is not a valid gyp test name.' - sys.exit(1) - tests.append(arg) - - if opts.list: - for test in tests: - print test - sys.exit(0) - - CommandRunner.verbose = not opts.quiet - CommandRunner.active = not opts.no_exec - cr = CommandRunner() - - os.environ['PYTHONPATH'] = os.path.abspath('test/lib') - if not opts.quiet: - sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH']) - - passed = [] - failed = [] - no_result = [] - - if opts.format: - format_list = opts.format.split(',') - else: - # TODO: not duplicate this mapping from pylib/gyp/__init__.py - format_list = { - 'aix5': ['make'], - 'freebsd7': ['make'], - 'freebsd8': ['make'], - 'openbsd5': ['make'], - 'cygwin': ['msvs'], - 'win32': ['msvs', 'ninja'], - 'linux2': ['make', 'ninja'], - 'linux3': ['make', 'ninja'], - 'darwin': ['make', 'ninja', 'xcode', 'xcode-ninja'], - }[sys.platform] - - for format in format_list: - os.environ['TESTGYP_FORMAT'] = format - if not opts.quiet: - sys.stdout.write('TESTGYP_FORMAT=%s\n' % format) - - gyp_options = [] - for option in opts.gyp_option: - gyp_options += ['-G', option] - if gyp_options and not opts.quiet: - sys.stdout.write('Extra Gyp options: %s\n' % gyp_options) - - for test in tests: - status = cr.run([sys.executable, test] + gyp_options, - stdout=sys.stdout, - stderr=sys.stderr) - if status == 2: - no_result.append(test) - elif status: - failed.append(test) - else: - passed.append(test) - - if not opts.quiet: - def report(description, tests): - if tests: - if len(tests) == 1: - sys.stdout.write("\n%s the following test:\n" % description) - else: - fmt = "\n%s the following %d tests:\n" - sys.stdout.write(fmt % (description, len(tests))) - sys.stdout.write("\t" + "\n\t".join(tests) + "\n") - - if opts.passed: - report("Passed", passed) - report("Failed", failed) - report("No result from", no_result) - - if failed: - return 1 - else: - return 0 - - -if __name__ == "__main__": - sys.exit(main()) From c5e980232e2cf9191f2853bccb341823da0a0c6c Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Thu, 19 Jul 2018 15:35:01 -0400 Subject: [PATCH 25/46] doc: lint README.md Fixes grammar, removes extra lines and spaces, etc. Also removes a few references to `node-waf`, which was removed ~6 years ago now. Happy to add back if people still need that information. PR-URL: https://github.com/nodejs/node-gyp/pull/1498 Reviewed-By: Vse Mozhet Byt Reviewed-By: Richard Lau --- README.md | 168 +++++++++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index bfb687d635..11a9033af5 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,21 @@ -node-gyp -========= -## Node.js native addon build tool +# `node-gyp` - Node.js native addon build tool `node-gyp` is a cross-platform command-line tool written in Node.js for compiling -native addon modules for Node.js. It bundles the [gyp](https://gyp.gsrc.io) +native addon modules for Node.js. It bundles the [gyp](https://gyp.gsrc.io) project used by the Chromium team and takes away the pain of dealing with the -various differences in build platforms. It is the replacement to the `node-waf` -program which is removed for node `v0.8`. If you have a native addon for node that -still has a `wscript` file, then you should definitely add a `binding.gyp` file -to support the latest versions of node. +various differences in build platforms. -Multiple target versions of node are supported (i.e. `0.8`, ..., `4`, `5`, `6`, -etc.), regardless of what version of node is actually installed on your system +Multiple target versions of Node.js are supported (i.e. `0.8`, ..., `4`, `5`, `6`, +etc.), regardless of what version of Node.js is actually installed on your system (`node-gyp` downloads the necessary development files or headers for the target version). ## Features * Easy to use, consistent interface * Same commands to build your module on every platform - * Supports multiple target versions of Node + * Supports multiple target versions of Node.js - -Installation ------------- +## Installation You can install with `npm`: @@ -80,7 +73,7 @@ version `node-gyp` uses by setting the '--python' variable: $ node-gyp --python /path/to/python2.7 ``` -If `node-gyp` is called by way of `npm` *and* you have multiple versions of +If `node-gyp` is called by way of `npm`, *and* you have multiple versions of Python installed, then you can set `npm`'s 'python' config key to the appropriate value: @@ -88,8 +81,7 @@ value: $ npm config set python /path/to/executable/python2.7 ``` -How to Use ----------- +## How to Use To compile your native addon, first go to its root directory: @@ -110,33 +102,30 @@ needs to be added (not needed when run by npm as configured above): $ node-gyp configure --msvs_version=2015 ``` -__Note__: The `configure` step looks for the `binding.gyp` file in the current -directory to process. See below for instructions on creating the `binding.gyp` file. +__Note__: The `configure` step looks for a `binding.gyp` file in the current +directory to process. See below for instructions on creating a `binding.gyp` file. Now you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file -(on Windows) in the `build/` directory. Next invoke the `build` command: +(on Windows) in the `build/` directory. Next, invoke the `build` command: ``` bash $ node-gyp build ``` Now you have your compiled `.node` bindings file! The compiled bindings end up -in `build/Debug/` or `build/Release/`, depending on the build mode. At this point -you can require the `.node` file with Node and run your tests! +in `build/Debug/` or `build/Release/`, depending on the build mode. At this point, +you can require the `.node` file with Node.js and run your tests! __Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or -`-d`) switch when running either the `configure`, `build` or `rebuild` command. - +`-d`) switch when running either the `configure`, `build` or `rebuild` commands. -The "binding.gyp" file ----------------------- +## The `binding.gyp` file -Previously when node had `node-waf` you had to write a `wscript` file. The -replacement for that is the `binding.gyp` file, which describes the configuration -to build your module in a JSON-like format. This file gets placed in the root of -your package, alongside the `package.json` file. +A `binding.gyp` file describes the configuration to build your module, in a +JSON-like format. This file gets placed in the root of your package, alongside +`package.json`. -A barebones `gyp` file appropriate for building a node addon looks like: +A barebones `gyp` file appropriate for building a Node.js addon could look like: ``` python { @@ -158,8 +147,7 @@ Some additional resources for addons and writing `gyp` files: * [*"binding.gyp" files out in the wild* wiki page](https://github.com/nodejs/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild) -Commands --------- +## Commands `node-gyp` responds to the following commands: @@ -170,86 +158,74 @@ Commands | `clean` | Removes the `build` directory if it exists | `configure` | Generates project build files for the current platform | `rebuild` | Runs `clean`, `configure` and `build` all in a row -| `install` | Installs node header files for the given version -| `list` | Lists the currently installed node header versions -| `remove` | Removes the node header files for the given version +| `install` | Installs Node.js header files for the given version +| `list` | Lists the currently installed Node.js header versions +| `remove` | Removes the Node.js header files for the given version -Command Options --------- +## Command Options `node-gyp` accepts the following command options: | **Command** | **Description** |:----------------------------------|:------------------------------------------ -| `-j n`, `--jobs n` | Run make in parallel -| `--target=v6.2.1` | Node version to build for (default=process.version) +| `-j n`, `--jobs n` | Run `make` in parallel +| `--target=v6.2.1` | Node.js version to build for (default is `process.version`) | `--silly`, `--loglevel=silly` | Log all progress to console | `--verbose`, `--loglevel=verbose` | Log most progress to console | `--silent`, `--loglevel=silent` | Don't log anything to console -| `debug`, `--debug` | Make Debug build (default=Release) +| `debug`, `--debug` | Make Debug build (default is `Release`) | `--release`, `--no-debug` | Make Release build | `-C $dir`, `--directory=$dir` | Run command in different directory -| `--make=$make` | Override make command (e.g. gmake) +| `--make=$make` | Override `make` command (e.g. `gmake`) | `--thin=yes` | Enable thin static libraries | `--arch=$arch` | Set target architecture (e.g. ia32) | `--tarball=$path` | Get headers from a local tarball -| `--devdir=$path` | SDK download directory (default=~/.node-gyp) +| `--devdir=$path` | SDK download directory (default is `~/.node-gyp`) | `--ensure` | Don't reinstall headers if already present | `--dist-url=$url` | Download header tarball from custom URL | `--proxy=$url` | Set HTTP proxy for downloading header tarball | `--cafile=$cafile` | Override default CA chain (to download tarball) | `--nodedir=$path` | Set the path to the node source code -| `--python=$path` | Set path to the python (2) binary -| `--msvs_version=$version` | Set Visual Studio version (win) -| `--solution=$solution` | Set Visual Studio Solution version (win) - - -Configuration --------- - -__`node-gyp` responds to environment variables or `npm` configuration__ -1. Environment variables take the form `npm_config_OPTION_NAME` for any of the - options listed above (dashes in option names should be replaced by underscores). - These work also when `node-gyp` is invoked directly: - `$ export npm_config_devdir=/tmp/.gyp` - or on Windows - `> set npm_config_devdir=c:\temp\.gyp` -2. As `npm` configuration, variables take the form `OPTION_NAME`. - This way only works when `node-gyp` is executed by `npm`: - `$ npm config set [--global] devdir /tmp/.gyp` - `$ npm i buffertools` - - - -License -------- - -(The MIT License) - -Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -[python-v2.7.10]: https://www.python.org/downloads/release/python-2710/ -[msvc2013]: https://www.microsoft.com/en-gb/download/details.aspx?id=44914 -[win7sdk]: https://www.microsoft.com/en-us/download/details.aspx?id=8279 -[compiler update for the Windows SDK 7.1]: https://www.microsoft.com/en-us/download/details.aspx?id=4422 +| `--python=$path` | Set path to the Python 2 binary +| `--msvs_version=$version` | Set Visual Studio version (Windows only) +| `--solution=$solution` | Set Visual Studio Solution version (Windows only) + +## Configuration + +### Environment variables + +Use the form `npm_config_OPTION_NAME` for any of the command options listed +above (dashes in option names should be replaced by underscores). + +For example, to set `devdir` equal to `/tmp/.gyp`, you would: + +Run this on Unix: + +```bash +$ export npm_config_devdir=/tmp/.gyp +``` + +Or this on Windows: + +```console +> set npm_config_devdir=c:\temp\.gyp +``` + +### `npm` configuration + +Use the form `OPTION_NAME` for any of the command options listed above. + +For example, to set `devdir` equal to `/tmp/.gyp`, you would run: + +```bash +$ npm config set [--global] devdir /tmp/.gyp +``` + +**Note:** Configuration set via `npm` will only be used when `node-gyp` +is run via `npm`, not when `node-gyp` is run directly. + +## License + +`node-gyp` is available under the MIT license. See the [LICENSE +file](LICENSE) for details. From 6b0f4aeaf36d9668a68d5ebd48deeba329dc2010 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Fri, 27 Jul 2018 23:36:02 -0400 Subject: [PATCH 26/46] bin,lib: remove extra comments/lines/spaces - Removes "module dependencies" comments and things that, IMHO, don't add too much value. Happy to add back if helps some people when reading through `node-gyp`. - DRY up `lib/process-release.js`. - Removes a bunch of extra blank lines, as well as random spaces. PR-URL: https://github.com/nodejs/node-gyp/pull/1508 Reviewed-By: Richard Lau --- bin/node-gyp.js | 10 +-------- lib/build.js | 14 +------------ lib/clean.js | 7 ------- lib/configure.js | 15 ++----------- lib/find-node-directory.js | 4 +--- lib/find-vs2017.js | 4 +--- lib/install.js | 7 ------- lib/list.js | 6 ------ lib/node-gyp.js | 13 ------------ lib/process-release.js | 43 +++++++++++++------------------------- lib/rebuild.js | 1 - lib/remove.js | 6 ------ 12 files changed, 21 insertions(+), 109 deletions(-) diff --git a/bin/node-gyp.js b/bin/node-gyp.js index 70d7d50262..0cc3517748 100755 --- a/bin/node-gyp.js +++ b/bin/node-gyp.js @@ -1,15 +1,7 @@ #!/usr/bin/env node -/** - * Set the title. - */ - process.title = 'node-gyp' -/** - * Module dependencies. - */ - var gyp = require('../') var log = require('npmlog') var osenv = require('osenv') @@ -126,7 +118,7 @@ process.on('uncaughtException', function (err) { }) function errorMessage () { - // copied from npm's lib/util/error-handler.js + // copied from npm's lib/utils/error-handler.js var os = require('os') log.error('System', os.type() + ' ' + os.release()) log.error('command', process.argv diff --git a/lib/build.js b/lib/build.js index 2f8e14c374..81494d65aa 100644 --- a/lib/build.js +++ b/lib/build.js @@ -1,10 +1,6 @@ module.exports = exports = build -/** - * Module dependencies. - */ - var fs = require('graceful-fs') , rm = require('rimraf') , path = require('path') @@ -32,8 +28,6 @@ function build (gyp, argv, callback) { var release = processRelease(argv, gyp, process.version, process.release) , makeCommand = gyp.opts.make || process.env.MAKE || platformMake , command = win ? 'msbuild' : makeCommand - , buildDir = path.resolve('build') - , configPath = path.resolve(buildDir, 'config.gypi') , jobs = gyp.opts.jobs || process.env.JOBS , buildType , config @@ -47,6 +41,7 @@ function build (gyp, argv, callback) { */ function loadConfigGypi () { + var configPath = path.resolve('build', 'config.gypi') fs.readFile(configPath, 'utf8', function (err, data) { if (err) { if (err.code == 'ENOENT') { @@ -187,13 +182,11 @@ function build (gyp, argv, callback) { }) } - /** * Actually spawn the process and compile the module. */ function doBuild () { - // Enable Verbose build var verbose = log.levels[log.level] <= log.levels.verbose if (!win && verbose) { @@ -253,10 +246,6 @@ function build (gyp, argv, callback) { proc.on('exit', onExit) } - /** - * Invoked after the make/msbuild command exits. - */ - function onExit (code, signal) { if (code !== 0) { return callback(new Error('`' + command + '` failed with exit code: ' + code)) @@ -266,5 +255,4 @@ function build (gyp, argv, callback) { } callback() } - } diff --git a/lib/clean.js b/lib/clean.js index e69164d45a..8172e1c3d3 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -3,20 +3,13 @@ module.exports = exports = clean exports.usage = 'Removes any generated build files and the "out" dir' -/** - * Module dependencies. - */ - var rm = require('rimraf') var log = require('npmlog') - function clean (gyp, argv, callback) { - // Remove the 'build' dir var buildDir = 'build' log.verbose('clean', 'removing "%s" directory', buildDir) rm(buildDir, callback) - } diff --git a/lib/configure.js b/lib/configure.js index f4820b514b..2cf4c443ce 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -5,10 +5,6 @@ module.exports.test = { findPython: findPython, } -/** - * Module dependencies. - */ - var fs = require('graceful-fs') , path = require('path') , log = require('npmlog') @@ -28,7 +24,6 @@ if (win) exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module' function configure (gyp, argv, callback) { - var python = gyp.opts.python || process.env.PYTHON || 'python2' , buildDir = path.resolve('build') , configNames = [ 'config.gypi', 'common.gypi' ] @@ -46,7 +41,6 @@ function configure (gyp, argv, callback) { }) function getNodeDir () { - // 'python' should be set by now process.env.PYTHON = python @@ -56,7 +50,6 @@ function configure (gyp, argv, callback) { log.verbose('get node dir', 'compiling against specified --nodedir dev files: %s', nodeDir) createBuildDir() - } else { // if no --nodedir specified, ensure node dependencies are installed if ('v' + release.version !== process.version) { @@ -245,12 +238,12 @@ function configure (gyp, argv, callback) { }) // For AIX and z/OS we need to set up the path to the exports file - // which contains the symbols needed for linking. + // which contains the symbols needed for linking. var node_exp_file = undefined if (process.platform === 'aix' || process.platform === 'os390') { var ext = process.platform === 'aix' ? 'exp' : 'x' var node_root_dir = findNodeDirectory() - var candidates = undefined + var candidates = undefined if (process.platform === 'aix') { candidates = ['include/node/node', 'out/Release/node', @@ -336,10 +329,6 @@ function configure (gyp, argv, callback) { }) } - /** - * Called when the `gyp` child process exits. - */ - function onCpExit (code, signal) { if (code !== 0) { callback(new Error('`gyp` failed with exit code: ' + code)) diff --git a/lib/find-node-directory.js b/lib/find-node-directory.js index 3aee8a109a..524909581f 100644 --- a/lib/find-node-directory.js +++ b/lib/find-node-directory.js @@ -1,7 +1,7 @@ var path = require('path') , log = require('npmlog') -function findNodeDirectory(scriptLocation, processObj) { +module.exports = function findNodeDirectory(scriptLocation, processObj) { // set dirname and process if not passed in // this facilitates regression tests if (scriptLocation === undefined) { @@ -57,5 +57,3 @@ function findNodeDirectory(scriptLocation, processObj) { } return node_root_dir } - -module.exports = findNodeDirectory diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js index ad46ceaf88..8655d7c931 100644 --- a/lib/find-vs2017.js +++ b/lib/find-vs2017.js @@ -2,7 +2,7 @@ var log = require('npmlog') , execFile = require('child_process').execFile , path = require('path') -function findVS2017(callback) { +module.exports = function findVS2017(callback) { var ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') var csFile = path.join(__dirname, 'Find-VS2017.cs') @@ -42,5 +42,3 @@ function findVS2017(callback) { child.stdin.end() } - -module.exports = findVS2017 diff --git a/lib/install.js b/lib/install.js index 8a615dfb38..fa0fef6fe0 100644 --- a/lib/install.js +++ b/lib/install.js @@ -10,10 +10,6 @@ module.exports.test = { exports.usage = 'Install node development files for the specified node version.' -/** - * Module dependencies. - */ - var fs = require('graceful-fs') , osenv = require('osenv') , tar = require('tar') @@ -28,7 +24,6 @@ var fs = require('graceful-fs') , win = process.platform == 'win32' function install (fs, gyp, argv, callback) { - var release = processRelease(argv, gyp, process.version, process.release) // ensure no double-callbacks happen @@ -124,7 +119,6 @@ function install (fs, gyp, argv, callback) { } function go () { - log.verbose('ensuring nodedir is created', devDir) // first create the dir for the node dev files @@ -165,7 +159,6 @@ function install (fs, gyp, argv, callback) { } // download the tarball and extract! - if (tarPath) { return tar.extract({ file: tarPath, diff --git a/lib/list.js b/lib/list.js index 9d680a56a4..cda4fd2f2f 100644 --- a/lib/list.js +++ b/lib/list.js @@ -3,20 +3,14 @@ module.exports = exports = list exports.usage = 'Prints a listing of the currently installed node development files' -/** - * Module dependencies. - */ - var fs = require('graceful-fs') , path = require('path') , log = require('npmlog') function list (gyp, args, callback) { - var devDir = gyp.devDir log.verbose('list', 'using node-gyp dir:', devDir) - // readdir() the node-gyp dir fs.readdir(devDir, onreaddir) function onreaddir (err, versions) { diff --git a/lib/node-gyp.js b/lib/node-gyp.js index a841161e32..b35a5ebe44 100644 --- a/lib/node-gyp.js +++ b/lib/node-gyp.js @@ -1,14 +1,6 @@ -/** - * Module exports. - */ - module.exports = exports = gyp -/** - * Module dependencies. - */ - var fs = require('graceful-fs') , path = require('path') , nopt = require('nopt') @@ -35,10 +27,6 @@ var fs = require('graceful-fs') // differentiate node-gyp's logs from npm's log.heading = 'gyp' -/** - * The `gyp` function. - */ - function gyp () { return new Gyp() } @@ -213,4 +201,3 @@ Object.defineProperty(proto, 'version', { } , enumerable: true }) - diff --git a/lib/process-release.js b/lib/process-release.js index 0d177f1c93..4805fcc7d1 100644 --- a/lib/process-release.js +++ b/lib/process-release.js @@ -9,7 +9,7 @@ var semver = require('semver') , bitsreV3 = /\/win-(x86|ia32|x64)\// // io.js v3.x.x shipped with "ia32" but should // have been "x86" -// Captures all the logic required to determine download URLs, local directory and +// Captures all the logic required to determine download URLs, local directory and // file names. Inputs come from command-line switches (--target, --dist-url), // `process.version` and `process.release` where it exists. function processRelease (argv, gyp, defaultVersion, defaultRelease) { @@ -88,35 +88,22 @@ function processRelease (argv, gyp, defaultVersion, defaultRelease) { baseUrl = url.resolve(defaultRelease.headersUrl, './') libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major) libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major) - - return { - version: version, - semver: versionSemver, - name: name, - baseUrl: baseUrl, - tarballUrl: defaultRelease.headersUrl, - shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'), - versionDir: (name !== 'node' ? name + '-' : '') + version, - libUrl32: libUrl32, - libUrl64: libUrl64, - libPath32: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl32).path)), - libPath64: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl64).path)) - } + tarballUrl = defaultRelease.headersUrl + } else { + // older versions without process.release are captured here and we have to make + // a lot of assumptions, additionally if you --target=x.y.z then we can't use the + // current process.release + baseUrl = distBaseUrl + libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major) + libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major) + + // making the bold assumption that anything with a version number >3.0.0 will + // have a *-headers.tar.gz file in its dist location, even some frankenstein + // custom version + canGetHeaders = semver.satisfies(versionSemver, headersTarballRange) + tarballUrl = url.resolve(baseUrl, name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz') } - // older versions without process.release are captured here and we have to make - // a lot of assumptions, additionally if you --target=x.y.z then we can't use the - // current process.release - - baseUrl = distBaseUrl - libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major) - libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major) - // making the bold assumption that anything with a version number >3.0.0 will - // have a *-headers.tar.gz file in its dist location, even some frankenstein - // custom version - canGetHeaders = semver.satisfies(versionSemver, headersTarballRange) - tarballUrl = url.resolve(baseUrl, name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz') - return { version: version, semver: versionSemver, diff --git a/lib/rebuild.js b/lib/rebuild.js index 4c6f472aa7..dc8025a7b0 100644 --- a/lib/rebuild.js +++ b/lib/rebuild.js @@ -4,7 +4,6 @@ module.exports = exports = rebuild exports.usage = 'Runs "clean", "configure" and "build" all at once' function rebuild (gyp, argv, callback) { - gyp.todo.push( { name: 'clean', args: [] } , { name: 'configure', args: argv } diff --git a/lib/remove.js b/lib/remove.js index eb80981b88..213af2b9d3 100644 --- a/lib/remove.js +++ b/lib/remove.js @@ -3,10 +3,6 @@ module.exports = exports = remove exports.usage = 'Removes the node development files for the specified version' -/** - * Module dependencies. - */ - var fs = require('fs') , rm = require('rimraf') , path = require('path') @@ -14,7 +10,6 @@ var fs = require('fs') , semver = require('semver') function remove (gyp, argv, callback) { - var devDir = gyp.devDir log.verbose('remove', 'using node-gyp dir:', devDir) @@ -48,5 +43,4 @@ function remove (gyp, argv, callback) { // Go ahead and delete the dir rm(versionPath, callback) }) - } From b2e5cf077238076f904696e8090e24ebe22b84c4 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Thu, 2 Aug 2018 18:12:08 -0400 Subject: [PATCH 27/46] Add ESLint no-unused-vars rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Uses `.eslintrc.yaml` for configuration - `npm run lint` is part of `npm test` PR-URL: https://github.com/nodejs/node-gyp/pull/1497 Reviewed-By: Gibson Fahnestock Reviewed-By: João Reis --- .eslintrc.yaml | 5 +++++ bin/node-gyp.js | 2 +- lib/build.js | 9 +++------ lib/configure.js | 10 +++++----- lib/install.js | 9 +++------ lib/list.js | 1 - lib/node-gyp.js | 3 +-- lib/remove.js | 2 +- package.json | 9 ++++++--- test/test-configure-python.js | 4 ++-- test/test-find-accessible-sync.js | 2 +- test/test-find-python.js | 12 ++++++------ 12 files changed, 34 insertions(+), 34 deletions(-) create mode 100644 .eslintrc.yaml diff --git a/.eslintrc.yaml b/.eslintrc.yaml new file mode 100644 index 0000000000..659dce8810 --- /dev/null +++ b/.eslintrc.yaml @@ -0,0 +1,5 @@ +--- + env: + node: true + rules: + no-unused-vars: error diff --git a/bin/node-gyp.js b/bin/node-gyp.js index 0cc3517748..a8fd9bc529 100755 --- a/bin/node-gyp.js +++ b/bin/node-gyp.js @@ -34,7 +34,7 @@ if (prog.todo.length === 0) { } else { console.log('%s', prog.usage()) } - return process.exit(0) + process.exit(0) } log.info('it worked if it ends with', 'ok') diff --git a/lib/build.js b/lib/build.js index 81494d65aa..b8389bcd7b 100644 --- a/lib/build.js +++ b/lib/build.js @@ -2,13 +2,11 @@ module.exports = exports = build var fs = require('graceful-fs') - , rm = require('rimraf') , path = require('path') , glob = require('glob') , log = require('npmlog') , which = require('which') , exec = require('child_process').exec - , processRelease = require('./process-release') , win = process.platform === 'win32' exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module' @@ -25,8 +23,7 @@ function build (gyp, argv, callback) { }) } - var release = processRelease(argv, gyp, process.version, process.release) - , makeCommand = gyp.opts.make || process.env.MAKE || platformMake + var makeCommand = gyp.opts.make || process.env.MAKE || platformMake , command = win ? 'msbuild' : makeCommand , jobs = gyp.opts.jobs || process.env.JOBS , buildType @@ -132,7 +129,7 @@ function build (gyp, argv, callback) { var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s' if (process.arch !== 'ia32') cmd += ' /reg:32' - exec(cmd, function (err, stdout, stderr) { + exec(cmd, function (err, stdout) { if (err) { return callback(new Error(err.message + '\n' + notfoundErr)) } @@ -162,7 +159,7 @@ function build (gyp, argv, callback) { ;(function verifyMsbuild () { if (!msbuilds.length) return callback(new Error(notfoundErr)) msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe') - fs.stat(msbuildPath, function (err, stat) { + fs.stat(msbuildPath, function (err) { if (err) { if (err.code == 'ENOENT') { if (msbuilds.length) { diff --git a/lib/configure.js b/lib/configure.js index 2cf4c443ce..47a77e637c 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -69,7 +69,7 @@ function configure (gyp, argv, callback) { // into devdir. Otherwise only install if they're not already there. gyp.opts.ensure = gyp.opts.tarball ? false : true - gyp.commands.install([ release.version ], function (err, version) { + gyp.commands.install([ release.version ], function (err) { if (err) return callback(err) log.verbose('get node dir', 'target node version installed:', release.versionDir) nodeDir = path.resolve(gyp.devDir, release.versionDir) @@ -188,7 +188,7 @@ function configure (gyp, argv, callback) { if (!name) return runGyp() var fullPath = path.resolve(name) log.verbose(name, 'checking for gypi file: %s', fullPath) - fs.stat(fullPath, function (err, stat) { + fs.stat(fullPath, function (err) { if (err) { if (err.code == 'ENOENT') { findConfigs() // check next gypi filename @@ -275,7 +275,7 @@ function configure (gyp, argv, callback) { var gyp_script = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py') var addon_gypi = path.resolve(__dirname, '..', 'addon.gypi') var common_gypi = path.resolve(nodeDir, 'include/node/common.gypi') - fs.stat(common_gypi, function (err, stat) { + fs.stat(common_gypi, function (err) { if (err) common_gypi = path.resolve(nodeDir, 'common.gypi') @@ -329,7 +329,7 @@ function configure (gyp, argv, callback) { }) } - function onCpExit (code, signal) { + function onCpExit (code) { if (code !== 0) { callback(new Error('`gyp` failed with exit code: ' + code)) } else { @@ -500,7 +500,7 @@ PythonFinder.prototype = { } var pythonPath = this.resolve(rootDir, 'Python27', 'python.exe') this.log.verbose('ensuring that file exists:', pythonPath) - this.stat(pythonPath, function (err, stat) { + this.stat(pythonPath, function (err) { if (err) { if (err.code == 'ENOENT') { this.failNoPython() diff --git a/lib/install.js b/lib/install.js index fa0fef6fe0..eea7618a01 100644 --- a/lib/install.js +++ b/lib/install.js @@ -13,7 +13,6 @@ exports.usage = 'Install node development files for the specified node version.' var fs = require('graceful-fs') , osenv = require('osenv') , tar = require('tar') - , rm = require('rimraf') , path = require('path') , crypto = require('crypto') , log = require('npmlog') @@ -33,7 +32,7 @@ function install (fs, gyp, argv, callback) { if (err) { log.warn('install', 'got an error, rolling back install') // roll-back the install if anything went wrong - gyp.commands.remove([ release.versionDir ], function (err2) { + gyp.commands.remove([ release.versionDir ], function () { callback(err) }) } else { @@ -75,7 +74,7 @@ function install (fs, gyp, argv, callback) { // check if it is already installed, and only install when needed if (gyp.opts.ensure) { log.verbose('install', '--ensure was passed, so won\'t reinstall if already installed') - fs.stat(devDir, function (err, stat) { + fs.stat(devDir, function (err) { if (err) { if (err.code == 'ENOENT') { log.verbose('install', 'version not already installed, continuing with install', release.version) @@ -146,7 +145,7 @@ function install (fs, gyp, argv, callback) { // checks if a file to be extracted from the tarball is valid. // only .h header files and the gyp files get extracted - function isValid (path, entry) { + function isValid (path) { var isValid = valid(path) if (isValid) { log.verbose('extracted file from tarball', path) @@ -265,8 +264,6 @@ function install (fs, gyp, argv, callback) { function downloadShasums(done) { log.verbose('check download content checksum, need to download `SHASUMS256.txt`...') - var shasumsPath = path.resolve(devDir, 'SHASUMS256.txt') - log.verbose('checksum url', release.shasumsUrl) try { var req = download(gyp, process.env, release.shasumsUrl) diff --git a/lib/list.js b/lib/list.js index cda4fd2f2f..90f6447180 100644 --- a/lib/list.js +++ b/lib/list.js @@ -4,7 +4,6 @@ module.exports = exports = list exports.usage = 'Prints a listing of the currently installed node development files' var fs = require('graceful-fs') - , path = require('path') , log = require('npmlog') function list (gyp, args, callback) { diff --git a/lib/node-gyp.js b/lib/node-gyp.js index b35a5ebe44..8dd551bf3d 100644 --- a/lib/node-gyp.js +++ b/lib/node-gyp.js @@ -1,8 +1,7 @@ module.exports = exports = gyp -var fs = require('graceful-fs') - , path = require('path') +var path = require('path') , nopt = require('nopt') , log = require('npmlog') , child_process = require('child_process') diff --git a/lib/remove.js b/lib/remove.js index 213af2b9d3..46a1a3d4c2 100644 --- a/lib/remove.js +++ b/lib/remove.js @@ -31,7 +31,7 @@ function remove (gyp, argv, callback) { log.verbose('remove', 'removing development files for version:', version) // first check if its even installed - fs.stat(versionPath, function (err, stat) { + fs.stat(versionPath, function (err) { if (err) { if (err.code == 'ENOENT') { callback(null, 'version was already uninstalled: ' + version) diff --git a/package.json b/package.json index a8e5fe9f27..69b450fbaf 100644 --- a/package.json +++ b/package.json @@ -38,12 +38,15 @@ "node": ">= 4.0.0" }, "devDependencies": { - "tape": "~4.2.0", + "babel-eslint": "^8.2.5", "bindings": "~1.2.1", + "eslint": "^5.0.1", "nan": "^2.0.0", - "require-inject": "~1.3.0" + "require-inject": "~1.3.0", + "tape": "~4.2.0" }, "scripts": { - "test": "tape test/test-*" + "lint": "eslint bin lib test", + "test": "npm run lint && tape test/test-*" } } diff --git a/test/test-configure-python.js b/test/test-configure-python.js index f235bdbba1..07cdce2b17 100644 --- a/test/test-configure-python.js +++ b/test/test-configure-python.js @@ -6,8 +6,8 @@ var gyp = require('../lib/node-gyp') var requireInject = require('require-inject') var configure = requireInject('../lib/configure', { 'graceful-fs': { - 'openSync': function (file, mode) { return 0; }, - 'closeSync': function (fd) { }, + 'openSync': function () { return 0; }, + 'closeSync': function () { }, 'writeFile': function (file, data, cb) { cb() }, 'stat': function (file, cb) { cb(null, {}) } } diff --git a/test/test-find-accessible-sync.js b/test/test-find-accessible-sync.js index d336243dd0..114403e278 100644 --- a/test/test-find-accessible-sync.js +++ b/test/test-find-accessible-sync.js @@ -5,7 +5,7 @@ var path = require('path') var requireInject = require('require-inject') var configure = requireInject('../lib/configure', { 'graceful-fs': { - 'closeSync': function (fd) { return undefined }, + 'closeSync': function () { return undefined }, 'openSync': function (path) { if (readableFiles.some(function (f) { return f === path} )) { return 0 diff --git a/test/test-find-python.js b/test/test-find-python.js index 2d9f171c57..2db9ee4b97 100644 --- a/test/test-find-python.js +++ b/test/test-find-python.js @@ -88,7 +88,7 @@ test('find python - python too old', function (t) { } f.checkPython() - function done(err, python) { + function done(err) { t.ok(/is not supported by gyp/.test(err)) } }) @@ -108,7 +108,7 @@ test('find python - python too new', function (t) { } f.checkPython() - function done(err, python) { + function done(err) { t.ok(/is not supported by gyp/.test(err)) } }) @@ -123,7 +123,7 @@ test('find python - no python', function (t) { } f.checkPython() - function done(err, python) { + function done(err) { t.ok(/Can't find Python executable/.test(err)) } }) @@ -170,7 +170,7 @@ test('find python - no python2, no python, unix', function (t) { } f.checkPython() - function done(err, python) { + function done(err) { t.ok(/Can't find Python executable/.test(err)) } }) @@ -271,7 +271,7 @@ test('find python - python 3, use python launcher, python 2 too old', } f.checkPython() - function done(err, python) { + function done(err) { t.ok(/is not supported by gyp/.test(err)) } }) @@ -333,7 +333,7 @@ test('find python - no python, no python launcher, bad guess', function (t) { } f.checkPython() - function done(err, python) { + function done(err) { t.ok(/Can't find Python executable/.test(err)) } }) From 25208f12c589c1e5c6b74396b63117685cd55ec6 Mon Sep 17 00:00:00 2001 From: Alessandro Vergani Date: Mon, 30 Jul 2018 14:29:12 +0200 Subject: [PATCH 28/46] win: improve parsing of SDK version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the parsing more robust and fixes the additional issue related to USB Device Connectivity component. Fixes: https://github.com/nodejs/node-gyp/issues/1466 PR-URL: https://github.com/nodejs/node-gyp/pull/1516 Reviewed-By: João Reis Reviewed-By: Refael Ackermann Reviewed-By: Richard Lau --- lib/Find-VS2017.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Find-VS2017.cs b/lib/Find-VS2017.cs index 87e0a9c9bb..6e7429b771 100644 --- a/lib/Find-VS2017.cs +++ b/lib/Find-VS2017.cs @@ -232,7 +232,9 @@ private static bool CheckInstance(ISetupInstance2 setupInstance2, ref StringBuil string[] parts = id.Substring(Win10SDKPrefix.Length).Split('.'); if (parts.Length > 1 && parts[1] != "Desktop") continue; - Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(parts[0])); + uint foundSdkVer; + if (UInt32.TryParse(parts[0], out foundSdkVer)) + Win10SDKVer = Math.Max(Win10SDKVer, foundSdkVer); } else if (id == "Microsoft.VisualStudio.Component.Windows81SDK") hasWin8SDK = true; else From da5db4059f9d3628a9fcace262c482d585460002 Mon Sep 17 00:00:00 2001 From: Yang Guo Date: Tue, 17 Jul 2018 08:27:52 +0200 Subject: [PATCH 29/46] configure: use sys.version_info to get python version This is cleaner than filtering additional strings from platform.python_version(). PR-URL: https://github.com/nodejs/node-gyp/pull/1504 Reviewed-By: Anna Henningsen Reviewed-By: Richard Lau Reviewed-By: Jon Moss Reviewed-By: Rod Vagg --- lib/configure.js | 10 +--------- test/test-find-python.js | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/lib/configure.js b/lib/configure.js index 47a77e637c..756107f3fc 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -437,7 +437,7 @@ PythonFinder.prototype = { }, checkPythonVersion: function checkPythonVersion () { - var args = ['-c', 'import platform; print(platform.python_version());'] + var args = ['-c', 'import sys; print "%s.%s.%s" % sys.version_info[:3];'] var env = extend({}, this.env) env.TERM = 'dumb' @@ -449,14 +449,6 @@ PythonFinder.prototype = { '`%s -c "' + args[1] + '"` returned: %j', this.python, stdout) var version = stdout.trim() - if (~version.indexOf('+')) { - this.log.silly('stripping "+" sign(s) from version') - version = version.replace(/\+/g, '') - } - if (~version.indexOf('rc')) { - this.log.silly('stripping "rc" identifier from version') - version = version.replace(/rc(.*)$/ig, '') - } var range = semver.Range('>=2.5.0 <3.0.0') var valid = false try { diff --git a/test/test-find-python.js b/test/test-find-python.js index 2db9ee4b97..250e37f4fe 100644 --- a/test/test-find-python.js +++ b/test/test-find-python.js @@ -62,7 +62,7 @@ test('find python - python', function (t) { } f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'python') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.7.0') } f.checkPython() @@ -83,7 +83,7 @@ test('find python - python too old', function (t) { } f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'python') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.3.4') } f.checkPython() @@ -103,7 +103,7 @@ test('find python - python too new', function (t) { } f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'python') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '3.0.0') } f.checkPython() @@ -142,7 +142,7 @@ test('find python - no python2', function (t) { } f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'python') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.7.0') } f.checkPython() @@ -189,7 +189,7 @@ test('find python - no python, use python launcher', function (t) { f.execFile = function(program, args, opts, cb) { f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'Z:\\snake.exe') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.7.0') } t.strictEqual(program, 'py.exe') @@ -220,7 +220,7 @@ test('find python - python 3, use python launcher', function (t) { f.execFile = function(program, args, opts, cb) { f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'Z:\\snake.exe') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.7.0') } t.strictEqual(program, 'py.exe') @@ -229,7 +229,7 @@ test('find python - python 3, use python launcher', function (t) { cb(null, 'Z:\\snake.exe') } t.strictEqual(program, 'python') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '3.0.0') } f.checkPython() @@ -257,7 +257,7 @@ test('find python - python 3, use python launcher, python 2 too old', f.execFile = function(program, args, opts, cb) { f.execFile = function(program, args, opts, cb) { t.strictEqual(program, 'Z:\\snake.exe') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.3.4') } t.strictEqual(program, 'py.exe') @@ -266,7 +266,7 @@ test('find python - python 3, use python launcher, python 2 too old', cb(null, 'Z:\\snake.exe') } t.strictEqual(program, 'python') - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '3.0.0') } f.checkPython() @@ -291,7 +291,7 @@ test('find python - no python, no python launcher, good guess', function (t) { f.execFile = function(program, args, opts, cb) { f.execFile = function(program, args, opts, cb) { t.ok(re.test(program)) - t.ok(/import platform/.test(args[1])) + t.ok(/import sys/.test(args[1])) cb(null, '2.7.0') } t.strictEqual(program, 'py.exe') From 1309efb4d4ad2f5e1097bd8310d126fd4642bed2 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Mon, 2 Jul 2018 17:37:03 +0200 Subject: [PATCH 30/46] doc: fix visual studio links Fixes: https://github.com/nodejs/node-gyp/issues/1472 PR-URL: https://github.com/nodejs/node-gyp/pull/1490 Reviewed-By: Jon Moss --- README.md | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 11a9033af5..db54896f89 100644 --- a/README.md +++ b/README.md @@ -47,22 +47,11 @@ Install all the required tools and configurations using Microsoft's [windows-bui #### Option 2 Install tools and configuration manually: - * Visual C++ Build Environment: - * Option 1: Install [Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) using the **Default Install** option. - - * Option 2: Install [Visual Studio 2015](https://www.visualstudio.com/products/visual-studio-community-vs) and select *Common Tools for Visual C++* during setup. This also works with the free Community and Express for Desktop editions. - - * Option 3: if you already have Visual Studio 2015 installed and did not install the - *Common Tools for Visual C++* during setup, you can `File -> New -> Project`, pick - any of the options under `Templates -> Other Languages -> Visual C++` then `Ok` - and Visual Studio will offer to install the *Common Tools for Visual C++* with a - "Install Missing Features" / "You need the Universal Windows App Development Tools - to develop Windows app projects." dialog. - - > :bulb: [Windows Vista / 7 only] requires [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773) - + * Install Visual C++ Build Environment: [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) + (using "Visual C++ build tools" workload) or [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community) + (using the "Desktop development with C++" workload) * Install [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` is not supported), and run `npm config set python python2.7` (or see below for further instructions on specifying the proper Python version and path.) - * Launch cmd, `npm config set msvs_version 2015` + * Launch cmd, `npm config set msvs_version 2017` If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips. From a0cf9d53ce0031081a95662a551b3fffa846aa5e Mon Sep 17 00:00:00 2001 From: Jonas Hermsmeier Date: Tue, 5 Jun 2018 14:56:02 +0200 Subject: [PATCH 31/46] doc: update link to commit guidelines This updates the link to the commit guidelines in the `PULL_REQUEST_TEMPLATE.md`, as they have moved from the `CONTRIBUTING.md` to `doc/guides/contributing/pull-requests.md` PR-URL: https://github.com/nodejs/node-gyp/pull/1456 Reviewed-By: Jon Moss --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7a61664287..10156d89af 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,7 @@ Contributor guide: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md - [ ] `npm install && npm test` passes - [ ] tests are included - [ ] documentation is changed or added -- [ ] commit message follows [commit guidelines](https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#commit-message-guidelines) +- [ ] commit message follows [commit guidelines](https://github.com/nodejs/node/blob/master/doc/guides/contributing/pull-requests.md#commit-message-guidelines) ##### Description of change From d9ee0eaffef13f1887a9bb38f39f3d876689fe9d Mon Sep 17 00:00:00 2001 From: Ivan Daniluk Date: Fri, 10 Nov 2017 20:31:13 +0100 Subject: [PATCH 32/46] doc: update Xcode preferences tab name. PR-URL: https://github.com/nodejs/node-gyp/pull/1330 Reviewed-By: Jon Moss --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db54896f89..e88bd0b5be 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ You will also need to install: * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on macOS) * [Xcode](https://developer.apple.com/xcode/download/) - * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` (or by running `xcode-select --install` in your Terminal) + * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Locations` (or by running `xcode-select --install` in your Terminal) * This step will install `gcc` and the related toolchain containing `make` ### On Windows From fb2d3a264fb9fe0d349dc7610ef2137ab7b6fb32 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Tue, 26 Sep 2017 16:45:11 -0400 Subject: [PATCH 33/46] deps: pin `request` version range Required for "node < 4" compatibility and is congruent with `npm` minimum for passing `npm test` >= 2.9.0 setting < 2.82.0 allows deduping PR-URL: https://github.com/nodejs/node-gyp/pull/1300 Fixes: https://github.com/nodejs/node-gyp/issues/1299 Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69b450fbaf..dd0920e5f9 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", "osenv": "0", - "request": "2", + "request": ">=2.9.0 <2.82.0", "rimraf": "2", "semver": "~5.3.0", "tar": "^3.1.3", From baa0616c7d06344b369d8d953c45f9ba8507bae3 Mon Sep 17 00:00:00 2001 From: Rohit Hazra Date: Thu, 5 Jul 2018 00:03:15 +0530 Subject: [PATCH 34/46] deps: bump request to 2.8.7, fixes heok/hawk issues PR-URL: https://github.com/nodejs/node-gyp/pull/1492 Reviewed-By: Jeremiah Senkpiel Reviewed-By: Matheus Marchini Reviewed-By: Jon Moss Reviewed-By: Rod Vagg --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd0920e5f9..0839aff48e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", "osenv": "0", - "request": ">=2.9.0 <2.82.0", + "request": "^2.87.0", "rimraf": "2", "semver": "~5.3.0", "tar": "^3.1.3", From eb78b5a25871eec774d04a9b51924188d31501af Mon Sep 17 00:00:00 2001 From: Rohit Hazra Date: Sat, 21 Jul 2018 16:02:41 +0530 Subject: [PATCH 35/46] test: added test/processExecSync.js for when execFileSync is not available. PR-URL: https://github.com/nodejs/node-gyp/pull/1492 Reviewed-By: Jeremiah Senkpiel Reviewed-By: Matheus Marchini Reviewed-By: Jon Moss Reviewed-By: Rod Vagg --- test/processExecSync.js | 141 ++++++++++++++++++++++++++++++++++++++++ test/test-addon.js | 2 +- 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 test/processExecSync.js diff --git a/test/processExecSync.js b/test/processExecSync.js new file mode 100644 index 0000000000..d9e8534280 --- /dev/null +++ b/test/processExecSync.js @@ -0,0 +1,141 @@ +var fs = require('graceful-fs') +var child_process = require('child_process') +var exec = child_process.exec + +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + }; +} + +function processExecSync(file, args, options) { + var child, error, timeout, tmpdir, command, quote; + command = makeCommand(file, args); + + /* + this function emulates child_process.execSync for legacy node <= 0.10.x + derived from https://github.com/gvarsanyi/sync-exec/blob/master/js/sync-exec.js + */ + + options = options || {}; + // init timeout + timeout = Date.now() + options.timeout; + // init tmpdir + var os_temp_base = "/tmp"; + var os = determine_os(); + os_temp_base = "/tmp" + + if(process.env.TMP){ + os_temp_base = process.env.TMP; + } + + if(os_temp_base[os_temp_base.length - 1] !== "/"){ + os_temp_base += "/"; + } + + tmpdir = os_temp_base+'processExecSync.' + Date.now() + Math.random(); + fs.mkdirSync(tmpdir); + + // init command + if(os === "linux"){ + command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + + '/stderr); echo $? > ' + tmpdir + '/status'; + }else{ + command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + + '/stderr) | echo %errorlevel% > ' + tmpdir + '/status | exit'; + } + + // init child + child = exec(command, options, function () { + return; + }); + + var maxTry = 100000; // increases the test time by 6 seconds on win-2016-node-0.10 + var tryCount = 0; + while (tryCount < maxTry) { + try { + var x = fs.readFileSync(tmpdir + '/status'); + if(x.toString() === "0"){ + break; + } + } catch (ignore) { + } + tryCount++; + if (Date.now() > timeout) { + error = child; + break; + } + } + + ['stdout', 'stderr', 'status'].forEach(function (file) { + child[file] = fs.readFileSync(tmpdir + '/' + file, options.encoding); + setTimeout(unlinkFile, 500, tmpdir + '/' + file); + }); + + child.status = Number(child.status); + if (child.status !== 0) { + error = child; + } + + try { + fs.rmdirSync(tmpdir); + } catch (ignore) { + } + if (error) { + throw error; + } + return child.stdout; +} + +module.exports = processExecSync; + +function makeCommand(file, args){ + var command, quote; + command = file + if(args.length > 0){ + for(var i in args){ + command = command + " "; + if(args[i][0] === "-"){ + command = command + args[i]; + }else{ + if(!quote){ + command = command + "\""; + quote = true; + } + command = command + args[i]; + if(quote){ + if(args.length === (parseInt(i) + 1)){ + command = command + "\""; + } + } + } + } + } + return command; +} + +function determine_os(){ + var os = ""; + var tmpVar = ""; + if(process.env.OSTYPE){ + tmpVar = process.env.OSTYPE; + }else if(process.env.OS){ + tmpVar = process.env.OS; + }else{ + //default is linux + tmpVar = "linux"; + } + + if(tmpVar.startsWith("linux")){ + os = "linux" + } + if(tmpVar.startsWith("win")){ + os = "win" + } + + return os; +} + +function unlinkFile(file){ + fs.unlinkSync(file); +} diff --git a/test/test-addon.js b/test/test-addon.js index 7ace1caf6a..2f4509ade4 100644 --- a/test/test-addon.js +++ b/test/test-addon.js @@ -6,7 +6,7 @@ var fs = require('graceful-fs') var child_process = require('child_process') var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') -var execFileSync = child_process.execFileSync +var execFileSync = child_process.execFileSync || require('./processExecSync') var execFile = child_process.execFile function runHello() { From 877b83b31691b9d30b85cd696853a06695ee1112 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Wed, 8 Aug 2018 21:43:32 +1000 Subject: [PATCH 36/46] test: formatting and minor fixes for execFileSync replacement PR-URL: https://github.com/nodejs/node-gyp/pull/1521 Reviewed-By: Jon Moss Reviewed-By: Richard Lau --- test/process-exec-sync.js | 138 +++++++++++++++++++++++++++++++++++++ test/processExecSync.js | 141 -------------------------------------- test/test-addon.js | 4 +- 3 files changed, 140 insertions(+), 143 deletions(-) create mode 100644 test/process-exec-sync.js delete mode 100644 test/processExecSync.js diff --git a/test/process-exec-sync.js b/test/process-exec-sync.js new file mode 100644 index 0000000000..859cbc1f6f --- /dev/null +++ b/test/process-exec-sync.js @@ -0,0 +1,138 @@ +'use strict' + +var fs = require('graceful-fs') +var child_process = require('child_process') + +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search + } +} + +function processExecSync(file, args, options) { + var child, error, timeout, tmpdir, command, quote + command = makeCommand(file, args) + + /* + this function emulates child_process.execSync for legacy node <= 0.10.x + derived from https://github.com/gvarsanyi/sync-exec/blob/master/js/sync-exec.js + */ + + options = options || {} + // init timeout + timeout = Date.now() + options.timeout + // init tmpdir + var os_temp_base = '/tmp' + var os = determine_os() + os_temp_base = '/tmp' + + if (process.env.TMP) { + os_temp_base = process.env.TMP + } + + if (os_temp_base[os_temp_base.length - 1] !== '/') { + os_temp_base += '/' + } + + tmpdir = os_temp_base + 'processExecSync.' + Date.now() + Math.random() + fs.mkdirSync(tmpdir) + + // init command + if (os === 'linux') { + command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + + '/stderr); echo $? > ' + tmpdir + '/status' + } else { + command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + + '/stderr) | echo %errorlevel% > ' + tmpdir + '/status | exit' + } + + // init child + child = child_process.exec(command, options) + + var maxTry = 100000 // increases the test time by 6 seconds on win-2016-node-0.10 + var tryCount = 0 + while (tryCount < maxTry) { + try { + var x = fs.readFileSync(tmpdir + '/status') + if (x.toString() === '0') { + break + } + } catch (ignore) {} + tryCount++ + if (Date.now() > timeout) { + error = child + break + } + } + + ['stdout', 'stderr', 'status'].forEach(function (file) { + child[file] = fs.readFileSync(tmpdir + '/' + file, options.encoding) + setTimeout(unlinkFile, 500, tmpdir + '/' + file) + }) + + child.status = Number(child.status) + if (child.status !== 0) { + error = child + } + + try { + fs.rmdirSync(tmpdir) + } catch (ignore) {} + if (error) { + throw error + } + return child.stdout +} + +function makeCommand(file, args) { + var command, quote + command = file + if (args.length > 0) { + for(var i in args) { + command = command + ' ' + if (args[i][0] === '-') { + command = command + args[i] + } else { + if (!quote) { + command = command + '\"' + quote = true + } + command = command + args[i] + if (quote) { + if (args.length === (parseInt(i) + 1)) { + command = command + '\"' + } + } + } + } + } + return command +} + +function determine_os() { + var os = '' + var tmpVar = '' + if (process.env.OSTYPE) { + tmpVar = process.env.OSTYPE + } else if (process.env.OS) { + tmpVar = process.env.OS + } else { + //default is linux + tmpVar = 'linux' + } + + if (tmpVar.startsWith('linux')) { + os = 'linux' + } + if (tmpVar.startsWith('win')) { + os = 'win' + } + + return os +} + +function unlinkFile(file) { + fs.unlinkSync(file) +} + +module.exports = processExecSync diff --git a/test/processExecSync.js b/test/processExecSync.js deleted file mode 100644 index d9e8534280..0000000000 --- a/test/processExecSync.js +++ /dev/null @@ -1,141 +0,0 @@ -var fs = require('graceful-fs') -var child_process = require('child_process') -var exec = child_process.exec - -if (!String.prototype.startsWith) { - String.prototype.startsWith = function(search, pos) { - return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; - }; -} - -function processExecSync(file, args, options) { - var child, error, timeout, tmpdir, command, quote; - command = makeCommand(file, args); - - /* - this function emulates child_process.execSync for legacy node <= 0.10.x - derived from https://github.com/gvarsanyi/sync-exec/blob/master/js/sync-exec.js - */ - - options = options || {}; - // init timeout - timeout = Date.now() + options.timeout; - // init tmpdir - var os_temp_base = "/tmp"; - var os = determine_os(); - os_temp_base = "/tmp" - - if(process.env.TMP){ - os_temp_base = process.env.TMP; - } - - if(os_temp_base[os_temp_base.length - 1] !== "/"){ - os_temp_base += "/"; - } - - tmpdir = os_temp_base+'processExecSync.' + Date.now() + Math.random(); - fs.mkdirSync(tmpdir); - - // init command - if(os === "linux"){ - command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + - '/stderr); echo $? > ' + tmpdir + '/status'; - }else{ - command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + - '/stderr) | echo %errorlevel% > ' + tmpdir + '/status | exit'; - } - - // init child - child = exec(command, options, function () { - return; - }); - - var maxTry = 100000; // increases the test time by 6 seconds on win-2016-node-0.10 - var tryCount = 0; - while (tryCount < maxTry) { - try { - var x = fs.readFileSync(tmpdir + '/status'); - if(x.toString() === "0"){ - break; - } - } catch (ignore) { - } - tryCount++; - if (Date.now() > timeout) { - error = child; - break; - } - } - - ['stdout', 'stderr', 'status'].forEach(function (file) { - child[file] = fs.readFileSync(tmpdir + '/' + file, options.encoding); - setTimeout(unlinkFile, 500, tmpdir + '/' + file); - }); - - child.status = Number(child.status); - if (child.status !== 0) { - error = child; - } - - try { - fs.rmdirSync(tmpdir); - } catch (ignore) { - } - if (error) { - throw error; - } - return child.stdout; -} - -module.exports = processExecSync; - -function makeCommand(file, args){ - var command, quote; - command = file - if(args.length > 0){ - for(var i in args){ - command = command + " "; - if(args[i][0] === "-"){ - command = command + args[i]; - }else{ - if(!quote){ - command = command + "\""; - quote = true; - } - command = command + args[i]; - if(quote){ - if(args.length === (parseInt(i) + 1)){ - command = command + "\""; - } - } - } - } - } - return command; -} - -function determine_os(){ - var os = ""; - var tmpVar = ""; - if(process.env.OSTYPE){ - tmpVar = process.env.OSTYPE; - }else if(process.env.OS){ - tmpVar = process.env.OS; - }else{ - //default is linux - tmpVar = "linux"; - } - - if(tmpVar.startsWith("linux")){ - os = "linux" - } - if(tmpVar.startsWith("win")){ - os = "win" - } - - return os; -} - -function unlinkFile(file){ - fs.unlinkSync(file); -} diff --git a/test/test-addon.js b/test/test-addon.js index 2f4509ade4..89350effc4 100644 --- a/test/test-addon.js +++ b/test/test-addon.js @@ -6,12 +6,12 @@ var fs = require('graceful-fs') var child_process = require('child_process') var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') -var execFileSync = child_process.execFileSync || require('./processExecSync') +var execFileSync = child_process.execFileSync || require('./process-exec-sync') var execFile = child_process.execFile function runHello() { var testCode = "console.log(require('hello_world').hello())" - return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString() + return execFileSync(process.execPath, ['-e', testCode], { cwd: __dirname }).toString() } function getEncoding() { From 8ad9ecdb15433fe76ac726b86783de3b206ce62a Mon Sep 17 00:00:00 2001 From: Stewart Addison Date: Mon, 14 Nov 2016 13:41:31 +0000 Subject: [PATCH 37/46] gyp: backport GYP fix to fix AIX shared suffix Required to support the shared library builds on AIX - this sets the shared library suffix within GYP to .a instead of .so on AIX My patch: https://codereview.chromium.org/2492233002/ was landed as as part of this one which fixed some other (not required, but included for completeness of the backport) changes: PR-URL: https://github.com/nodejs/node/pull9675 Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis Reviewed-By: Michael Dawson Ref: https://codereview.chromium.org/2511733005/ --- gyp/AUTHORS | 7 ++++--- gyp/PRESUBMIT.py | 26 ++++++++++++++------------ gyp/pylib/gyp/generator/make.py | 10 ++++++++-- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/gyp/AUTHORS b/gyp/AUTHORS index fecf84a1c4..d76d8cd768 100644 --- a/gyp/AUTHORS +++ b/gyp/AUTHORS @@ -1,9 +1,10 @@ # Names should be added to this file like so: # Name or Organization -Google Inc. -Bloomberg Finance L.P. -Yandex LLC +Google Inc. <*@google.com> +Bloomberg Finance L.P. <*@bloomberg.net> +IBM Inc. <*@*.ibm.com> +Yandex LLC <*@yandex-team.ru> Steven Knight Ryan Norton diff --git a/gyp/PRESUBMIT.py b/gyp/PRESUBMIT.py index dde025383c..f6c8a357af 100644 --- a/gyp/PRESUBMIT.py +++ b/gyp/PRESUBMIT.py @@ -73,23 +73,15 @@ ] -def CheckChangeOnUpload(input_api, output_api): - report = [] - report.extend(input_api.canned_checks.PanProjectChecks( - input_api, output_api)) - return report - - -def CheckChangeOnCommit(input_api, output_api): - report = [] - +def _LicenseHeader(input_api): # Accept any year number from 2009 to the current year. current_year = int(input_api.time.strftime('%Y')) allowed_years = (str(s) for s in reversed(xrange(2009, current_year + 1))) + years_re = '(' + '|'.join(allowed_years) + ')' # The (c) is deprecated, but tolerate it until it's removed from all files. - license = ( + return ( r'.*? Copyright (\(c\) )?%(year)s Google Inc\. All rights reserved\.\n' r'.*? Use of this source code is governed by a BSD-style license that ' r'can be\n' @@ -98,8 +90,18 @@ def CheckChangeOnCommit(input_api, output_api): 'year': years_re, } +def CheckChangeOnUpload(input_api, output_api): + report = [] + report.extend(input_api.canned_checks.PanProjectChecks( + input_api, output_api, license_header=_LicenseHeader(input_api))) + return report + + +def CheckChangeOnCommit(input_api, output_api): + report = [] + report.extend(input_api.canned_checks.PanProjectChecks( - input_api, output_api, license_header=license)) + input_api, output_api, license_header=_LicenseHeader(input_api))) report.extend(input_api.canned_checks.CheckTreeIsOpen( input_api, output_api, 'http://gyp-status.appspot.com/status', diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 8990057a04..51c5026a1e 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -90,7 +90,10 @@ def CalculateVariables(default_variables, params): if flavor == 'android': operating_system = 'linux' # Keep this legacy behavior for now. default_variables.setdefault('OS', operating_system) - default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') + if flavor == 'aix': + default_variables.setdefault('SHARED_LIB_SUFFIX', '.a') + else: + default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') default_variables.setdefault('SHARED_LIB_DIR','$(builddir)/lib.$(TOOLSET)') default_variables.setdefault('LIB_DIR', '$(obj).$(TOOLSET)') @@ -1369,7 +1372,10 @@ def ComputeOutputBasename(self, spec): if target[:3] == 'lib': target = target[3:] target_prefix = 'lib' - target_ext = '.so' + if self.flavor == 'aix': + target_ext = '.a' + else: + target_ext = '.so' elif self.type == 'none': target = '%s.stamp' % target elif self.type != 'executable': From a26504010c44daf97f17ffcb6afddf0444b14986 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 28 May 2016 00:10:28 +0200 Subject: [PATCH 38/46] gyp: float gyp patch for long filenames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pulling in https://codereview.chromium.org/2019133002/ in its current state, as gyp seems to be largely abandoned as a project. Original commit message: Hash intermediate file name to avoid ENAMETOOLONG Hash the intermediate Makefile target used for multi-output rules so that it still works when the involved file names are very long. Since the intermediate file's name is effectively arbitrary, this does not come with notable behavioural changes. The `import hashlib` boilerplate is taken directly from `xcodeproj_file.py`. Concretely, this makes the V8 inspector build currently fail when long pathnames are involved, notably when using ecryptfs which has a lower file name length limit. Fixes: https://github.com/nodejs/node/issues/7959 Ref: https://github.com/nodejs/node/issues/7510 PR-URL: https://github.com/nodejs/node/pull/7963 Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Saúl Ibarra Corretgé --- gyp/pylib/gyp/generator/make.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 51c5026a1e..e0485d7299 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -31,6 +31,8 @@ from gyp.common import GetEnvironFallback from gyp.common import GypError +import hashlib + generator_default_variables = { 'EXECUTABLE_PREFIX': '', 'EXECUTABLE_SUFFIX': '', @@ -1771,7 +1773,10 @@ def WriteMakeRule(self, outputs, inputs, actions=None, comment=None, # actual command. # - The intermediate recipe will 'touch' the intermediate file. # - The multi-output rule will have an do-nothing recipe. - intermediate = "%s.intermediate" % (command if command else self.target) + + # Hash the target name to avoid generating overlong filenames. + cmddigest = hashlib.sha1(command if command else self.target).hexdigest() + intermediate = "%s.intermediate" % cmddigest self.WriteLn('%s: %s' % (' '.join(outputs), intermediate)) self.WriteLn('\t%s' % '@:'); self.WriteLn('%s: %s' % ('.INTERMEDIATE', intermediate)) From 5c2aad83ea45308bebfe3a10520f0cf3010b5bbf Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 5 Aug 2016 13:23:22 +0200 Subject: [PATCH 39/46] gyp: add compile_commands.json gyp generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this is a re-base of the gyp part of 3c46bb9931ecea71167342322e09121ee48cde8e after bumping GYP version to https://chromium.googlesource.com/external/gyp/+/eb296f67da078ec01f5e3a9ea9cdc6d26d680161 Original-Review-By: James M Snell Ref: https://github.com/nodejs/node/pull/7986 PR-URL: https://github.com/nodejs/node/pull/12450 Reviewed-By: João Reis --- .../gyp/generator/compile_commands_json.py | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 tools/gyp/pylib/gyp/generator/compile_commands_json.py diff --git a/tools/gyp/pylib/gyp/generator/compile_commands_json.py b/tools/gyp/pylib/gyp/generator/compile_commands_json.py new file mode 100644 index 0000000000..575db63c4e --- /dev/null +++ b/tools/gyp/pylib/gyp/generator/compile_commands_json.py @@ -0,0 +1,115 @@ +# Copyright (c) 2016 Ben Noordhuis . All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import gyp.common +import gyp.xcode_emulation +import json +import os + +generator_additional_non_configuration_keys = [] +generator_additional_path_sections = [] +generator_extra_sources_for_rules = [] +generator_filelist_paths = None +generator_supports_multiple_toolsets = True +generator_wants_sorted_dependencies = False + +# Lifted from make.py. The actual values don't matter much. +generator_default_variables = { + 'CONFIGURATION_NAME': '$(BUILDTYPE)', + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/$(TARGET)/geni', + 'PRODUCT_DIR': '$(builddir)', + 'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s', + 'RULE_INPUT_EXT': '$(suffix $<)', + 'RULE_INPUT_NAME': '$(notdir $<)', + 'RULE_INPUT_PATH': '$(abspath $<)', + 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', + 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', + 'SHARED_LIB_PREFIX': 'lib', + 'STATIC_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', +} + + +def IsMac(params): + return 'mac' == gyp.common.GetFlavor(params) + + +def CalculateVariables(default_variables, params): + default_variables.setdefault('OS', gyp.common.GetFlavor(params)) + + +def AddCommandsForTarget(cwd, target, params, per_config_commands): + output_dir = params['generator_flags']['output_dir'] + for configuration_name, configuration in target['configurations'].iteritems(): + builddir_name = os.path.join(output_dir, configuration_name) + + if IsMac(params): + xcode_settings = gyp.xcode_emulation.XcodeSettings(target) + cflags = xcode_settings.GetCflags(configuration_name) + cflags_c = xcode_settings.GetCflagsC(configuration_name) + cflags_cc = xcode_settings.GetCflagsCC(configuration_name) + else: + cflags = configuration.get('cflags', []) + cflags_c = configuration.get('cflags_c', []) + cflags_cc = configuration.get('cflags_cc', []) + + cflags_c = cflags + cflags_c + cflags_cc = cflags + cflags_cc + + defines = configuration.get('defines', []) + defines = ['-D' + s for s in defines] + + # TODO(bnoordhuis) Handle generated source files. + sources = target.get('sources', []) + sources = [s for s in sources if s.endswith('.c') or s.endswith('.cc')] + + def resolve(filename): + return os.path.abspath(os.path.join(cwd, filename)) + + # TODO(bnoordhuis) Handle generated header files. + include_dirs = configuration.get('include_dirs', []) + include_dirs = [s for s in include_dirs if not s.startswith('$(obj)')] + includes = ['-I' + resolve(s) for s in include_dirs] + + defines = gyp.common.EncodePOSIXShellList(defines) + includes = gyp.common.EncodePOSIXShellList(includes) + cflags_c = gyp.common.EncodePOSIXShellList(cflags_c) + cflags_cc = gyp.common.EncodePOSIXShellList(cflags_cc) + + commands = per_config_commands.setdefault(configuration_name, []) + for source in sources: + file = resolve(source) + isc = source.endswith('.c') + cc = 'cc' if isc else 'c++' + cflags = cflags_c if isc else cflags_cc + command = ' '.join((cc, defines, includes, cflags, + '-c', gyp.common.EncodePOSIXShellArgument(file))) + commands.append(dict(command=command, directory=output_dir, file=file)) + + +def GenerateOutput(target_list, target_dicts, data, params): + per_config_commands = {} + for qualified_target, target in target_dicts.iteritems(): + build_file, target_name, toolset = ( + gyp.common.ParseQualifiedTarget(qualified_target)) + if IsMac(params): + settings = data[build_file] + gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(settings, target) + cwd = os.path.dirname(build_file) + AddCommandsForTarget(cwd, target, params, per_config_commands) + + output_dir = params['generator_flags']['output_dir'] + for configuration_name, commands in per_config_commands.iteritems(): + filename = os.path.join(output_dir, + configuration_name, + 'compile_commands.json') + gyp.common.EnsureDirExists(filename) + fp = open(filename, 'w') + json.dump(commands, fp=fp, indent=0, check_circular=False) + + +def PerformBuild(data, configurations, params): + pass From 6ffef511e1ba5b0e747d59cc3d65635c85a627de Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Tue, 18 Oct 2016 16:41:26 +0200 Subject: [PATCH 40/46] gyp: enable cctest to use objects (gyp part) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this is a re-base of the gyp part of 6a09a69ec9d36b705e9bde2ac1a193566a702d96 after bumping GYP version to https://chromium.googlesource.com/external/gyp/+/eb296f67da078ec01f5e3a9ea9cdc6d26d680161 Original-PR-URL: https://github.com/nodejs/node/pull/11956 Original-Ref: https://github.com/nodejs/node/pull/9163 Original-Reviewed-By: James M Snell PR-URL: https://github.com/nodejs/node/pull/12450 Reviewed-By: João Reis --- gyp/pylib/gyp/generator/make.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index e0485d7299..782b1b7ff5 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -147,7 +147,7 @@ def CalculateGeneratorInputInfo(params): # special "figure out circular dependencies" flags around the entire # input list during linking. quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) $(LIBS) -Wl,--end-group # We support two kinds of shared objects (.so): # 1) shared_library, which is just bundling together many dependent libraries From f739c18da9e86545a289977fb0ee459b021af917 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Thu, 13 Jul 2017 15:05:54 -0700 Subject: [PATCH 41/46] gyp: implement LD/LDXX for ninja and FIPS The ability to set the link rule is used for FIPS, and needs to set both the `ld =` and `ldxx =` variables in the ninja build file to link c++ (node) and c (openssl-cli, etc.) executables. URL: https://github.com/nodejs/node/pull/14227 Reviewed-By: Refael Ackermann Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- gyp/pylib/gyp/generator/ninja.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index 4ee2bd1b4d..42580fe3d3 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -1873,6 +1873,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, ld = os.path.join(build_to_root, value) if key == 'LD.host': ld_host = os.path.join(build_to_root, value) + if key == 'LDXX': + ldxx = os.path.join(build_to_root, value) + if key == 'LDXX.host': + ldxx_host = os.path.join(build_to_root, value) if key == 'NM': nm = os.path.join(build_to_root, value) if key == 'NM.host': @@ -1962,6 +1966,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, CommandWithWrapper('CXX.host', wrappers, cxx_host)) if flavor == 'win': master_ninja.variable('ld_host', ld_host) + master_ninja.variable('ldxx_host', ldxx_host) else: master_ninja.variable('ld_host', CommandWithWrapper( 'LINK', wrappers, ld_host)) From d8eac7a6fe18583e4ed03934bf7a80bd9ea71bc0 Mon Sep 17 00:00:00 2001 From: Masashi Hirano Date: Mon, 14 May 2018 23:16:58 +0900 Subject: [PATCH 42/46] tools: fix "the the" typos in comments PR-URL: https://github.com/nodejs/node/pull/20716 Fixes: https://github.com/nodejs/node/issues/20682 Reviewed-By: Trivikram Kamat Reviewed-By: Ruben Bridgewater Reviewed-By: Michael Dawson Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- gyp/pylib/gyp/MSVSSettings.py | 2 +- gyp/pylib/gyp/generator/make.py | 2 +- gyp/pylib/gyp/generator/ninja.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gyp/pylib/gyp/MSVSSettings.py b/gyp/pylib/gyp/MSVSSettings.py index 4985756bdd..a08cc154d7 100644 --- a/gyp/pylib/gyp/MSVSSettings.py +++ b/gyp/pylib/gyp/MSVSSettings.py @@ -417,7 +417,7 @@ def FixVCMacroSlashes(s): def ConvertVCMacrosToMSBuild(s): - """Convert the the MSVS macros found in the string to the MSBuild equivalent. + """Convert the MSVS macros found in the string to the MSBuild equivalent. This list is probably not exhaustive. Add as needed. """ diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 782b1b7ff5..fe801b77ce 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -19,7 +19,7 @@ # # Global settings and utility functions are currently stuffed in the # toplevel Makefile. It may make sense to generate some .mk files on -# the side to keep the the files readable. +# the side to keep the files readable. import os import re diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index 42580fe3d3..ba911c19dc 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -140,7 +140,7 @@ def __init__(self, type): # On Windows, incremental linking requires linking against all the .objs # that compose a .lib (rather than the .lib itself). That list is stored # here. In this case, we also need to save the compile_deps for the target, - # so that the the target that directly depends on the .objs can also depend + # so that the target that directly depends on the .objs can also depend # on those. self.component_objs = None self.compile_deps = None From eebc8f6a9fb74638dd58e9173a80d0601142f314 Mon Sep 17 00:00:00 2001 From: Ujjwal Sharma Date: Mon, 25 Jun 2018 16:17:16 +0530 Subject: [PATCH 43/46] tools: patch gyp to avoid xcrun errors Previously running ./configure with only the Xcode Command Line Tools installed would give: xcrun: error: unable to lookup item 'PlatformPath' from command line tools installation xcrun: error: unable to lookup item 'PlatformPath' in SDK '/' Co-authored-by: Ben Noordhuis Fixes: https://github.com/nodejs/node/issues/12531 PR-URL: https://github.com/nodejs/node/pull/21520 Reviewed-By: Ben Noordhuis Reviewed-By: Joyee Cheung Reviewed-By: Gibson Fahnestock Reviewed-By: Refael Ackermann Reviewed-By: James M Snell --- gyp/pylib/gyp/xcode_emulation.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index 4321f60895..69f7d97cfa 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -233,6 +233,9 @@ def _IsIosWatchKitExtension(self): def _IsIosWatchApp(self): return int(self.spec.get('ios_watch_app', 0)) != 0 + def _IsXCTest(self): + return int(self.spec.get('mac_xctest_bundle', 0)) != 0 + def GetFrameworkVersion(self): """Returns the framework version of the current target. Only valid for bundles.""" @@ -568,6 +571,11 @@ def GetCflags(self, configname, arch=None): cflags += self._Settings().get('WARNING_CFLAGS', []) + if self._IsXCTest(): + platform_root = self._XcodePlatformPath(configname) + if platform_root: + cflags.append('-F' + platform_root + '/Developer/Library/Frameworks/') + if sdk_root: framework_root = sdk_root else: @@ -831,6 +839,11 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): for directory in framework_dirs: ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root)) + if self._IsXCTest(): + platform_root = self._XcodePlatformPath(configname) + if platform_root: + cflags.append('-F' + platform_root + '/Developer/Library/Frameworks/') + is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension() if sdk_root and is_extension: # Adds the link flags for extensions. These flags are common for all From 2ca32e0405ad5c45da0f4c5aa09a1a68352a6c6b Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Tue, 18 Apr 2017 02:20:56 -0400 Subject: [PATCH 44/46] gyp: fix ninja build failure (GYP patch) Currently the files specified in libraries in node.gyp `cctest` target are getting a '.lib' extension on windows when generated with ninja. This commit adds a check to see if a file has a '.obj' extension and in that case no '.lib' extension will be added. Also, the LIBS specified in the 'libraries' section are not being included in the --start-group --end-group section which means that these libraries will not be searched causing issue with linkers where the order matters. PR-URL: https://github.com/nodejs/node/pull/12484 Fixes: https://github.com/nodejs/node/issues/12448 Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Refael Ackermann Reviewed-By: Gibson Fahnestock --- gyp/pylib/gyp/generator/ninja.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index ba911c19dc..a00573ebf2 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -2091,13 +2091,13 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, restat=True, command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'}, rspfile='$link_file_list', - rspfile_content='-Wl,--start-group $in -Wl,--end-group $solibs $libs', + rspfile_content='-Wl,--start-group $in $solibs $libs -Wl,--end-group', pool='link_pool') master_ninja.rule( 'link', description='LINK $out', command=('$ld $ldflags -o $out ' - '-Wl,--start-group $in -Wl,--end-group $solibs $libs'), + '-Wl,--start-group $in $solibs $libs -Wl,--end-group'), pool='link_pool') elif flavor == 'win': master_ninja.rule( From bac9e44a8c0c55ff92366de18dea4d6d5017823b Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 9 Aug 2018 10:46:43 +1000 Subject: [PATCH 45/46] doc: update changelog --- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f7e66f8d0..33bbfad5de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,54 @@ +v3.8.0 2018-08-09 +================= + +* [[`c5929cb4fe`](https://github.com/nodejs/node-gyp/commit/c5929cb4fe)] - **doc**: update Xcode preferences tab name. (Ivan Daniluk) [#1330](https://github.com/nodejs/node-gyp/pull/1330) +* [[`8b488da8b9`](https://github.com/nodejs/node-gyp/commit/8b488da8b9)] - **doc**: update link to commit guidelines (Jonas Hermsmeier) [#1456](https://github.com/nodejs/node-gyp/pull/1456) +* [[`b4fe8c16f9`](https://github.com/nodejs/node-gyp/commit/b4fe8c16f9)] - **doc**: fix visual studio links (Bartosz Sosnowski) [#1490](https://github.com/nodejs/node-gyp/pull/1490) +* [[`536759c7e9`](https://github.com/nodejs/node-gyp/commit/536759c7e9)] - **configure**: use sys.version\_info to get python version (Yang Guo) [#1504](https://github.com/nodejs/node-gyp/pull/1504) +* [[`94c39c604e`](https://github.com/nodejs/node-gyp/commit/94c39c604e)] - **gyp**: fix ninja build failure (GYP patch) (Daniel Bevenius) [nodejs/node#12484](https://github.com/nodejs/node/pull/12484) +* [[`e8ea74e0fa`](https://github.com/nodejs/node-gyp/commit/e8ea74e0fa)] - **tools**: patch gyp to avoid xcrun errors (Ujjwal Sharma) [nodejs/node#21520](https://github.com/nodejs/node/pull/21520) +* [[`ea9aff44f2`](https://github.com/nodejs/node-gyp/commit/ea9aff44f2)] - **tools**: fix "the the" typos in comments (Masashi Hirano) [nodejs/node#20716](https://github.com/nodejs/node/pull/20716) +* [[`207e5aa4fd`](https://github.com/nodejs/node-gyp/commit/207e5aa4fd)] - **gyp**: implement LD/LDXX for ninja and FIPS (Sam Roberts) +* [[`b416c5f4b7`](https://github.com/nodejs/node-gyp/commit/b416c5f4b7)] - **gyp**: enable cctest to use objects (gyp part) (Daniel Bevenius) [nodejs/node#12450](https://github.com/nodejs/node/pull/12450) +* [[`40692d016b`](https://github.com/nodejs/node-gyp/commit/40692d016b)] - **gyp**: add compile\_commands.json gyp generator (Ben Noordhuis) [nodejs/node#12450](https://github.com/nodejs/node/pull/12450) +* [[`fc3c4e2b10`](https://github.com/nodejs/node-gyp/commit/fc3c4e2b10)] - **gyp**: float gyp patch for long filenames (Anna Henningsen) [nodejs/node#7963](https://github.com/nodejs/node/pull/7963) +* [[`8aedbfdef6`](https://github.com/nodejs/node-gyp/commit/8aedbfdef6)] - **gyp**: backport GYP fix to fix AIX shared suffix (Stewart Addison) +* [[`6cd84b84fc`](https://github.com/nodejs/node-gyp/commit/6cd84b84fc)] - **test**: formatting and minor fixes for execFileSync replacement (Rod Vagg) [#1521](https://github.com/nodejs/node-gyp/pull/1521) +* [[`60e421363f`](https://github.com/nodejs/node-gyp/commit/60e421363f)] - **test**: added test/processExecSync.js for when execFileSync is not available. (Rohit Hazra) [#1492](https://github.com/nodejs/node-gyp/pull/1492) +* [[`969447c5bd`](https://github.com/nodejs/node-gyp/commit/969447c5bd)] - **deps**: bump request to 2.8.7, fixes heok/hawk issues (Rohit Hazra) [#1492](https://github.com/nodejs/node-gyp/pull/1492) +* [[`340403ccfe`](https://github.com/nodejs/node-gyp/commit/340403ccfe)] - **win**: improve parsing of SDK version (Alessandro Vergani) [#1516](https://github.com/nodejs/node-gyp/pull/1516) + +v3.7.0 2018-06-08 +================= + +* [[`84cea7b30d`](https://github.com/nodejs/node-gyp/commit/84cea7b30d)] - Remove unused gyp test scripts. (Ben Noordhuis) [#1458](https://github.com/nodejs/node-gyp/pull/1458) +* [[`0540e4ec63`](https://github.com/nodejs/node-gyp/commit/0540e4ec63)] - **gyp**: escape spaces in filenames in make generator (Jeff Senn) [#1436](https://github.com/nodejs/node-gyp/pull/1436) +* [[`88fc6fa0ec`](https://github.com/nodejs/node-gyp/commit/88fc6fa0ec)] - Drop dependency on minimatch. (Brian Woodward) [#1158](https://github.com/nodejs/node-gyp/pull/1158) +* [[`1e203c5148`](https://github.com/nodejs/node-gyp/commit/1e203c5148)] - Fix include path when pointing to Node.js source (Richard Lau) [#1055](https://github.com/nodejs/node-gyp/pull/1055) +* [[`53d8cb967c`](https://github.com/nodejs/node-gyp/commit/53d8cb967c)] - Prefix build targets with /t: on Windows (Natalie Wolfe) [#1164](https://github.com/nodejs/node-gyp/pull/1164) +* [[`53a5f8ff38`](https://github.com/nodejs/node-gyp/commit/53a5f8ff38)] - **gyp**: add support for .mm files to msvs generator (Julien Racle) [#1167](https://github.com/nodejs/node-gyp/pull/1167) +* [[`dd8561e528`](https://github.com/nodejs/node-gyp/commit/dd8561e528)] - **zos**: don't use universal-new-lines mode (John Barboza) [#1451](https://github.com/nodejs/node-gyp/pull/1451) +* [[`e5a69010ed`](https://github.com/nodejs/node-gyp/commit/e5a69010ed)] - **zos**: add search locations for libnode.x (John Barboza) [#1451](https://github.com/nodejs/node-gyp/pull/1451) +* [[`79febace53`](https://github.com/nodejs/node-gyp/commit/79febace53)] - **doc**: update macOS information in README (Josh Parnham) [#1323](https://github.com/nodejs/node-gyp/pull/1323) +* [[`9425448945`](https://github.com/nodejs/node-gyp/commit/9425448945)] - **gyp**: don't print xcodebuild not found errors (Gibson Fahnestock) [#1370](https://github.com/nodejs/node-gyp/pull/1370) +* [[`6f1286f5b2`](https://github.com/nodejs/node-gyp/commit/6f1286f5b2)] - Fix infinite install loop. (Ben Noordhuis) [#1384](https://github.com/nodejs/node-gyp/pull/1384) +* [[`2580b9139e`](https://github.com/nodejs/node-gyp/commit/2580b9139e)] - Update `--nodedir` description in README. (Ben Noordhuis) [#1372](https://github.com/nodejs/node-gyp/pull/1372) +* [[`a61360391a`](https://github.com/nodejs/node-gyp/commit/a61360391a)] - Update README with another way to install on windows (JeffAtDeere) [#1352](https://github.com/nodejs/node-gyp/pull/1352) +* [[`47496bf6dc`](https://github.com/nodejs/node-gyp/commit/47496bf6dc)] - Fix IndexError when parsing GYP files. (Ben Noordhuis) [#1267](https://github.com/nodejs/node-gyp/pull/1267) +* [[`b2024dee7b`](https://github.com/nodejs/node-gyp/commit/b2024dee7b)] - **zos**: support platform (John Barboza) [#1276](https://github.com/nodejs/node-gyp/pull/1276) +* [[`90d86512f4`](https://github.com/nodejs/node-gyp/commit/90d86512f4)] - **win**: run PS with `-NoProfile` (Refael Ackermann) [#1292](https://github.com/nodejs/node-gyp/pull/1292) +* [[`2da5f86ef7`](https://github.com/nodejs/node-gyp/commit/2da5f86ef7)] - **doc**: add github PR and Issue templates (Gibson Fahnestock) [#1228](https://github.com/nodejs/node-gyp/pull/1228) +* [[`a46a770d68`](https://github.com/nodejs/node-gyp/commit/a46a770d68)] - **doc**: update proposed DCO and CoC (Mikeal Rogers) [#1229](https://github.com/nodejs/node-gyp/pull/1229) +* [[`7e803d58e0`](https://github.com/nodejs/node-gyp/commit/7e803d58e0)] - **doc**: headerify the Install instructions (Nick Schonning) [#1225](https://github.com/nodejs/node-gyp/pull/1225) +* [[`f27599193a`](https://github.com/nodejs/node-gyp/commit/f27599193a)] - **gyp**: update xml string encoding conversion (Liu Chao) [#1203](https://github.com/nodejs/node-gyp/pull/1203) +* [[`0a07e481f7`](https://github.com/nodejs/node-gyp/commit/0a07e481f7)] - **configure**: don't set ensure if tarball is set (Gibson Fahnestock) [#1220](https://github.com/nodejs/node-gyp/pull/1220) + +v3.6.3 2018-06-08 +================= + +* [[`90cd2e8da9`](https://github.com/nodejs/node-gyp/commit/90cd2e8da9)] - **gyp**: fix regex to match multi-digit versions (Jonas Hermsmeier) [#1455](https://github.com/nodejs/node-gyp/pull/1455) +* [[`7900122337`](https://github.com/nodejs/node-gyp/commit/7900122337)] - deps: pin `request` version range (Refael Ackerman) [#1300](https://github.com/nodejs/node-gyp/pull/1300) + v3.6.2 2017-06-01 ================= From 1ad3f92fc88e2d8e9e66694ace67fedf90a8fdc6 Mon Sep 17 00:00:00 2001 From: "Ilguiz [eel ghEEz] Latypov" Date: Wed, 12 Sep 2018 04:27:20 -0400 Subject: [PATCH 46/46] Allow passing defines such as -- -DFOO=bar --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index b8389bcd7b..780400538c 100644 --- a/lib/build.js +++ b/lib/build.js @@ -19,7 +19,7 @@ function build (gyp, argv, callback) { platformMake = 'gmake' } else if (win && argv.length > 0) { argv = argv.map(function(target) { - return '/t:' + target + return target.substring(0, 1) === '-' ? target : '/t:' + target }) }