From 5f924ce62c9bca9ab9c2e547bfb87b9a391271ed Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 30 May 2017 20:52:45 -0400 Subject: [PATCH 01/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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 3481739265a0cb6005dc82cb49645b02241c05f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Thu, 11 Oct 2018 02:39:17 +0100 Subject: [PATCH 46/54] test: remove unused variable This fixes linting. https://github.com/nodejs/node-gyp/pull/1561 Reviewed-By: Refael Ackermann --- test/process-exec-sync.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/process-exec-sync.js b/test/process-exec-sync.js index 859cbc1f6f..13daf308a3 100644 --- a/test/process-exec-sync.js +++ b/test/process-exec-sync.js @@ -10,7 +10,7 @@ if (!String.prototype.startsWith) { } function processExecSync(file, args, options) { - var child, error, timeout, tmpdir, command, quote + var child, error, timeout, tmpdir, command command = makeCommand(file, args) /* From c9276f3202b23641db3d55b3aa574fc6735f8790 Mon Sep 17 00:00:00 2001 From: cclauss Date: Tue, 14 Nov 2017 09:17:20 +0100 Subject: [PATCH 47/54] gyp: get ready for python 3 https://github.com/nodejs/node-gyp/pull/1335 Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/MSVSSettings.py | 21 ++--- gyp/pylib/gyp/MSVSVersion.py | 2 +- gyp/pylib/gyp/__init__.py | 17 ++-- gyp/pylib/gyp/common.py | 8 +- gyp/pylib/gyp/easy_xml.py | 1 + gyp/pylib/gyp/flock_tool.py | 2 +- gyp/pylib/gyp/generator/analyzer.py | 79 ++++++++++--------- gyp/pylib/gyp/generator/android.py | 7 +- gyp/pylib/gyp/generator/cmake.py | 11 +-- .../gyp/generator/dump_dependency_json.py | 3 +- gyp/pylib/gyp/generator/eclipse.py | 2 +- gyp/pylib/gyp/generator/make.py | 9 ++- gyp/pylib/gyp/generator/msvs.py | 13 +-- gyp/pylib/gyp/generator/ninja.py | 9 ++- gyp/pylib/gyp/generator/xcode.py | 13 +-- gyp/pylib/gyp/input.py | 29 +++---- gyp/pylib/gyp/mac_tool.py | 11 +-- gyp/pylib/gyp/win_tool.py | 11 +-- gyp/pylib/gyp/xcode_emulation.py | 15 ++-- gyp/pylib/gyp/xcode_ninja.py | 2 +- gyp/pylib/gyp/xcodeproj_file.py | 2 +- gyp/tools/graphviz.py | 29 +++---- gyp/tools/pretty_gyp.py | 11 +-- gyp/tools/pretty_sln.py | 47 +++++------ gyp/tools/pretty_vcproj.py | 15 ++-- test/fixtures/test-charmap.py | 7 +- 26 files changed, 198 insertions(+), 178 deletions(-) diff --git a/gyp/pylib/gyp/MSVSSettings.py b/gyp/pylib/gyp/MSVSSettings.py index a08cc154d7..94525ae1cc 100644 --- a/gyp/pylib/gyp/MSVSSettings.py +++ b/gyp/pylib/gyp/MSVSSettings.py @@ -13,6 +13,7 @@ The MSBuild schemas were also considered. They are typically found in the MSBuild install directory, e.g. c:\Program Files (x86)\MSBuild """ +from __future__ import print_function import sys import re @@ -400,7 +401,7 @@ def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr): if unrecognized: # We don't know this setting. Give a warning. - print >> stderr, error_msg + print(error_msg, file=stderr) def FixVCMacroSlashes(s): @@ -461,9 +462,9 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): # Invoke the translation function. try: msvs_tool[msvs_setting](msvs_value, msbuild_settings) - except ValueError, e: - print >> stderr, ('Warning: while converting %s/%s to MSBuild, ' - '%s' % (msvs_tool_name, msvs_setting, e)) + except ValueError as e: + print(('Warning: while converting %s/%s to MSBuild, ' + '%s' % (msvs_tool_name, msvs_setting, e)), file=stderr) else: _ValidateExclusionSetting(msvs_setting, msvs_tool, @@ -472,8 +473,8 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): (msvs_tool_name, msvs_setting)), stderr) else: - print >> stderr, ('Warning: unrecognized tool %s while converting to ' - 'MSBuild.' % msvs_tool_name) + print(('Warning: unrecognized tool %s while converting to ' + 'MSBuild.' % msvs_tool_name), file=stderr) return msbuild_settings @@ -517,9 +518,9 @@ def _ValidateSettings(validators, settings, stderr): if setting in tool_validators: try: tool_validators[setting](value) - except ValueError, e: - print >> stderr, ('Warning: for %s/%s, %s' % - (tool_name, setting, e)) + except ValueError as e: + print(('Warning: for %s/%s, %s' % + (tool_name, setting, e)), file=stderr) else: _ValidateExclusionSetting(setting, tool_validators, @@ -528,7 +529,7 @@ def _ValidateSettings(validators, settings, stderr): stderr) else: - print >> stderr, ('Warning: unrecognized tool %s' % tool_name) + print(('Warning: unrecognized tool %s' % tool_name), file=stderr) # MSVS and MBuild names of the tools. diff --git a/gyp/pylib/gyp/MSVSVersion.py b/gyp/pylib/gyp/MSVSVersion.py index d9bfa684fa..c31ff3e114 100644 --- a/gyp/pylib/gyp/MSVSVersion.py +++ b/gyp/pylib/gyp/MSVSVersion.py @@ -158,7 +158,7 @@ def _RegistryQuery(key, value=None): text = None try: text = _RegistryQueryBase('Sysnative', key, value) - except OSError, e: + except OSError as e: if e.errno == errno.ENOENT: text = _RegistryQueryBase('System32', key, value) else: diff --git a/gyp/pylib/gyp/__init__.py b/gyp/pylib/gyp/__init__.py index 668f38b60d..30fb7093ee 100755 --- a/gyp/pylib/gyp/__init__.py +++ b/gyp/pylib/gyp/__init__.py @@ -4,6 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function import copy import gyp.input import optparse @@ -34,8 +35,8 @@ def DebugOutput(mode, message, *args): pass if args: message %= args - print '%s:%s:%d:%s %s' % (mode.upper(), os.path.basename(ctx[0]), - ctx[1], ctx[2], message) + print('%s:%s:%d:%s %s' % (mode.upper(), os.path.basename(ctx[0]), + ctx[1], ctx[2], message)) def FindBuildFiles(): extension = '.gyp' @@ -226,12 +227,12 @@ def Noop(value): (action == 'store_false' and not value)): flags.append(opt) elif options.use_environment and env_name: - print >>sys.stderr, ('Warning: environment regeneration unimplemented ' + print(('Warning: environment regeneration unimplemented ' 'for %s flag %r env_name %r' % (action, opt, - env_name)) + env_name)), file=sys.stderr) else: - print >>sys.stderr, ('Warning: regeneration unimplemented for action %r ' - 'flag %r' % (action, opt)) + print(('Warning: regeneration unimplemented for action %r ' + 'flag %r' % (action, opt)), file=sys.stderr) return flags @@ -475,7 +476,7 @@ def gyp_main(args): if home_dot_gyp != None: default_include = os.path.join(home_dot_gyp, 'include.gypi') if os.path.exists(default_include): - print 'Using overrides found in ' + default_include + print('Using overrides found in ' + default_include) includes.append(default_include) # Command-line --include files come after the default include. @@ -536,7 +537,7 @@ def gyp_main(args): def main(args): try: return gyp_main(args) - except GypError, e: + except GypError as e: sys.stderr.write("gyp: %s\n" % e) return 1 diff --git a/gyp/pylib/gyp/common.py b/gyp/pylib/gyp/common.py index 501118796f..b7bae925f4 100644 --- a/gyp/pylib/gyp/common.py +++ b/gyp/pylib/gyp/common.py @@ -363,7 +363,7 @@ def close(self): same = False try: same = filecmp.cmp(self.tmp_path, filename, False) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: raise @@ -382,9 +382,9 @@ def close(self): # # No way to get the umask without setting a new one? Set a safe one # and then set it back to the old value. - umask = os.umask(077) + umask = os.umask(0o77) os.umask(umask) - os.chmod(self.tmp_path, 0666 & ~umask) + os.chmod(self.tmp_path, 0o666 & ~umask) if sys.platform == 'win32' and os.path.exists(filename): # NOTE: on windows (but not cygwin) rename will not replace an # existing file, so it must be preceded with a remove. Sadly there @@ -464,7 +464,7 @@ def CopyTool(flavor, out_path): ''.join([source[0], '# Generated by gyp. Do not edit.\n'] + source[1:])) # Make file executable. - os.chmod(tool_path, 0755) + os.chmod(tool_path, 0o755) # From Alex Martelli, diff --git a/gyp/pylib/gyp/easy_xml.py b/gyp/pylib/gyp/easy_xml.py index 841f31f925..fd525a712b 100644 --- a/gyp/pylib/gyp/easy_xml.py +++ b/gyp/pylib/gyp/easy_xml.py @@ -5,6 +5,7 @@ import re import os import locale +from functools import reduce def XmlToString(content, encoding='utf-8', pretty=False): diff --git a/gyp/pylib/gyp/flock_tool.py b/gyp/pylib/gyp/flock_tool.py index b38d8660f7..81fb79d136 100755 --- a/gyp/pylib/gyp/flock_tool.py +++ b/gyp/pylib/gyp/flock_tool.py @@ -39,7 +39,7 @@ def ExecFlock(self, lockfile, *cmd_list): # where fcntl.flock(fd, LOCK_EX) always fails # with EBADF, that's why we use this F_SETLK # hack instead. - fd = os.open(lockfile, os.O_WRONLY|os.O_NOCTTY|os.O_CREAT, 0666) + fd = os.open(lockfile, os.O_WRONLY|os.O_NOCTTY|os.O_CREAT, 0o666) if sys.platform.startswith('aix'): # Python on AIX is compiled with LARGEFILE support, which changes the # struct size. diff --git a/gyp/pylib/gyp/generator/analyzer.py b/gyp/pylib/gyp/generator/analyzer.py index 921c1a6b71..ce7f83c932 100644 --- a/gyp/pylib/gyp/generator/analyzer.py +++ b/gyp/pylib/gyp/generator/analyzer.py @@ -61,6 +61,7 @@ directly supplied to gyp. OTOH if both "a.gyp" and "b.gyp" are supplied to gyp then the "all" target includes "b1" and "b2". """ +from __future__ import print_function import gyp.common import gyp.ninja_syntax as ninja_syntax @@ -155,7 +156,7 @@ def _AddSources(sources, base_path, base_path_components, result): continue result.append(base_path + source) if debug: - print 'AddSource', org_source, result[len(result) - 1] + print('AddSource', org_source, result[len(result) - 1]) def _ExtractSourcesFromAction(action, base_path, base_path_components, @@ -185,7 +186,7 @@ def _ExtractSources(target, target_dict, toplevel_dir): base_path += '/' if debug: - print 'ExtractSources', target, base_path + print('ExtractSources', target, base_path) results = [] if 'sources' in target_dict: @@ -278,7 +279,7 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir): the root of the source tree.""" if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files: if debug: - print 'gyp file modified', build_file + print('gyp file modified', build_file) return True # First element of included_files is the file itself. @@ -291,8 +292,8 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir): _ToGypPath(gyp.common.UnrelativePath(include_file, build_file)) if _ToLocalPath(toplevel_dir, rel_include_file) in files: if debug: - print 'included gyp file modified, gyp_file=', build_file, \ - 'included file=', rel_include_file + print('included gyp file modified, gyp_file=', build_file, \ + 'included file=', rel_include_file) return True return False @@ -373,7 +374,7 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, # If a build file (or any of its included files) is modified we assume all # targets in the file are modified. if build_file_in_files[build_file]: - print 'matching target from modified build file', target_name + print('matching target from modified build file', target_name) target.match_status = MATCH_STATUS_MATCHES matching_targets.append(target) else: @@ -381,7 +382,7 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, toplevel_dir) for source in sources: if _ToGypPath(os.path.normpath(source)) in files: - print 'target', target_name, 'matches', source + print('target', target_name, 'matches', source) target.match_status = MATCH_STATUS_MATCHES matching_targets.append(target) break @@ -433,7 +434,7 @@ def _DoesTargetDependOnMatchingTargets(target): for dep in target.deps: if _DoesTargetDependOnMatchingTargets(dep): target.match_status = MATCH_STATUS_MATCHES_BY_DEPENDENCY - print '\t', target.name, 'matches by dep', dep.name + print('\t', target.name, 'matches by dep', dep.name) return True target.match_status = MATCH_STATUS_DOESNT_MATCH return False @@ -445,7 +446,7 @@ def _GetTargetsDependingOnMatchingTargets(possible_targets): supplied as input to analyzer. possible_targets: targets to search from.""" found = [] - print 'Targets that matched by dependency:' + print('Targets that matched by dependency:') for target in possible_targets: if _DoesTargetDependOnMatchingTargets(target): found.append(target) @@ -484,12 +485,12 @@ def _AddCompileTargets(target, roots, add_if_no_ancestor, result): (add_if_no_ancestor or target.requires_build)) or (target.is_static_library and add_if_no_ancestor and not target.is_or_has_linked_ancestor)): - print '\t\tadding to compile targets', target.name, 'executable', \ + print('\t\tadding to compile targets', target.name, 'executable', \ target.is_executable, 'added_to_compile_targets', \ target.added_to_compile_targets, 'add_if_no_ancestor', \ add_if_no_ancestor, 'requires_build', target.requires_build, \ 'is_static_library', target.is_static_library, \ - 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor + 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor) result.add(target) target.added_to_compile_targets = True @@ -500,7 +501,7 @@ def _GetCompileTargets(matching_targets, supplied_targets): supplied_targets: set of targets supplied to analyzer to search from.""" result = set() for target in matching_targets: - print 'finding compile targets for match', target.name + print('finding compile targets for match', target.name) _AddCompileTargets(target, supplied_targets, True, result) return result @@ -508,46 +509,46 @@ def _GetCompileTargets(matching_targets, supplied_targets): def _WriteOutput(params, **values): """Writes the output, either to stdout or a file is specified.""" if 'error' in values: - print 'Error:', values['error'] + print('Error:', values['error']) if 'status' in values: - print values['status'] + print(values['status']) if 'targets' in values: values['targets'].sort() - print 'Supplied targets that depend on changed files:' + print('Supplied targets that depend on changed files:') for target in values['targets']: - print '\t', target + print('\t', target) if 'invalid_targets' in values: values['invalid_targets'].sort() - print 'The following targets were not found:' + print('The following targets were not found:') for target in values['invalid_targets']: - print '\t', target + print('\t', target) if 'build_targets' in values: values['build_targets'].sort() - print 'Targets that require a build:' + print('Targets that require a build:') for target in values['build_targets']: - print '\t', target + print('\t', target) if 'compile_targets' in values: values['compile_targets'].sort() - print 'Targets that need to be built:' + print('Targets that need to be built:') for target in values['compile_targets']: - print '\t', target + print('\t', target) if 'test_targets' in values: values['test_targets'].sort() - print 'Test targets:' + print('Test targets:') for target in values['test_targets']: - print '\t', target + print('\t', target) output_path = params.get('generator_flags', {}).get( 'analyzer_output_path', None) if not output_path: - print json.dumps(values) + print(json.dumps(values)) return try: f = open(output_path, 'w') f.write(json.dumps(values) + '\n') f.close() except IOError as e: - print 'Error writing to output file', output_path, str(e) + print('Error writing to output file', output_path, str(e)) def _WasGypIncludeFileModified(params, files): @@ -556,7 +557,7 @@ def _WasGypIncludeFileModified(params, files): if params['options'].includes: for include in params['options'].includes: if _ToGypPath(os.path.normpath(include)) in files: - print 'Include file modified, assuming all changed', include + print('Include file modified, assuming all changed', include) return True return False @@ -638,13 +639,13 @@ def find_matching_test_target_names(self): set(self._root_targets))] else: test_targets = [x for x in test_targets_no_all] - print 'supplied test_targets' + print('supplied test_targets') for target_name in self._test_target_names: - print '\t', target_name - print 'found test_targets' + print('\t', target_name) + print('found test_targets') for target in test_targets: - print '\t', target.name - print 'searching for matching test targets' + print('\t', target.name) + print('searching for matching test targets') matching_test_targets = _GetTargetsDependingOnMatchingTargets(test_targets) matching_test_targets_contains_all = (test_target_names_contains_all and set(matching_test_targets) & @@ -654,14 +655,14 @@ def find_matching_test_target_names(self): # 'all' is subsequentely added to the matching names below. matching_test_targets = [x for x in (set(matching_test_targets) & set(test_targets_no_all))] - print 'matched test_targets' + print('matched test_targets') for target in matching_test_targets: - print '\t', target.name + print('\t', target.name) matching_target_names = [gyp.common.ParseQualifiedTarget(target.name)[1] for target in matching_test_targets] if matching_test_targets_contains_all: matching_target_names.append('all') - print '\tall' + print('\tall') return matching_target_names def find_matching_compile_target_names(self): @@ -677,10 +678,10 @@ def find_matching_compile_target_names(self): if 'all' in self._supplied_target_names(): supplied_targets = [x for x in (set(supplied_targets) | set(self._root_targets))] - print 'Supplied test_targets & compile_targets' + print('Supplied test_targets & compile_targets') for target in supplied_targets: - print '\t', target.name - print 'Finding compile targets' + print('\t', target.name) + print('Finding compile targets') compile_targets = _GetCompileTargets(self._changed_targets, supplied_targets) return [gyp.common.ParseQualifiedTarget(target.name)[1] @@ -699,7 +700,7 @@ def GenerateOutput(target_list, target_dicts, data, params): toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir)) if debug: - print 'toplevel_dir', toplevel_dir + print('toplevel_dir', toplevel_dir) if _WasGypIncludeFileModified(params, config.files): result_dict = { 'status': all_changed_string, diff --git a/gyp/pylib/gyp/generator/android.py b/gyp/pylib/gyp/generator/android.py index 5b26cc785a..ed507fbd0d 100644 --- a/gyp/pylib/gyp/generator/android.py +++ b/gyp/pylib/gyp/generator/android.py @@ -1,3 +1,4 @@ +from __future__ import print_function # 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. @@ -636,8 +637,8 @@ def ComputeOutputParts(self, spec): elif self.type == 'none': target_ext = '.stamp' elif self.type != 'executable': - print ("ERROR: What output file should be generated?", - "type", self.type, "target", target) + print(("ERROR: What output file should be generated?", + "type", self.type, "target", target)) if self.type != 'static_library' and self.type != 'shared_library': target_prefix = spec.get('product_prefix', target_prefix) @@ -956,7 +957,7 @@ def PerformBuild(data, configurations, params): env = dict(os.environ) env['ONE_SHOT_MAKEFILE'] = makefile arguments = ['make', '-C', os.environ['ANDROID_BUILD_TOP'], 'gyp_all_modules'] - print 'Building: %s' % arguments + print('Building: %s' % arguments) subprocess.check_call(arguments, env=env) diff --git a/gyp/pylib/gyp/generator/cmake.py b/gyp/pylib/gyp/generator/cmake.py index 17f5e6396c..6f901656ce 100644 --- a/gyp/pylib/gyp/generator/cmake.py +++ b/gyp/pylib/gyp/generator/cmake.py @@ -27,6 +27,7 @@ not be able to find the header file directories described in the generated CMakeLists.txt file. """ +from __future__ import print_function import multiprocessing import os @@ -863,8 +864,8 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, default_product_ext = generator_default_variables['SHARED_LIB_SUFFIX'] elif target_type != 'executable': - print ('ERROR: What output file should be generated?', - 'type', target_type, 'target', target_name) + print(('ERROR: What output file should be generated?', + 'type', target_type, 'target', target_name)) product_prefix = spec.get('product_prefix', default_product_prefix) product_name = spec.get('product_name', default_product_name) @@ -1180,11 +1181,11 @@ def PerformBuild(data, configurations, params): output_dir, config_name)) arguments = ['cmake', '-G', 'Ninja'] - print 'Generating [%s]: %s' % (config_name, arguments) + print('Generating [%s]: %s' % (config_name, arguments)) subprocess.check_call(arguments, cwd=build_dir) arguments = ['ninja', '-C', build_dir] - print 'Building [%s]: %s' % (config_name, arguments) + print('Building [%s]: %s' % (config_name, arguments)) subprocess.check_call(arguments) @@ -1212,7 +1213,7 @@ def GenerateOutput(target_list, target_dicts, data, params): arglists.append((target_list, target_dicts, data, params, config_name)) pool.map(CallGenerateOutputForConfig, arglists) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: pool.terminate() raise e else: diff --git a/gyp/pylib/gyp/generator/dump_dependency_json.py b/gyp/pylib/gyp/generator/dump_dependency_json.py index 160eafe2ef..8e4f3168f3 100644 --- a/gyp/pylib/gyp/generator/dump_dependency_json.py +++ b/gyp/pylib/gyp/generator/dump_dependency_json.py @@ -1,3 +1,4 @@ +from __future__ import print_function # 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. @@ -96,4 +97,4 @@ def GenerateOutput(target_list, target_dicts, data, params): f = open(filename, 'w') json.dump(edges, f) f.close() - print 'Wrote json to %s.' % filename + print('Wrote json to %s.' % filename) diff --git a/gyp/pylib/gyp/generator/eclipse.py b/gyp/pylib/gyp/generator/eclipse.py index 3544347b3b..b7c6aa951f 100644 --- a/gyp/pylib/gyp/generator/eclipse.py +++ b/gyp/pylib/gyp/generator/eclipse.py @@ -141,7 +141,7 @@ def GetAllIncludeDirectories(target_list, target_dicts, compiler_includes_list.append(include_dir) # Find standard gyp include dirs. - if config.has_key('include_dirs'): + if 'include_dirs' in config: include_dirs = config['include_dirs'] for shared_intermediate_dir in shared_intermediate_dirs: for include_dir in include_dirs: diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index fe801b77ce..8f7082ab45 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -1,3 +1,4 @@ +from __future__ import print_function # Copyright (c) 2013 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. @@ -1381,8 +1382,8 @@ def ComputeOutputBasename(self, spec): elif self.type == 'none': target = '%s.stamp' % target elif self.type != 'executable': - print ("ERROR: What output file should be generated?", - "type", self.type, "target", target) + print(("ERROR: What output file should be generated?", + "type", self.type, "target", target)) target_prefix = spec.get('product_prefix', target_prefix) target = spec.get('product_name', target) @@ -1638,7 +1639,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all, postbuilds=postbuilds) else: - print "WARNING: no output for", self.type, target + print("WARNING: no output for", self.type, target) # Add an alias for each target (if there are any outputs). # Installable target aliases are created below. @@ -1992,7 +1993,7 @@ def PerformBuild(data, configurations, params): if options.toplevel_dir and options.toplevel_dir != '.': arguments += '-C', options.toplevel_dir arguments.append('BUILDTYPE=' + config) - print 'Building [%s]: %s' % (config, arguments) + print('Building [%s]: %s' % (config, arguments)) subprocess.check_call(arguments) diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py index 3901ba9416..344cd1d18c 100644 --- a/gyp/pylib/gyp/generator/msvs.py +++ b/gyp/pylib/gyp/generator/msvs.py @@ -1,3 +1,4 @@ +from __future__ import print_function # 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. @@ -755,8 +756,8 @@ def _Replace(match): # the VCProj but cause the same problem on the final command-line. Moving # the item to the end of the list does works, but that's only possible if # there's only one such item. Let's just warn the user. - print >> sys.stderr, ('Warning: MSVS may misinterpret the odd number of ' + - 'quotes in ' + s) + print(('Warning: MSVS may misinterpret the odd number of ' + + 'quotes in ' + s), file=sys.stderr) return s @@ -1949,7 +1950,7 @@ def PerformBuild(data, configurations, params): for config in configurations: arguments = [devenv, sln_path, '/Build', config] - print 'Building [%s]: %s' % (config, arguments) + print('Building [%s]: %s' % (config, arguments)) rtn = subprocess.check_call(arguments) @@ -2031,7 +2032,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if generator_flags.get('msvs_error_on_missing_sources', False): raise GypError(error_message) else: - print >> sys.stdout, "Warning: " + error_message + print("Warning: " + error_message, file=sys.stdout) def _GenerateMSBuildFiltersFile(filters_path, source_files, @@ -2729,7 +2730,7 @@ def _GetMSBuildPropertySheets(configurations): props_specified = False for name, settings in sorted(configurations.iteritems()): configuration = _GetConfigurationCondition(name, settings) - if settings.has_key('msbuild_props'): + if 'msbuild_props' in settings: additional_props[configuration] = _FixPaths(settings['msbuild_props']) props_specified = True else: @@ -2782,7 +2783,7 @@ def _ConvertMSVSBuildAttributes(spec, config, build_file): elif a == 'ConfigurationType': msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a]) else: - print 'Warning: Do not know how to convert MSVS attribute ' + a + print('Warning: Do not know how to convert MSVS attribute ' + a) return msbuild_attributes diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index a00573ebf2..1fc00e1f98 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -1,3 +1,4 @@ +from __future__ import print_function # Copyright (c) 2013 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. @@ -472,8 +473,8 @@ def WriteSpec(self, spec, config_name, generator_flags): if self.flavor != 'mac' or len(self.archs) == 1: link_deps += [self.GypPathToNinja(o) for o in obj_outputs] else: - print "Warning: Actions/rules writing object files don't work with " \ - "multiarch targets, dropping. (target %s)" % spec['target_name'] + print("Warning: Actions/rules writing object files don't work with " \ + "multiarch targets, dropping. (target %s)" % spec['target_name']) elif self.flavor == 'mac' and len(self.archs) > 1: link_deps = collections.defaultdict(list) @@ -2376,7 +2377,7 @@ def PerformBuild(data, configurations, params): for config in configurations: builddir = os.path.join(options.toplevel_dir, 'out', config) arguments = ['ninja', '-C', builddir] - print 'Building [%s]: %s' % (config, arguments) + print('Building [%s]: %s' % (config, arguments)) subprocess.check_call(arguments) @@ -2413,7 +2414,7 @@ def GenerateOutput(target_list, target_dicts, data, params): arglists.append( (target_list, target_dicts, data, params, config_name)) pool.map(CallGenerateOutputForConfig, arglists) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: pool.terminate() raise e else: diff --git a/gyp/pylib/gyp/generator/xcode.py b/gyp/pylib/gyp/generator/xcode.py index 0e3fb9301e..63f80d7657 100644 --- a/gyp/pylib/gyp/generator/xcode.py +++ b/gyp/pylib/gyp/generator/xcode.py @@ -1,3 +1,4 @@ +from __future__ import print_function # 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. @@ -128,7 +129,7 @@ def __init__(self, gyp_path, path, build_file_dict): try: os.makedirs(self.path) self.created_dir = True - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise @@ -453,7 +454,7 @@ def Write(self): same = False try: same = filecmp.cmp(pbxproj_path, new_pbxproj_path, False) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: raise @@ -472,10 +473,10 @@ def Write(self): # # No way to get the umask without setting a new one? Set a safe one # and then set it back to the old value. - umask = os.umask(077) + umask = os.umask(0o77) os.umask(umask) - os.chmod(new_pbxproj_path, 0666 & ~umask) + os.chmod(new_pbxproj_path, 0o666 & ~umask) os.rename(new_pbxproj_path, pbxproj_path) except Exception: @@ -576,7 +577,7 @@ def PerformBuild(data, configurations, params): for config in configurations: arguments = ['xcodebuild', '-project', xcodeproj_path] arguments += ['-configuration', config] - print "Building [%s]: %s" % (config, arguments) + print("Building [%s]: %s" % (config, arguments)) subprocess.check_call(arguments) @@ -736,7 +737,7 @@ def GenerateOutput(target_list, target_dicts, data, params): xctarget_type = gyp.xcodeproj_file.PBXNativeTarget try: target_properties['productType'] = _types[type_bundle_key] - except KeyError, e: + except KeyError as e: gyp.common.ExceptionAppend(e, "-- unknown product type while " "writing target %s" % target_name) raise diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index 10f6e0dba1..f55619f3b0 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -1,3 +1,4 @@ +from __future__ import print_function # 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. @@ -249,10 +250,10 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, else: build_file_data = eval(build_file_contents, {'__builtins__': None}, None) - except SyntaxError, e: + except SyntaxError as e: e.filename = build_file_path raise - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend(e, 'while reading ' + build_file_path) raise @@ -272,7 +273,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, else: LoadBuildFileIncludesIntoDict(build_file_data, build_file_path, data, aux_data, None, check) - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend(e, 'while reading includes of ' + build_file_path) raise @@ -474,7 +475,7 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes, try: LoadTargetBuildFile(dependency, data, aux_data, variables, includes, depth, check, load_dependencies) - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend( e, 'while loading dependencies of %s' % build_file_path) raise @@ -517,12 +518,12 @@ def CallLoadTargetBuildFile(global_flags, return (build_file_path, build_file_data, dependencies) - except GypError, e: + except GypError as e: sys.stderr.write("gyp: %s\n" % e) return None - except Exception, e: - print >>sys.stderr, 'Exception:', e - print >>sys.stderr, traceback.format_exc() + except Exception as e: + print('Exception:', e, file=sys.stderr) + print(traceback.format_exc(), file=sys.stderr) return None @@ -612,7 +613,7 @@ def LoadTargetBuildFilesParallel(build_files, data, variables, includes, depth, args = (global_flags, dependency, variables, includes, depth, check, generator_input_info), callback = parallel_state.LoadTargetBuildFileCallback) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: parallel_state.pool.terminate() raise e @@ -912,7 +913,7 @@ def ExpandVariables(input, phase, variables, build_file): stderr=subprocess.PIPE, stdin=subprocess.PIPE, cwd=build_file_dir) - except Exception, e: + except Exception as e: raise GypError("%s while executing command '%s' in %s" % (e, contents, build_file)) @@ -1097,13 +1098,13 @@ def EvalSingleCondition( if eval(ast_code, {'__builtins__': None}, variables): return true_dict return false_dict - except SyntaxError, e: + except SyntaxError as e: syntax_error = SyntaxError('%s while evaluating condition \'%s\' in %s ' 'at character %d.' % (str(e.args[0]), e.text, build_file, e.offset), e.filename, e.lineno, e.offset, e.text) raise syntax_error - except NameError, e: + except NameError as e: gyp.common.ExceptionAppend(e, 'while evaluating condition \'%s\' in %s' % (cond_expr_expanded, build_file)) raise GypError(e) @@ -1858,7 +1859,7 @@ def VerifyNoGYPFileCircularDependencies(targets): for dependency in target_dependencies: try: dependency_build_file = gyp.common.BuildFile(dependency) - except GypError, e: + except GypError as e: gyp.common.ExceptionAppend( e, 'while computing dependencies of .gyp file %s' % build_file) raise @@ -2781,7 +2782,7 @@ def Load(build_files, variables, includes, depth, generator_input_info, check, try: LoadTargetBuildFile(build_file, data, aux_data, variables, includes, depth, check, True) - except Exception, e: + except Exception as e: gyp.common.ExceptionAppend(e, 'while trying to load %s' % build_file) raise diff --git a/gyp/pylib/gyp/mac_tool.py b/gyp/pylib/gyp/mac_tool.py index eeeaceb0c7..36203801c8 100755 --- a/gyp/pylib/gyp/mac_tool.py +++ b/gyp/pylib/gyp/mac_tool.py @@ -7,6 +7,7 @@ These functions are executed via gyp-mac-tool when using the Makefile generator. """ +from __future__ import print_function import fcntl import fnmatch @@ -243,7 +244,7 @@ def ExecFilterLibtool(self, *cmd_list): _, err = libtoolout.communicate() for line in err.splitlines(): if not libtool_re.match(line) and not libtool_re5.match(line): - print >>sys.stderr, line + print(line, file=sys.stderr) # Unconditionally touch the output .a file on the command line if present # and the command succeeded. A bit hacky. if not libtoolout.returncode: @@ -440,8 +441,8 @@ def _FindProvisioningProfile(self, profile, bundle_identifier): profiles_dir = os.path.join( os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles') if not os.path.isdir(profiles_dir): - print >>sys.stderr, ( - 'cannot find mobile provisioning for %s' % bundle_identifier) + print(( + 'cannot find mobile provisioning for %s' % bundle_identifier), file=sys.stderr) sys.exit(1) provisioning_profiles = None if profile: @@ -462,8 +463,8 @@ def _FindProvisioningProfile(self, profile, bundle_identifier): valid_provisioning_profiles[app_id_pattern] = ( profile_path, profile_data, team_identifier) if not valid_provisioning_profiles: - print >>sys.stderr, ( - 'cannot find mobile provisioning for %s' % bundle_identifier) + print(( + 'cannot find mobile provisioning for %s' % bundle_identifier), file=sys.stderr) sys.exit(1) # If the user has multiple provisioning profiles installed that can be # used for ${bundle_identifier}, pick the most specific one (ie. the diff --git a/gyp/pylib/gyp/win_tool.py b/gyp/pylib/gyp/win_tool.py index bb6f1ea436..85a7926095 100755 --- a/gyp/pylib/gyp/win_tool.py +++ b/gyp/pylib/gyp/win_tool.py @@ -8,6 +8,7 @@ These functions are executed via gyp-win-tool when using the ninja generator. """ +from __future__ import print_function import os import re @@ -126,7 +127,7 @@ def ExecLinkWrapper(self, arch, use_separate_mspdbsrv, *args): if (not line.startswith(' Creating library ') and not line.startswith('Generating code') and not line.startswith('Finished generating code')): - print line + print(line) return link.returncode def ExecLinkWithManifests(self, arch, embed_manifest, out, ldcmd, resname, @@ -215,7 +216,7 @@ def ExecManifestWrapper(self, arch, *args): out, _ = popen.communicate() for line in out.splitlines(): if line and 'manifest authoring warning 81010002' not in line: - print line + print(line) return popen.returncode def ExecManifestToRc(self, arch, *args): @@ -255,7 +256,7 @@ def ExecMidlWrapper(self, arch, outdir, tlb, h, dlldata, iid, proxy, idl, for x in lines if x.startswith(prefixes)) for line in lines: if not line.startswith(prefixes) and line not in processing: - print line + print(line) return popen.returncode def ExecAsmWrapper(self, arch, *args): @@ -269,7 +270,7 @@ def ExecAsmWrapper(self, arch, *args): not line.startswith('Microsoft (R) Macro Assembler') and not line.startswith(' Assembling: ') and line): - print line + print(line) return popen.returncode def ExecRcWrapper(self, arch, *args): @@ -283,7 +284,7 @@ def ExecRcWrapper(self, arch, *args): if (not line.startswith('Microsoft (R) Windows (R) Resource Compiler') and not line.startswith('Copyright (C) Microsoft Corporation') and line): - print line + print(line) return popen.returncode def ExecActionWrapper(self, arch, rspfile, *dir): diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index 69f7d97cfa..cbd589b43b 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -6,6 +6,7 @@ This module contains classes that help to emulate xcodebuild behavior on top of other build systems, such as make and ninja. """ +from __future__ import print_function import copy import gyp.common @@ -73,7 +74,7 @@ def _ExpandArchs(self, archs, sdkroot): if arch not in expanded_archs: expanded_archs.append(arch) except KeyError as e: - print 'Warning: Ignoring unsupported variable "%s".' % variable + print('Warning: Ignoring unsupported variable "%s".' % variable) elif arch not in expanded_archs: expanded_archs.append(arch) return expanded_archs @@ -194,8 +195,8 @@ def _ConvertConditionalKeys(self, configname): new_key = key.split("[")[0] settings[new_key] = settings[key] else: - print 'Warning: Conditional keys not implemented, ignoring:', \ - ' '.join(conditional_keys) + print('Warning: Conditional keys not implemented, ignoring:', \ + ' '.join(conditional_keys)) del settings[key] def _Settings(self): @@ -213,7 +214,7 @@ def _Appendf(self, lst, test_key, format_str, default=None): def _WarnUnimplemented(self, test_key): if test_key in self._Settings(): - print 'Warning: Ignoring not yet implemented key "%s".' % test_key + print('Warning: Ignoring not yet implemented key "%s".' % test_key) def IsBinaryOutputFormat(self, configname): default = "binary" if self.isIOS else "xml" @@ -997,8 +998,8 @@ def _GetIOSPostbuilds(self, configname, output_binary): unimpl = ['OTHER_CODE_SIGN_FLAGS'] unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) if unimpl: - print 'Warning: Some codesign keys not implemented, ignoring: %s' % ( - ', '.join(sorted(unimpl))) + print('Warning: Some codesign keys not implemented, ignoring: %s' % ( + ', '.join(sorted(unimpl)))) return ['%s code-sign-bundle "%s" "%s" "%s" "%s"' % ( os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, @@ -1597,7 +1598,7 @@ def GetEdges(node): order = gyp.common.TopologicallySorted(env.keys(), GetEdges) order.reverse() return order - except gyp.common.CycleError, e: + except gyp.common.CycleError as e: raise GypError( 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) diff --git a/gyp/pylib/gyp/xcode_ninja.py b/gyp/pylib/gyp/xcode_ninja.py index 3820d6bf04..d781471005 100644 --- a/gyp/pylib/gyp/xcode_ninja.py +++ b/gyp/pylib/gyp/xcode_ninja.py @@ -28,7 +28,7 @@ def _WriteWorkspace(main_gyp, sources_gyp, params): workspace_path = os.path.join(options.generator_output, workspace_path) try: os.makedirs(workspace_path) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise output_string = '\n' + \ diff --git a/gyp/pylib/gyp/xcodeproj_file.py b/gyp/pylib/gyp/xcodeproj_file.py index d08b7f7770..712eefe3f8 100644 --- a/gyp/pylib/gyp/xcodeproj_file.py +++ b/gyp/pylib/gyp/xcodeproj_file.py @@ -691,7 +691,7 @@ def _XCKVPrint(self, file, tabs, key, value): printable_value[0] == '"' and printable_value[-1] == '"': printable_value = printable_value[1:-1] printable += printable_key + ' = ' + printable_value + ';' + after_kv - except TypeError, e: + except TypeError as e: gyp.common.ExceptionAppend(e, 'while printing key "%s"' % key) raise diff --git a/gyp/tools/graphviz.py b/gyp/tools/graphviz.py index 326ae221cf..dcf7c765e5 100755 --- a/gyp/tools/graphviz.py +++ b/gyp/tools/graphviz.py @@ -7,6 +7,7 @@ """Using the JSON dumped by the dump-dependency-json generator, generate input suitable for graphviz to render a dependency graph of targets.""" +from __future__ import print_function import collections import json @@ -50,9 +51,9 @@ def WriteGraph(edges): build_file, target_name, toolset = ParseTarget(src) files[build_file].append(src) - print 'digraph D {' - print ' fontsize=8' # Used by subgraphs. - print ' node [fontsize=8]' + print('digraph D {') + print(' fontsize=8') # Used by subgraphs. + print(' node [fontsize=8]') # Output nodes by file. We must first write out each node within # its file grouping before writing out any edges that may refer @@ -63,31 +64,31 @@ def WriteGraph(edges): # the display by making it a box without an internal node. target = targets[0] build_file, target_name, toolset = ParseTarget(target) - print ' "%s" [shape=box, label="%s\\n%s"]' % (target, filename, - target_name) + print(' "%s" [shape=box, label="%s\\n%s"]' % (target, filename, + target_name)) else: # Group multiple nodes together in a subgraph. - print ' subgraph "cluster_%s" {' % filename - print ' label = "%s"' % filename + print(' subgraph "cluster_%s" {' % filename) + print(' label = "%s"' % filename) for target in targets: build_file, target_name, toolset = ParseTarget(target) - print ' "%s" [label="%s"]' % (target, target_name) - print ' }' + print(' "%s" [label="%s"]' % (target, target_name)) + print(' }') # Now that we've placed all the nodes within subgraphs, output all # the edges between nodes. for src, dsts in edges.items(): for dst in dsts: - print ' "%s" -> "%s"' % (src, dst) + print(' "%s" -> "%s"' % (src, dst)) - print '}' + print('}') def main(): if len(sys.argv) < 2: - print >>sys.stderr, __doc__ - print >>sys.stderr - print >>sys.stderr, 'usage: %s target1 target2...' % (sys.argv[0]) + print(__doc__, file=sys.stderr) + print(file=sys.stderr) + print('usage: %s target1 target2...' % (sys.argv[0]), file=sys.stderr) return 1 edges = LoadEdges('dump.json', sys.argv[1:]) diff --git a/gyp/tools/pretty_gyp.py b/gyp/tools/pretty_gyp.py index c51d35872c..8111224595 100755 --- a/gyp/tools/pretty_gyp.py +++ b/gyp/tools/pretty_gyp.py @@ -5,6 +5,7 @@ # found in the LICENSE file. """Pretty-prints the contents of a GYP file.""" +from __future__ import print_function import sys import re @@ -119,22 +120,22 @@ def prettyprint_input(lines): last_line = "" for line in lines: if COMMENT_RE.match(line): - print line + print(line) else: line = line.strip('\r\n\t ') # Otherwise doesn't strip \r on Unix. if len(line) > 0: (brace_diff, after) = count_braces(line) if brace_diff != 0: if after: - print " " * (basic_offset * indent) + line + print(" " * (basic_offset * indent) + line) indent += brace_diff else: indent += brace_diff - print " " * (basic_offset * indent) + line + print(" " * (basic_offset * indent) + line) else: - print " " * (basic_offset * indent) + line + print(" " * (basic_offset * indent) + line) else: - print "" + print("") last_line = line diff --git a/gyp/tools/pretty_sln.py b/gyp/tools/pretty_sln.py index ca8cf4ad3f..64a9ec2bf6 100755 --- a/gyp/tools/pretty_sln.py +++ b/gyp/tools/pretty_sln.py @@ -11,6 +11,7 @@ Then it outputs a possible build order. """ +from __future__ import print_function __author__ = 'nsylvain (Nicolas Sylvain)' @@ -26,7 +27,7 @@ def BuildProject(project, built, projects, deps): for dep in deps[project]: if dep not in built: BuildProject(dep, built, projects, deps) - print project + print(project) built.append(project) def ParseSolution(solution_file): @@ -100,44 +101,44 @@ def ParseSolution(solution_file): return (projects, dependencies) def PrintDependencies(projects, deps): - print "---------------------------------------" - print "Dependencies for all projects" - print "---------------------------------------" - print "-- --" + print("---------------------------------------") + print("Dependencies for all projects") + print("---------------------------------------") + print("-- --") for (project, dep_list) in sorted(deps.items()): - print "Project : %s" % project - print "Path : %s" % projects[project][0] + print("Project : %s" % project) + print("Path : %s" % projects[project][0]) if dep_list: for dep in dep_list: - print " - %s" % dep - print "" + print(" - %s" % dep) + print("") - print "-- --" + print("-- --") def PrintBuildOrder(projects, deps): - print "---------------------------------------" - print "Build order " - print "---------------------------------------" - print "-- --" + print("---------------------------------------") + print("Build order ") + print("---------------------------------------") + print("-- --") built = [] for (project, _) in sorted(deps.items()): if project not in built: BuildProject(project, built, projects, deps) - print "-- --" + print("-- --") def PrintVCProj(projects): for project in projects: - print "-------------------------------------" - print "-------------------------------------" - print project - print project - print project - print "-------------------------------------" - print "-------------------------------------" + print("-------------------------------------") + print("-------------------------------------") + print(project) + print(project) + print(project) + print("-------------------------------------") + print("-------------------------------------") project_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[1]), projects[project][2])) @@ -153,7 +154,7 @@ def PrintVCProj(projects): def main(): # check if we have exactly 1 parameter. if len(sys.argv) < 2: - print 'Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0] + print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0]) return 1 (projects, deps) = ParseSolution(sys.argv[1]) diff --git a/gyp/tools/pretty_vcproj.py b/gyp/tools/pretty_vcproj.py index 6099bd7cc4..c96ba061ef 100755 --- a/gyp/tools/pretty_vcproj.py +++ b/gyp/tools/pretty_vcproj.py @@ -11,6 +11,7 @@ It outputs the resulting xml to stdout. """ +from __future__ import print_function __author__ = 'nsylvain (Nicolas Sylvain)' @@ -61,7 +62,7 @@ def get_string(node): def PrettyPrintNode(node, indent=0): if node.nodeType == Node.TEXT_NODE: if node.data.strip(): - print '%s%s' % (' '*indent, node.data.strip()) + print('%s%s' % (' '*indent, node.data.strip())) return if node.childNodes: @@ -73,23 +74,23 @@ def PrettyPrintNode(node, indent=0): # Print the main tag if attr_count == 0: - print '%s<%s>' % (' '*indent, node.nodeName) + print('%s<%s>' % (' '*indent, node.nodeName)) else: - print '%s<%s' % (' '*indent, node.nodeName) + print('%s<%s' % (' '*indent, node.nodeName)) all_attributes = [] for (name, value) in node.attributes.items(): all_attributes.append((name, value)) all_attributes.sort(CmpTuple()) for (name, value) in all_attributes: - print '%s %s="%s"' % (' '*indent, name, value) - print '%s>' % (' '*indent) + print('%s %s="%s"' % (' '*indent, name, value)) + print('%s>' % (' '*indent)) if node.nodeValue: - print '%s %s' % (' '*indent, node.nodeValue) + print('%s %s' % (' '*indent, node.nodeValue)) for sub_node in node.childNodes: PrettyPrintNode(sub_node, indent=indent+2) - print '%s' % (' '*indent, node.nodeName) + print('%s' % (' '*indent, node.nodeName)) def FlattenFilter(node): diff --git a/test/fixtures/test-charmap.py b/test/fixtures/test-charmap.py index d9fa6fb25e..b752f0bbbf 100644 --- a/test/fixtures/test-charmap.py +++ b/test/fixtures/test-charmap.py @@ -1,3 +1,4 @@ +from __future__ import print_function import sys import locale @@ -14,9 +15,9 @@ def main(): 'cp1252': u'Lat\u012Bna', 'cp932': u'\u306b\u307b\u3093\u3054' } - if textmap.has_key(encoding): - print textmap[encoding] + if encoding in textmap: + print(textmap[encoding]) return True if __name__ == '__main__': - print main() + print(main()) From 73b5b63975c74cb536829bef62456707590949ef Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Sun, 19 Mar 2017 13:26:41 -0700 Subject: [PATCH 48/54] gyp: use print as a function, as specified in PEP 3105. https://github.com/nodejs/node-gyp/pull/1150 Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/MSVSSettings.py | 15 ++++++++------- gyp/pylib/gyp/__init__.py | 9 +++++---- gyp/pylib/gyp/generator/analyzer.py | 15 ++++++++------- gyp/pylib/gyp/generator/android.py | 15 ++++++++------- gyp/pylib/gyp/generator/cmake.py | 9 +++++---- gyp/pylib/gyp/generator/make.py | 12 ++++++------ gyp/pylib/gyp/generator/msvs.py | 13 +++++++------ gyp/pylib/gyp/input.py | 7 ++++--- gyp/pylib/gyp/mac_tool.py | 7 +++---- gyp/pylib/gyp/win_tool.py | 1 + gyp/pylib/gyp/xcode_emulation.py | 1 + gyp/tools/graphviz.py | 1 + gyp/tools/pretty_gyp.py | 1 + gyp/tools/pretty_sln.py | 3 ++- gyp/tools/pretty_vcproj.py | 8 ++++---- 15 files changed, 64 insertions(+), 53 deletions(-) diff --git a/gyp/pylib/gyp/MSVSSettings.py b/gyp/pylib/gyp/MSVSSettings.py index 94525ae1cc..455862c636 100644 --- a/gyp/pylib/gyp/MSVSSettings.py +++ b/gyp/pylib/gyp/MSVSSettings.py @@ -13,6 +13,7 @@ The MSBuild schemas were also considered. They are typically found in the MSBuild install directory, e.g. c:\Program Files (x86)\MSBuild """ + from __future__ import print_function import sys @@ -463,8 +464,8 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): try: msvs_tool[msvs_setting](msvs_value, msbuild_settings) except ValueError as e: - print(('Warning: while converting %s/%s to MSBuild, ' - '%s' % (msvs_tool_name, msvs_setting, e)), file=stderr) + print('Warning: while converting %s/%s to MSBuild, ' + '%s' % (msvs_tool_name, msvs_setting, e), file=stderr) else: _ValidateExclusionSetting(msvs_setting, msvs_tool, @@ -473,8 +474,8 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): (msvs_tool_name, msvs_setting)), stderr) else: - print(('Warning: unrecognized tool %s while converting to ' - 'MSBuild.' % msvs_tool_name), file=stderr) + print('Warning: unrecognized tool %s while converting to ' + 'MSBuild.' % msvs_tool_name, file=stderr) return msbuild_settings @@ -519,8 +520,8 @@ def _ValidateSettings(validators, settings, stderr): try: tool_validators[setting](value) except ValueError as e: - print(('Warning: for %s/%s, %s' % - (tool_name, setting, e)), file=stderr) + print('Warning: for %s/%s, %s' % + (tool_name, setting, e), file=stderr) else: _ValidateExclusionSetting(setting, tool_validators, @@ -529,7 +530,7 @@ def _ValidateSettings(validators, settings, stderr): stderr) else: - print(('Warning: unrecognized tool %s' % tool_name), file=stderr) + print('Warning: unrecognized tool %s' % (tool_name), file=stderr) # MSVS and MBuild names of the tools. diff --git a/gyp/pylib/gyp/__init__.py b/gyp/pylib/gyp/__init__.py index 30fb7093ee..bd51cde888 100755 --- a/gyp/pylib/gyp/__init__.py +++ b/gyp/pylib/gyp/__init__.py @@ -5,6 +5,7 @@ # found in the LICENSE file. from __future__ import print_function + import copy import gyp.input import optparse @@ -227,12 +228,12 @@ def Noop(value): (action == 'store_false' and not value)): flags.append(opt) elif options.use_environment and env_name: - print(('Warning: environment regeneration unimplemented ' + print('Warning: environment regeneration unimplemented ' 'for %s flag %r env_name %r' % (action, opt, - env_name)), file=sys.stderr) + env_name), file=sys.stderr) else: - print(('Warning: regeneration unimplemented for action %r ' - 'flag %r' % (action, opt)), file=sys.stderr) + print('Warning: regeneration unimplemented for action %r ' + 'flag %r' % (action, opt), file=sys.stderr) return flags diff --git a/gyp/pylib/gyp/generator/analyzer.py b/gyp/pylib/gyp/generator/analyzer.py index ce7f83c932..dc17c96524 100644 --- a/gyp/pylib/gyp/generator/analyzer.py +++ b/gyp/pylib/gyp/generator/analyzer.py @@ -61,6 +61,7 @@ directly supplied to gyp. OTOH if both "a.gyp" and "b.gyp" are supplied to gyp then the "all" target includes "b1" and "b2". """ + from __future__ import print_function import gyp.common @@ -292,8 +293,8 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir): _ToGypPath(gyp.common.UnrelativePath(include_file, build_file)) if _ToLocalPath(toplevel_dir, rel_include_file) in files: if debug: - print('included gyp file modified, gyp_file=', build_file, \ - 'included file=', rel_include_file) + print('included gyp file modified, gyp_file=', build_file, + 'included file=', rel_include_file) return True return False @@ -485,11 +486,11 @@ def _AddCompileTargets(target, roots, add_if_no_ancestor, result): (add_if_no_ancestor or target.requires_build)) or (target.is_static_library and add_if_no_ancestor and not target.is_or_has_linked_ancestor)): - print('\t\tadding to compile targets', target.name, 'executable', \ - target.is_executable, 'added_to_compile_targets', \ - target.added_to_compile_targets, 'add_if_no_ancestor', \ - add_if_no_ancestor, 'requires_build', target.requires_build, \ - 'is_static_library', target.is_static_library, \ + print('\t\tadding to compile targets', target.name, 'executable', + target.is_executable, 'added_to_compile_targets', + target.added_to_compile_targets, 'add_if_no_ancestor', + add_if_no_ancestor, 'requires_build', target.requires_build, + 'is_static_library', target.is_static_library, 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor) result.add(target) target.added_to_compile_targets = True diff --git a/gyp/pylib/gyp/generator/android.py b/gyp/pylib/gyp/generator/android.py index ed507fbd0d..66139892cc 100644 --- a/gyp/pylib/gyp/generator/android.py +++ b/gyp/pylib/gyp/generator/android.py @@ -1,4 +1,3 @@ -from __future__ import print_function # 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. @@ -15,6 +14,8 @@ # variables set potentially clash with other Android build system variables. # Try to avoid setting global variables where possible. +from __future__ import print_function + import gyp import gyp.common import gyp.generator.make as make # Reuse global functions from make backend. @@ -251,7 +252,7 @@ def WriteActions(self, actions, extra_sources, extra_outputs): dirs = set() for out in outputs: if not out.startswith('$'): - print ('WARNING: Action for target "%s" writes output to local path ' + print('WARNING: Action for target "%s" writes output to local path ' '"%s".' % (self.target, out)) dir = os.path.split(out)[0] if dir: @@ -356,7 +357,7 @@ def WriteRules(self, rules, extra_sources, extra_outputs): dirs = set() for out in outputs: if not out.startswith('$'): - print ('WARNING: Rule for target %s writes output to local path %s' + print('WARNING: Rule for target %s writes output to local path %s' % (self.target, out)) dir = os.path.dirname(out) if dir: @@ -430,7 +431,7 @@ def WriteCopies(self, copies, extra_outputs): # $(gyp_shared_intermediate_dir). Note that we can't use an assertion # because some of the gyp tests depend on this. if not copy['destination'].startswith('$'): - print ('WARNING: Copy rule for target %s writes output to ' + print('WARNING: Copy rule for target %s writes output to ' 'local path %s' % (self.target, copy['destination'])) # LocalPathify() calls normpath, stripping trailing slashes. @@ -637,8 +638,8 @@ def ComputeOutputParts(self, spec): elif self.type == 'none': target_ext = '.stamp' elif self.type != 'executable': - print(("ERROR: What output file should be generated?", - "type", self.type, "target", target)) + print("ERROR: What output file should be generated?", + "type", self.type, "target", target) if self.type != 'static_library' and self.type != 'shared_library': target_prefix = spec.get('product_prefix', target_prefix) @@ -1066,7 +1067,7 @@ def CalculateMakefilePath(build_file, base_name): write_alias_target=write_alias_targets, sdk_version=sdk_version) if android_module in android_modules: - print ('ERROR: Android module names must be unique. The following ' + print('ERROR: Android module names must be unique. The following ' 'targets both generate Android module name %s.\n %s\n %s' % (android_module, android_modules[android_module], qualified_target)) diff --git a/gyp/pylib/gyp/generator/cmake.py b/gyp/pylib/gyp/generator/cmake.py index 6f901656ce..7aabddb633 100644 --- a/gyp/pylib/gyp/generator/cmake.py +++ b/gyp/pylib/gyp/generator/cmake.py @@ -27,6 +27,7 @@ not be able to find the header file directories described in the generated CMakeLists.txt file. """ + from __future__ import print_function import multiprocessing @@ -640,8 +641,8 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type) if cmake_target_type is None: - print ('Target %s has unknown target type %s, skipping.' % - ( target_name, target_type ) ) + print('Target %s has unknown target type %s, skipping.' % + ( target_name, target_type )) return SetVariable(output, 'TARGET', target_name) @@ -864,8 +865,8 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, default_product_ext = generator_default_variables['SHARED_LIB_SUFFIX'] elif target_type != 'executable': - print(('ERROR: What output file should be generated?', - 'type', target_type, 'target', target_name)) + print('ERROR: What output file should be generated?', + 'type', target_type, 'target', target_name) product_prefix = spec.get('product_prefix', default_product_prefix) product_name = spec.get('product_name', default_product_name) diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 8f7082ab45..96212be1fc 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -1,4 +1,3 @@ -from __future__ import print_function # Copyright (c) 2013 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. @@ -22,6 +21,8 @@ # toplevel Makefile. It may make sense to generate some .mk files on # the side to keep the files readable. +from __future__ import print_function + import os import re import sys @@ -678,9 +679,8 @@ def _ValidateSourcesForOSX(spec, all_sources): error += ' %s: %s\n' % (basename, ' '.join(files)) if error: - print('static library %s has several files with the same basename:\n' % - spec['target_name'] + error + 'libtool on OS X will generate' + - ' warnings for them.') + print(('static library %s has several files with the same basename:\n' % spec['target_name']) + + error + 'libtool on OS X will generate' + ' warnings for them.') raise GypError('Duplicate basenames in sources section, see list above') @@ -1382,8 +1382,8 @@ def ComputeOutputBasename(self, spec): elif self.type == 'none': target = '%s.stamp' % target elif self.type != 'executable': - print(("ERROR: What output file should be generated?", - "type", self.type, "target", target)) + print("ERROR: What output file should be generated?", + "type", self.type, "target", target) target_prefix = spec.get('product_prefix', target_prefix) target = spec.get('product_name', target) diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py index 344cd1d18c..128456b181 100644 --- a/gyp/pylib/gyp/generator/msvs.py +++ b/gyp/pylib/gyp/generator/msvs.py @@ -1,8 +1,9 @@ -from __future__ import print_function # 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. +from __future__ import print_function + import copy import ntpath import os @@ -756,8 +757,8 @@ def _Replace(match): # the VCProj but cause the same problem on the final command-line. Moving # the item to the end of the list does works, but that's only possible if # there's only one such item. Let's just warn the user. - print(('Warning: MSVS may misinterpret the odd number of ' + - 'quotes in ' + s), file=sys.stderr) + print('Warning: MSVS may misinterpret the odd number of ' + + 'quotes in ' + s, file=sys.stderr) return s @@ -975,8 +976,8 @@ def _ValidateSourcesForMSVSProject(spec, version): error += ' %s: %s\n' % (basename, ' '.join(files)) if error: - print('static library %s has several files with the same basename:\n' % - spec['target_name'] + error + 'MSVC08 cannot handle that.') + print('static library %s has several files with the same basename:\n' % spec['target_name'] + + error + 'MSVC08 cannot handle that.') raise GypError('Duplicate basenames in sources section, see list above') @@ -3028,7 +3029,7 @@ def _FinalizeMSBuildSettings(spec, configuration): for ignored_setting in ignored_settings: value = configuration.get(ignored_setting) if value: - print ('Warning: The automatic conversion to MSBuild does not handle ' + print('Warning: The automatic conversion to MSBuild does not handle ' '%s. Ignoring setting of %s' % (ignored_setting, str(value))) defines = [_EscapeCppDefineForMSBuild(d) for d in defines] diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index f55619f3b0..5afbba03fe 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -1,8 +1,9 @@ -from __future__ import print_function # 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. +from __future__ import print_function + from compiler.ast import Const from compiler.ast import Dict from compiler.ast import Discard @@ -2530,8 +2531,8 @@ def ValidateSourcesInTarget(target, target_dict, build_file, error += ' %s: %s\n' % (basename, ' '.join(files)) if error: - print('static library %s has several files with the same basename:\n' % - target + error + 'libtool on Mac cannot handle that. Use ' + print('static library %s has several files with the same basename:\n' % target + + error + 'libtool on Mac cannot handle that. Use ' '--no-duplicate-basename-check to disable this validation.') raise GypError('Duplicate basenames in sources section, see list above') diff --git a/gyp/pylib/gyp/mac_tool.py b/gyp/pylib/gyp/mac_tool.py index 36203801c8..0ab3de18f7 100755 --- a/gyp/pylib/gyp/mac_tool.py +++ b/gyp/pylib/gyp/mac_tool.py @@ -7,6 +7,7 @@ These functions are executed via gyp-mac-tool when using the Makefile generator. """ + from __future__ import print_function import fcntl @@ -441,8 +442,7 @@ def _FindProvisioningProfile(self, profile, bundle_identifier): profiles_dir = os.path.join( os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles') if not os.path.isdir(profiles_dir): - print(( - 'cannot find mobile provisioning for %s' % bundle_identifier), file=sys.stderr) + print('cannot find mobile provisioning for %s' % (bundle_identifier), file=sys.stderr) sys.exit(1) provisioning_profiles = None if profile: @@ -463,8 +463,7 @@ def _FindProvisioningProfile(self, profile, bundle_identifier): valid_provisioning_profiles[app_id_pattern] = ( profile_path, profile_data, team_identifier) if not valid_provisioning_profiles: - print(( - 'cannot find mobile provisioning for %s' % bundle_identifier), file=sys.stderr) + print('cannot find mobile provisioning for %s' % (bundle_identifier), file=sys.stderr) sys.exit(1) # If the user has multiple provisioning profiles installed that can be # used for ${bundle_identifier}, pick the most specific one (ie. the diff --git a/gyp/pylib/gyp/win_tool.py b/gyp/pylib/gyp/win_tool.py index 85a7926095..3bade00dbe 100755 --- a/gyp/pylib/gyp/win_tool.py +++ b/gyp/pylib/gyp/win_tool.py @@ -8,6 +8,7 @@ These functions are executed via gyp-win-tool when using the ninja generator. """ + from __future__ import print_function import os diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index cbd589b43b..fd4427b86b 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -6,6 +6,7 @@ This module contains classes that help to emulate xcodebuild behavior on top of other build systems, such as make and ninja. """ + from __future__ import print_function import copy diff --git a/gyp/tools/graphviz.py b/gyp/tools/graphviz.py index dcf7c765e5..538b059da4 100755 --- a/gyp/tools/graphviz.py +++ b/gyp/tools/graphviz.py @@ -7,6 +7,7 @@ """Using the JSON dumped by the dump-dependency-json generator, generate input suitable for graphviz to render a dependency graph of targets.""" + from __future__ import print_function import collections diff --git a/gyp/tools/pretty_gyp.py b/gyp/tools/pretty_gyp.py index 8111224595..d01c692edc 100755 --- a/gyp/tools/pretty_gyp.py +++ b/gyp/tools/pretty_gyp.py @@ -5,6 +5,7 @@ # found in the LICENSE file. """Pretty-prints the contents of a GYP file.""" + from __future__ import print_function import sys diff --git a/gyp/tools/pretty_sln.py b/gyp/tools/pretty_sln.py index 64a9ec2bf6..731844caf7 100755 --- a/gyp/tools/pretty_sln.py +++ b/gyp/tools/pretty_sln.py @@ -11,10 +11,11 @@ Then it outputs a possible build order. """ -from __future__ import print_function __author__ = 'nsylvain (Nicolas Sylvain)' +from __future__ import print_function + import os import re import sys diff --git a/gyp/tools/pretty_vcproj.py b/gyp/tools/pretty_vcproj.py index c96ba061ef..51cfc4e081 100755 --- a/gyp/tools/pretty_vcproj.py +++ b/gyp/tools/pretty_vcproj.py @@ -11,10 +11,10 @@ It outputs the resulting xml to stdout. """ -from __future__ import print_function - __author__ = 'nsylvain (Nicolas Sylvain)' +from __future__ import print_function + import os import sys @@ -284,8 +284,8 @@ def main(argv): # check if we have exactly 1 parameter. if len(argv) < 2: - print ('Usage: %s "c:\\path\\to\\vcproj.vcproj" [key1=value1] ' - '[key2=value2]' % argv[0]) + print(('Usage: %s "c:\\path\\to\\vcproj.vcproj" [key1=value1] ' + '[key2=value2]' % argv[0])) return 1 # Parse the keys From 332144473d69a2b7e87e490b956f5aa9a0aac712 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Sun, 19 Mar 2017 16:36:13 -0400 Subject: [PATCH 49/54] gyp: replace deprecated functions * assertEquals() with assertEqual() * iteritems() with items() for Python 3. * xrange() with range() for Python 3. https://github.com/nodejs/node-gyp/pull/1150 Reviewed-By: Refael Ackermann --- gyp/PRESUBMIT.py | 3 +- gyp/pylib/gyp/MSVSSettings.py | 8 ++-- gyp/pylib/gyp/MSVSUserFile.py | 4 +- gyp/pylib/gyp/MSVSUtil.py | 2 +- gyp/pylib/gyp/__init__.py | 4 +- gyp/pylib/gyp/easy_xml.py | 2 +- gyp/pylib/gyp/generator/android.py | 6 +-- gyp/pylib/gyp/generator/gypd.py | 2 +- gyp/pylib/gyp/generator/make.py | 4 +- gyp/pylib/gyp/generator/msvs.py | 58 ++++++++++++++-------------- gyp/pylib/gyp/generator/ninja.py | 6 +-- gyp/pylib/gyp/generator/xcode.py | 20 +++++----- gyp/pylib/gyp/input.py | 62 +++++++++++++++--------------- gyp/pylib/gyp/input_test.py | 22 +++++------ gyp/pylib/gyp/mac_tool.py | 6 +-- gyp/pylib/gyp/msvs_emulation.py | 6 +-- gyp/pylib/gyp/ordered_dict.py | 4 +- gyp/pylib/gyp/simple_copy.py | 2 +- gyp/pylib/gyp/win_tool.py | 2 +- gyp/pylib/gyp/xcode_emulation.py | 6 +-- gyp/pylib/gyp/xcode_ninja.py | 4 +- gyp/pylib/gyp/xcodeproj_file.py | 26 ++++++------- 22 files changed, 129 insertions(+), 130 deletions(-) diff --git a/gyp/PRESUBMIT.py b/gyp/PRESUBMIT.py index f6c8a357af..e52f9d2d22 100644 --- a/gyp/PRESUBMIT.py +++ b/gyp/PRESUBMIT.py @@ -76,8 +76,7 @@ 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))) - + allowed_years = (str(s) for s in reversed(range(2009, current_year + 1))) years_re = '(' + '|'.join(allowed_years) + ')' # The (c) is deprecated, but tolerate it until it's removed from all files. diff --git a/gyp/pylib/gyp/MSVSSettings.py b/gyp/pylib/gyp/MSVSSettings.py index 455862c636..00721eb237 100644 --- a/gyp/pylib/gyp/MSVSSettings.py +++ b/gyp/pylib/gyp/MSVSSettings.py @@ -435,7 +435,7 @@ def ConvertVCMacrosToMSBuild(s): '$(PlatformName)': '$(Platform)', '$(SafeInputName)': '%(Filename)', } - for old, new in replace_map.iteritems(): + for old, new in replace_map.items(): s = s.replace(old, new) s = FixVCMacroSlashes(s) return s @@ -455,10 +455,10 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): dictionaries of settings and their values. """ msbuild_settings = {} - for msvs_tool_name, msvs_tool_settings in msvs_settings.iteritems(): + for msvs_tool_name, msvs_tool_settings in msvs_settings.items(): if msvs_tool_name in _msvs_to_msbuild_converters: msvs_tool = _msvs_to_msbuild_converters[msvs_tool_name] - for msvs_setting, msvs_value in msvs_tool_settings.iteritems(): + for msvs_setting, msvs_value in msvs_tool_settings.items(): if msvs_setting in msvs_tool: # Invoke the translation function. try: @@ -515,7 +515,7 @@ def _ValidateSettings(validators, settings, stderr): for tool_name in settings: if tool_name in validators: tool_validators = validators[tool_name] - for setting, value in settings[tool_name].iteritems(): + for setting, value in settings[tool_name].items(): if setting in tool_validators: try: tool_validators[setting](value) diff --git a/gyp/pylib/gyp/MSVSUserFile.py b/gyp/pylib/gyp/MSVSUserFile.py index 6c07e9a893..2264d64015 100644 --- a/gyp/pylib/gyp/MSVSUserFile.py +++ b/gyp/pylib/gyp/MSVSUserFile.py @@ -91,7 +91,7 @@ def AddDebugSettings(self, config_name, command, environment = {}, if environment and isinstance(environment, dict): env_list = ['%s="%s"' % (key, val) - for (key,val) in environment.iteritems()] + for (key,val) in environment.items()] environment = ' '.join(env_list) else: environment = '' @@ -135,7 +135,7 @@ def AddDebugSettings(self, config_name, command, environment = {}, def WriteIfChanged(self): """Writes the user file.""" configs = ['Configurations'] - for config, spec in sorted(self.configurations.iteritems()): + for config, spec in sorted(self.configurations.items()): configs.append(spec) content = ['VisualStudioUserFile', diff --git a/gyp/pylib/gyp/MSVSUtil.py b/gyp/pylib/gyp/MSVSUtil.py index 0b32e91180..c8187eb331 100644 --- a/gyp/pylib/gyp/MSVSUtil.py +++ b/gyp/pylib/gyp/MSVSUtil.py @@ -235,7 +235,7 @@ def InsertLargePdbShims(target_list, target_dicts, vars): # Set up the shim to output its PDB to the same location as the final linker # target. - for config_name, config in shim_dict.get('configurations').iteritems(): + for config_name, config in shim_dict.get('configurations').items(): pdb_path = _GetPdbPath(target_dict, config_name, vars) # A few keys that we don't want to propagate. diff --git a/gyp/pylib/gyp/__init__.py b/gyp/pylib/gyp/__init__.py index bd51cde888..5f82f2ef2c 100755 --- a/gyp/pylib/gyp/__init__.py +++ b/gyp/pylib/gyp/__init__.py @@ -209,7 +209,7 @@ def Noop(value): # We always want to ignore the environment when regenerating, to avoid # duplicate or changed flags in the environment at the time of regeneration. flags = ['--ignore-environment'] - for name, metadata in options._regeneration_metadata.iteritems(): + for name, metadata in options._regeneration_metadata.items(): opt = metadata['opt'] value = getattr(options, name) value_predicate = metadata['type'] == 'path' and FixPath or Noop @@ -434,7 +434,7 @@ def gyp_main(args): build_file_dir = os.path.abspath(os.path.dirname(build_file)) build_file_dir_components = build_file_dir.split(os.path.sep) components_len = len(build_file_dir_components) - for index in xrange(components_len - 1, -1, -1): + for index in range(components_len - 1, -1, -1): if build_file_dir_components[index] == 'src': options.depth = os.path.sep.join(build_file_dir_components) break diff --git a/gyp/pylib/gyp/easy_xml.py b/gyp/pylib/gyp/easy_xml.py index fd525a712b..7c3f621f1f 100644 --- a/gyp/pylib/gyp/easy_xml.py +++ b/gyp/pylib/gyp/easy_xml.py @@ -81,7 +81,7 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0): # Optionally in second position is a dictionary of the attributes. rest = specification[1:] if rest and isinstance(rest[0], dict): - for at, val in sorted(rest[0].iteritems()): + for at, val in sorted(rest[0].items()): xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True))) rest = rest[1:] if rest: diff --git a/gyp/pylib/gyp/generator/android.py b/gyp/pylib/gyp/generator/android.py index 66139892cc..b7f9842888 100644 --- a/gyp/pylib/gyp/generator/android.py +++ b/gyp/pylib/gyp/generator/android.py @@ -460,7 +460,7 @@ def WriteSourceFlags(self, spec, configs): Args: spec, configs: input from gyp. """ - for configname, config in sorted(configs.iteritems()): + for configname, config in sorted(configs.items()): extracted_includes = [] self.WriteLn('\n# Flags passed to both C and C++ files.') @@ -790,7 +790,7 @@ def WriteTargetFlags(self, spec, configs, link_deps): static_libs, dynamic_libs, ldflags_libs = self.FilterLibraries(libraries) if self.type != 'static_library': - for configname, config in sorted(configs.iteritems()): + for configname, config in sorted(configs.items()): ldflags = list(config.get('ldflags', [])) self.WriteLn('') self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname) @@ -839,7 +839,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, part_of_all, settings = spec.get('aosp_build_settings', {}) if settings: self.WriteLn('### Set directly by aosp_build_settings.') - for k, v in settings.iteritems(): + for k, v in settings.items(): if isinstance(v, list): self.WriteList(v, k) else: diff --git a/gyp/pylib/gyp/generator/gypd.py b/gyp/pylib/gyp/generator/gypd.py index 3efdb9966a..78eeaa61b2 100644 --- a/gyp/pylib/gyp/generator/gypd.py +++ b/gyp/pylib/gyp/generator/gypd.py @@ -88,7 +88,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if not output_file in output_files: output_files[output_file] = input_file - for output_file, input_file in output_files.iteritems(): + for output_file, input_file in output_files.items(): output = open(output_file, 'w') pprint.pprint(data[input_file], output) output.close() diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 96212be1fc..cfc7b05433 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -674,7 +674,7 @@ def _ValidateSourcesForOSX(spec, all_sources): basenames.setdefault(basename, []).append(source) error = '' - for basename, files in basenames.iteritems(): + for basename, files in basenames.items(): if len(files) > 1: error += ' %s: %s\n' % (basename, ' '.join(files)) @@ -1547,7 +1547,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, # Postbuilds expect to be run in the gyp file's directory, so insert an # implicit postbuild to cd to there. postbuilds.insert(0, gyp.common.EncodePOSIXShellList(['cd', self.path])) - for i in xrange(len(postbuilds)): + for i in range(len(postbuilds)): if not postbuilds[i].startswith('$'): postbuilds[i] = EscapeShellArgument(postbuilds[i]) self.WriteLn('%s: builddir := $(abs_builddir)' % QuoteSpaces(self.output)) diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py index 128456b181..fb2549d025 100644 --- a/gyp/pylib/gyp/generator/msvs.py +++ b/gyp/pylib/gyp/generator/msvs.py @@ -451,7 +451,7 @@ def _AddCustomBuildToolForMSVS(p, spec, primary_input, 'CommandLine': cmd, }) # Add to the properties of primary input for each config. - for config_name, c_data in spec['configurations'].iteritems(): + for config_name, c_data in spec['configurations'].items(): p.AddFileConfig(_FixPath(primary_input), _ConfigFullName(config_name, c_data), tools=[tool]) @@ -971,7 +971,7 @@ def _ValidateSourcesForMSVSProject(spec, version): basenames.setdefault(basename, []).append(source) error = '' - for basename, files in basenames.iteritems(): + for basename, files in basenames.items(): if len(files) > 1: error += ' %s: %s\n' % (basename, ' '.join(files)) @@ -1003,7 +1003,7 @@ def _GenerateMSVSProject(project, options, version, generator_flags): relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, project_dir) config_type = _GetMSVSConfigurationType(spec, project.build_file) - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config) # MSVC08 and prior version cannot handle duplicate basenames in the same @@ -1369,10 +1369,10 @@ def _ConvertToolsToExpectedForm(tools): A list of Tool objects. """ tool_list = [] - for tool, settings in tools.iteritems(): + for tool, settings in tools.items(): # Collapse settings with lists. settings_fixed = {} - for setting, value in settings.iteritems(): + for setting, value in settings.items(): if type(value) == list: if ((tool == 'VCLinkerTool' and setting == 'AdditionalDependencies') or @@ -1547,7 +1547,7 @@ def _IdlFilesHandledNonNatively(spec, sources): def _GetPrecompileRelatedFiles(spec): # Gather a list of precompiled header related sources. precompiled_related = [] - for _, config in spec['configurations'].iteritems(): + for _, config in spec['configurations'].items(): for k in precomp_keys: f = config.get(k) if f: @@ -1558,7 +1558,7 @@ def _GetPrecompileRelatedFiles(spec): def _ExcludeFilesFromBeingBuilt(p, spec, excluded_sources, excluded_idl, list_excluded): exclusions = _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl) - for file_name, excluded_configs in exclusions.iteritems(): + for file_name, excluded_configs in exclusions.items(): if (not list_excluded and len(excluded_configs) == len(spec['configurations'])): # If we're not listing excluded files, then they won't appear in the @@ -1575,7 +1575,7 @@ def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): # Exclude excluded sources from being built. for f in excluded_sources: excluded_configs = [] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): precomped = [_FixPath(config.get(i, '')) for i in precomp_keys] # Don't do this for ones that are precompiled header related. if f not in precomped: @@ -1585,7 +1585,7 @@ def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): # Exclude them now. for f in excluded_idl: excluded_configs = [] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): excluded_configs.append((config_name, config)) exclusions[f] = excluded_configs return exclusions @@ -1594,7 +1594,7 @@ def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): def _AddToolFilesToMSVS(p, spec): # Add in tool files (rules). tool_files = OrderedSet() - for _, config in spec['configurations'].iteritems(): + for _, config in spec['configurations'].items(): for f in config.get('msvs_tool_files', []): tool_files.add(f) for f in tool_files: @@ -1607,7 +1607,7 @@ def _HandlePreCompiledHeaders(p, sources, spec): # kind (i.e. C vs. C++) as the precompiled header source stub needs # to have use of precompiled headers disabled. extensions_excluded_from_precompile = [] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): source = config.get('msvs_precompiled_source') if source: source = _FixPath(source) @@ -1628,7 +1628,7 @@ def DisableForSourceTree(source_tree): else: basename, extension = os.path.splitext(source) if extension in extensions_excluded_from_precompile: - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): tool = MSVSProject.Tool('VCCLCompilerTool', {'UsePrecompiledHeader': '0', 'ForcedIncludeFiles': '$(NOINHERIT)'}) @@ -1679,7 +1679,7 @@ def _WriteMSVSUserFile(project_path, version, spec): return # Nothing to add # Write out the user file. user_file = _CreateMSVSUserFile(project_path, version, spec) - for config_name, c_data in spec['configurations'].iteritems(): + for config_name, c_data in spec['configurations'].items(): user_file.AddDebugSettings(_ConfigFullName(config_name, c_data), action, environment, working_directory) user_file.WriteIfChanged() @@ -1730,7 +1730,7 @@ def _GetPathDict(root, path): def _DictsToFolders(base_path, bucket, flat): # Convert to folders recursively. children = [] - for folder, contents in bucket.iteritems(): + for folder, contents in bucket.items(): if type(contents) == dict: folder_children = _DictsToFolders(os.path.join(base_path, folder), contents, flat) @@ -1802,7 +1802,7 @@ def _GetPlatformOverridesOfProject(spec): # Prepare a dict indicating which project configurations are used for which # solution configurations for this target. config_platform_overrides = {} - for config_name, c in spec['configurations'].iteritems(): + for config_name, c in spec['configurations'].items(): config_fullname = _ConfigFullName(config_name, c) platform = c.get('msvs_target_platform', _ConfigPlatform(c)) fixed_config_fullname = '%s|%s' % ( @@ -1941,7 +1941,7 @@ def PerformBuild(data, configurations, params): msvs_version = params['msvs_version'] devenv = os.path.join(msvs_version.path, 'Common7', 'IDE', 'devenv.com') - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): (build_file_root, build_file_ext) = os.path.splitext(build_file) if build_file_ext != '.gyp': continue @@ -1990,7 +1990,7 @@ def GenerateOutput(target_list, target_dicts, data, params): configs = set() for qualified_target in target_list: spec = target_dicts[qualified_target] - for config_name, config in spec['configurations'].iteritems(): + for config_name, config in spec['configurations'].items(): configs.add(_ConfigFullName(config_name, config)) configs = list(configs) @@ -2630,7 +2630,7 @@ def _GetConfigurationCondition(name, settings): def _GetMSBuildProjectConfigurations(configurations): group = ['ItemGroup', {'Label': 'ProjectConfigurations'}] - for (name, settings) in sorted(configurations.iteritems()): + for (name, settings) in sorted(configurations.items()): configuration, platform = _GetConfigurationAndPlatform(name, settings) designation = '%s|%s' % (configuration, platform) group.append( @@ -2700,7 +2700,7 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): def _GetMSBuildConfigurationDetails(spec, build_file): properties = {} - for name, settings in spec['configurations'].iteritems(): + for name, settings in spec['configurations'].items(): msbuild_attributes = _GetMSBuildAttributes(spec, settings, build_file) condition = _GetConfigurationCondition(name, settings) character_set = msbuild_attributes.get('CharacterSet') @@ -2729,7 +2729,7 @@ def _GetMSBuildPropertySheets(configurations): user_props = r'$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props' additional_props = {} props_specified = False - for name, settings in sorted(configurations.iteritems()): + for name, settings in sorted(configurations.items()): configuration = _GetConfigurationCondition(name, settings) if 'msbuild_props' in settings: additional_props[configuration] = _FixPaths(settings['msbuild_props']) @@ -2751,7 +2751,7 @@ def _GetMSBuildPropertySheets(configurations): ] else: sheets = [] - for condition, props in additional_props.iteritems(): + for condition, props in additional_props.items(): import_group = [ 'ImportGroup', {'Label': 'PropertySheets', @@ -2878,7 +2878,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): new_paths = '$(ExecutablePath);' + ';'.join(new_paths) properties = {} - for (name, configuration) in sorted(configurations.iteritems()): + for (name, configuration) in sorted(configurations.items()): condition = _GetConfigurationCondition(name, configuration) attributes = _GetMSBuildAttributes(spec, configuration, build_file) msbuild_settings = configuration['finalized_msbuild_settings'] @@ -2903,7 +2903,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): _AddConditionalProperty(properties, condition, 'ExecutablePath', new_paths) tool_settings = msbuild_settings.get('', {}) - for name, value in sorted(tool_settings.iteritems()): + for name, value in sorted(tool_settings.items()): formatted_value = _GetValueFormattedForMSBuild('', name, value) _AddConditionalProperty(properties, condition, name, formatted_value) return _GetMSBuildPropertyGroup(spec, None, properties) @@ -2972,7 +2972,7 @@ def GetEdges(node): # NOTE: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) for name in reversed(properties_ordered): values = properties[name] - for value, conditions in sorted(values.iteritems()): + for value, conditions in sorted(values.items()): if len(conditions) == num_configurations: # If the value is the same all configurations, # just add one unconditional entry. @@ -2985,18 +2985,18 @@ def GetEdges(node): def _GetMSBuildToolSettingsSections(spec, configurations): groups = [] - for (name, configuration) in sorted(configurations.iteritems()): + for (name, configuration) in sorted(configurations.items()): msbuild_settings = configuration['finalized_msbuild_settings'] group = ['ItemDefinitionGroup', {'Condition': _GetConfigurationCondition(name, configuration)} ] - for tool_name, tool_settings in sorted(msbuild_settings.iteritems()): + for tool_name, tool_settings in sorted(msbuild_settings.items()): # Skip the tool named '' which is a holder of global settings handled # by _GetMSBuildConfigurationGlobalProperties. if tool_name: if tool_settings: tool = [tool_name] - for name, value in sorted(tool_settings.iteritems()): + for name, value in sorted(tool_settings.items()): formatted_value = _GetValueFormattedForMSBuild(tool_name, name, value) tool.append([name, formatted_value]) @@ -3196,7 +3196,7 @@ def _AddSources2(spec, sources, exclusions, grouped_sources, {'Condition': condition}, 'true']) # Add precompile if needed - for config_name, configuration in spec['configurations'].iteritems(): + for config_name, configuration in spec['configurations'].items(): precompiled_source = configuration.get('msvs_precompiled_source', '') if precompiled_source != '': precompiled_source = _FixPath(precompiled_source) @@ -3436,7 +3436,7 @@ def _GenerateActionsForMSBuild(spec, actions_to_add): """ sources_handled_by_action = OrderedSet() actions_spec = [] - for primary_input, actions in actions_to_add.iteritems(): + for primary_input, actions in actions_to_add.items(): inputs = OrderedSet() outputs = OrderedSet() descriptions = [] diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index 1fc00e1f98..aae5b71310 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -797,7 +797,7 @@ def WriteMacXCassets(self, xcassets, bundle_depends): 'XCASSETS_LAUNCH_IMAGE': 'launch-image', } settings = self.xcode_settings.xcode_settings[self.config_name] - for settings_key, arg_name in settings_to_arg.iteritems(): + for settings_key, arg_name in settings_to_arg.items(): value = settings.get(settings_key) if value: extra_arguments[arg_name] = value @@ -1890,7 +1890,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value) # Support wrappers from environment variables too. - for key, value in os.environ.iteritems(): + for key, value in os.environ.items(): if key.lower().endswith('_wrapper'): key_prefix = key[:-len('_wrapper')] key_prefix = re.sub(r'\.HOST$', '.host', key_prefix) @@ -1906,7 +1906,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, configs, generator_flags) cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles( toplevel_build, generator_flags, shared_system_includes, OpenOutput) - for arch, path in cl_paths.iteritems(): + for arch, path in cl_paths.items(): if clang_cl: # If we have selected clang-cl, use that instead. path = clang_cl diff --git a/gyp/pylib/gyp/generator/xcode.py b/gyp/pylib/gyp/generator/xcode.py index 63f80d7657..694a28afb1 100644 --- a/gyp/pylib/gyp/generator/xcode.py +++ b/gyp/pylib/gyp/generator/xcode.py @@ -183,7 +183,7 @@ def Finalize1(self, xcode_targets, serialize_all_tests): # the tree tree view for UI display. # Any values set globally are applied to all configurations, then any # per-configuration values are applied. - for xck, xcv in self.build_file_dict.get('xcode_settings', {}).iteritems(): + for xck, xcv in self.build_file_dict.get('xcode_settings', {}).items(): xccl.SetBuildSetting(xck, xcv) if 'xcode_config_file' in self.build_file_dict: config_ref = self.project.AddOrGetFileInRootGroup( @@ -197,7 +197,7 @@ def Finalize1(self, xcode_targets, serialize_all_tests): if build_file_configuration_named: xcc = xccl.ConfigurationNamed(config_name) for xck, xcv in build_file_configuration_named.get('xcode_settings', - {}).iteritems(): + {}).items(): xcc.SetBuildSetting(xck, xcv) if 'xcode_config_file' in build_file_configuration_named: config_ref = self.project.AddOrGetFileInRootGroup( @@ -273,7 +273,7 @@ def Finalize1(self, xcode_targets, serialize_all_tests): script = script + "\n".join( ['export %s="%s"' % (key, gyp.xcodeproj_file.ConvertVariablesToShellSyntax(val)) - for (key, val) in command.get('environment').iteritems()]) + "\n" + for (key, val) in command.get('environment').items()]) + "\n" # Some test end up using sockets, files on disk, etc. and can get # confused if more then one test runs at a time. The generator @@ -566,7 +566,7 @@ def EscapeXcodeDefine(s): def PerformBuild(data, configurations, params): options = params['options'] - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): (build_file_root, build_file_ext) = os.path.splitext(build_file) if build_file_ext != '.gyp': continue @@ -625,7 +625,7 @@ def GenerateOutput(target_list, target_dicts, data, params): skip_excluded_files = \ not generator_flags.get('xcode_list_excluded_files', True) xcode_projects = {} - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): (build_file_root, build_file_ext) = os.path.splitext(build_file) if build_file_ext != '.gyp': continue @@ -1014,7 +1014,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # target. makefile.write('all: \\\n') for concrete_output_index in \ - xrange(0, len(concrete_outputs_by_rule_source)): + range(0, len(concrete_outputs_by_rule_source)): # Only list the first (index [0]) concrete output of each input # in the "all" target. Otherwise, a parallel make (-j > 1) would # attempt to process each input multiple times simultaneously. @@ -1037,7 +1037,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # rule source. Collect the names of the directories that are # required. concrete_output_dirs = [] - for concrete_output_index in xrange(0, len(concrete_outputs)): + for concrete_output_index in range(0, len(concrete_outputs)): concrete_output = concrete_outputs[concrete_output_index] if concrete_output_index == 0: bol = '' @@ -1056,7 +1056,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # the set of additional rule inputs, if any. prerequisites = [rule_source] prerequisites.extend(rule.get('inputs', [])) - for prerequisite_index in xrange(0, len(prerequisites)): + for prerequisite_index in range(0, len(prerequisites)): prerequisite = prerequisites[prerequisite_index] if prerequisite_index == len(prerequisites) - 1: eol = '' @@ -1278,7 +1278,7 @@ def GenerateOutput(target_list, target_dicts, data, params): set_define = EscapeXcodeDefine(define) xcbc.AppendBuildSetting('GCC_PREPROCESSOR_DEFINITIONS', set_define) if 'xcode_settings' in configuration: - for xck, xcv in configuration['xcode_settings'].iteritems(): + for xck, xcv in configuration['xcode_settings'].items(): xcbc.SetBuildSetting(xck, xcv) if 'xcode_config_file' in configuration: config_ref = pbxp.AddOrGetFileInRootGroup( @@ -1286,7 +1286,7 @@ def GenerateOutput(target_list, target_dicts, data, params): xcbc.SetBaseConfiguration(config_ref) build_files = [] - for build_file, build_file_dict in data.iteritems(): + for build_file, build_file_dict in data.items(): if build_file.endswith('.gyp'): build_files.append(build_file) diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index 5afbba03fe..68e51131d8 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -311,7 +311,7 @@ def LoadBuildFileIncludesIntoDict(subdict, subdict_path, data, aux_data, subdict_path, include) # Recurse into subdictionaries. - for k, v in subdict.iteritems(): + for k, v in subdict.items(): if type(v) is dict: LoadBuildFileIncludesIntoDict(v, subdict_path, data, aux_data, None, check) @@ -497,7 +497,7 @@ def CallLoadTargetBuildFile(global_flags, signal.signal(signal.SIGINT, signal.SIG_IGN) # Apply globals so that the worker process behaves the same. - for key, value in global_flags.iteritems(): + for key, value in global_flags.items(): globals()[key] = value SetGeneratorGlobals(generator_input_info) @@ -1028,7 +1028,7 @@ def ExpandVariables(input, phase, variables, build_file): # Convert all strings that are canonically-represented integers into integers. if type(output) is list: - for index in xrange(0, len(output)): + for index in range(0, len(output)): if IsStrCanonicalInt(output[index]): output[index] = int(output[index]) elif IsStrCanonicalInt(output): @@ -1160,7 +1160,7 @@ def ProcessConditionsInDict(the_dict, phase, variables, build_file): def LoadAutomaticVariablesFromDict(variables, the_dict): # Any keys with plain string values in the_dict become automatic variables. # The variable name is the key name with a "_" character prepended. - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): if type(value) in (str, int, list): variables['_' + key] = value @@ -1173,7 +1173,7 @@ def LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key): # the_dict in the_dict's parent dict. If the_dict's parent is not a dict # (it could be a list or it could be parentless because it is a root dict), # the_dict_key will be None. - for key, value in the_dict.get('variables', {}).iteritems(): + for key, value in the_dict.get('variables', {}).items(): if type(value) not in (str, int, list): continue @@ -1212,7 +1212,7 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, # list before we process them so that you can reference one # variable from another. They will be fully expanded by recursion # in ExpandVariables. - for key, value in the_dict['variables'].iteritems(): + for key, value in the_dict['variables'].items(): variables[key] = value # Handle the associated variables dict first, so that any variable @@ -1225,7 +1225,7 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key) - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): # Skip "variables", which was already processed if present. if key != 'variables' and type(value) is str: expanded = ExpandVariables(value, phase, variables, build_file) @@ -1283,7 +1283,7 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, # Recurse into child dicts, or process child lists which may result in # further recursion into descendant dicts. - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): # Skip "variables" and string values, which were already processed if # present. if key == 'variables' or type(value) is str: @@ -1380,12 +1380,12 @@ def QualifyDependencies(targets): for dep in dependency_sections for op in ('', '!', '/')] - for target, target_dict in targets.iteritems(): + for target, target_dict in targets.items(): target_build_file = gyp.common.BuildFile(target) toolset = target_dict['toolset'] for dependency_key in all_dependency_sections: dependencies = target_dict.get(dependency_key, []) - for index in xrange(0, len(dependencies)): + for index in range(0, len(dependencies)): dep_file, dep_target, dep_toolset = gyp.common.ResolveTarget( target_build_file, dependencies[index], toolset) if not multiple_toolsets: @@ -1420,13 +1420,13 @@ def ExpandWildcardDependencies(targets, data): dependency list, must be qualified when this function is called. """ - for target, target_dict in targets.iteritems(): + for target, target_dict in targets.items(): toolset = target_dict['toolset'] target_build_file = gyp.common.BuildFile(target) for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) - # Loop this way instead of "for dependency in" or "for index in xrange" + # Loop this way instead of "for dependency in" or "for index in range" # because the dependencies list will be modified within the loop body. index = 0 while index < len(dependencies): @@ -1482,7 +1482,7 @@ def Unify(l): def RemoveDuplicateDependencies(targets): """Makes sure every dependency appears only once in all targets's dependency lists.""" - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: @@ -1498,7 +1498,7 @@ def Filter(l, item): def RemoveSelfDependencies(targets): """Remove self dependencies from targets that have the prune_self_dependency variable set.""" - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: @@ -1511,7 +1511,7 @@ def RemoveSelfDependencies(targets): def RemoveLinkDependenciesFromNoneTargets(targets): """Remove dependencies having the 'link_dependency' attribute from the 'none' targets.""" - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: @@ -1797,14 +1797,14 @@ def BuildDependencyList(targets): # Create a DependencyGraphNode for each target. Put it into a dict for easy # access. dependency_nodes = {} - for target, spec in targets.iteritems(): + for target, spec in targets.items(): if target not in dependency_nodes: dependency_nodes[target] = DependencyGraphNode(target) # Set up the dependency links. Targets that have no dependencies are treated # as dependent on root_node. root_node = DependencyGraphNode(None) - for target, spec in targets.iteritems(): + for target, spec in targets.items(): target_node = dependency_nodes[target] target_build_file = gyp.common.BuildFile(target) dependencies = spec.get('dependencies') @@ -1853,7 +1853,7 @@ def VerifyNoGYPFileCircularDependencies(targets): dependency_nodes[build_file] = DependencyGraphNode(build_file) # Set up the dependency links. - for target, spec in targets.iteritems(): + for target, spec in targets.items(): build_file = gyp.common.BuildFile(target) build_file_node = dependency_nodes[build_file] target_dependencies = spec.get('dependencies', []) @@ -2118,7 +2118,7 @@ def is_in_set_or_list(x, s, l): def MergeDicts(to, fro, to_file, fro_file): # I wanted to name the parameter "from" but it's a Python keyword... - for k, v in fro.iteritems(): + for k, v in fro.items(): # It would be nice to do "if not k in to: to[k] = v" but that wouldn't give # copy semantics. Something else may want to merge from the |fro| dict # later, and having the same dict ref pointed to twice in the tree isn't @@ -2253,13 +2253,13 @@ def SetUpConfigurations(target, target_dict): if not 'configurations' in target_dict: target_dict['configurations'] = {'Default': {}} if not 'default_configuration' in target_dict: - concrete = [i for (i, config) in target_dict['configurations'].iteritems() + concrete = [i for (i, config) in target_dict['configurations'].items() if not config.get('abstract')] target_dict['default_configuration'] = sorted(concrete)[0] merged_configurations = {} configs = target_dict['configurations'] - for (configuration, old_configuration_dict) in configs.iteritems(): + for (configuration, old_configuration_dict) in configs.items(): # Skip abstract configurations (saves work only). if old_configuration_dict.get('abstract'): continue @@ -2267,7 +2267,7 @@ def SetUpConfigurations(target, target_dict): # Get the inheritance relationship right by making a copy of the target # dict. new_configuration_dict = {} - for (key, target_val) in target_dict.iteritems(): + for (key, target_val) in target_dict.items(): key_ext = key[-1:] if key_ext in key_suffixes: key_base = key[:-1] @@ -2351,7 +2351,7 @@ def ProcessListFiltersInDict(name, the_dict): lists = [] del_lists = [] - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): operation = key[-1] if operation != '!' and operation != '/': continue @@ -2399,7 +2399,7 @@ def ProcessListFiltersInDict(name, the_dict): exclude_key = list_key + '!' if exclude_key in the_dict: for exclude_item in the_dict[exclude_key]: - for index in xrange(0, len(the_list)): + for index in range(0, len(the_list)): if exclude_item == the_list[index]: # This item matches the exclude_item, so set its action to 0 # (exclude). @@ -2425,7 +2425,7 @@ def ProcessListFiltersInDict(name, the_dict): raise ValueError('Unrecognized action ' + action + ' in ' + name + \ ' key ' + regex_key) - for index in xrange(0, len(the_list)): + for index in range(0, len(the_list)): list_item = the_list[index] if list_actions[index] == action_value: # Even if the regex matches, nothing will change so continue (regex @@ -2456,7 +2456,7 @@ def ProcessListFiltersInDict(name, the_dict): # the indices of items that haven't been seen yet don't shift. That means # that things need to be prepended to excluded_list to maintain them in the # same order that they existed in the_list. - for index in xrange(len(list_actions) - 1, -1, -1): + for index in range(len(list_actions) - 1, -1, -1): if list_actions[index] == 0: # Dump anything with action 0 (exclude). Keep anything with action 1 # (include) or -1 (no include or exclude seen for the item). @@ -2469,7 +2469,7 @@ def ProcessListFiltersInDict(name, the_dict): the_dict[excluded_key] = excluded_list # Now recurse into subdicts and lists that may contain dicts. - for key, value in the_dict.iteritems(): + for key, value in the_dict.items(): if type(value) is dict: ProcessListFiltersInDict(key, value) elif type(value) is list: @@ -2526,7 +2526,7 @@ def ValidateSourcesInTarget(target, target_dict, build_file, basenames.setdefault(basename, []).append(source) error = '' - for basename, files in basenames.iteritems(): + for basename, files in basenames.items(): if len(files) > 1: error += ' %s: %s\n' % (basename, ' '.join(files)) @@ -2646,7 +2646,7 @@ def ValidateActionsInTarget(target, target_dict, build_file): def TurnIntIntoStrInDict(the_dict): """Given dict the_dict, recursively converts all integers into strings. """ - # Use items instead of iteritems because there's no need to try to look at + # Use items instead of items because there's no need to try to look at # reinserted keys and their associated values. for k, v in the_dict.items(): if type(v) is int: @@ -2665,7 +2665,7 @@ def TurnIntIntoStrInDict(the_dict): def TurnIntIntoStrInList(the_list): """Given list the_list, recursively converts all integers into strings. """ - for index in xrange(0, len(the_list)): + for index in range(0, len(the_list)): item = the_list[index] if type(item) is int: the_list[index] = str(item) @@ -2805,7 +2805,7 @@ def Load(build_files, variables, includes, depth, generator_input_info, check, RemoveLinkDependenciesFromNoneTargets(targets) # Apply exclude (!) and regex (/) list filters only for dependency_sections. - for target_name, target_dict in targets.iteritems(): + for target_name, target_dict in targets.items(): tmp_dict = {} for key_base in dependency_sections: for op in ('', '!', '/'): diff --git a/gyp/pylib/gyp/input_test.py b/gyp/pylib/gyp/input_test.py index 4234fbb830..1bc5e3d308 100755 --- a/gyp/pylib/gyp/input_test.py +++ b/gyp/pylib/gyp/input_test.py @@ -22,38 +22,38 @@ def _create_dependency(self, dependent, dependency): dependency.dependents.append(dependent) def test_no_cycle_empty_graph(self): - for label, node in self.nodes.iteritems(): - self.assertEquals([], node.FindCycles()) + for label, node in self.nodes.items(): + self.assertEqual([], node.FindCycles()) def test_no_cycle_line(self): self._create_dependency(self.nodes['a'], self.nodes['b']) self._create_dependency(self.nodes['b'], self.nodes['c']) self._create_dependency(self.nodes['c'], self.nodes['d']) - for label, node in self.nodes.iteritems(): - self.assertEquals([], node.FindCycles()) + for label, node in self.nodes.items(): + self.assertEqual([], node.FindCycles()) def test_no_cycle_dag(self): self._create_dependency(self.nodes['a'], self.nodes['b']) self._create_dependency(self.nodes['a'], self.nodes['c']) self._create_dependency(self.nodes['b'], self.nodes['c']) - for label, node in self.nodes.iteritems(): - self.assertEquals([], node.FindCycles()) + for label, node in self.nodes.items(): + self.assertEqual([], node.FindCycles()) def test_cycle_self_reference(self): self._create_dependency(self.nodes['a'], self.nodes['a']) - self.assertEquals([[self.nodes['a'], self.nodes['a']]], + self.assertEqual([[self.nodes['a'], self.nodes['a']]], self.nodes['a'].FindCycles()) def test_cycle_two_nodes(self): self._create_dependency(self.nodes['a'], self.nodes['b']) self._create_dependency(self.nodes['b'], self.nodes['a']) - self.assertEquals([[self.nodes['a'], self.nodes['b'], self.nodes['a']]], + self.assertEqual([[self.nodes['a'], self.nodes['b'], self.nodes['a']]], self.nodes['a'].FindCycles()) - self.assertEquals([[self.nodes['b'], self.nodes['a'], self.nodes['b']]], + self.assertEqual([[self.nodes['b'], self.nodes['a'], self.nodes['b']]], self.nodes['b'].FindCycles()) def test_two_cycles(self): @@ -68,7 +68,7 @@ def test_two_cycles(self): [self.nodes['a'], self.nodes['b'], self.nodes['a']] in cycles) self.assertTrue( [self.nodes['b'], self.nodes['c'], self.nodes['b']] in cycles) - self.assertEquals(2, len(cycles)) + self.assertEqual(2, len(cycles)) def test_big_cycle(self): self._create_dependency(self.nodes['a'], self.nodes['b']) @@ -77,7 +77,7 @@ def test_big_cycle(self): self._create_dependency(self.nodes['d'], self.nodes['e']) self._create_dependency(self.nodes['e'], self.nodes['a']) - self.assertEquals([[self.nodes['a'], + self.assertEqual([[self.nodes['a'], self.nodes['b'], self.nodes['c'], self.nodes['d'], diff --git a/gyp/pylib/gyp/mac_tool.py b/gyp/pylib/gyp/mac_tool.py index 0ab3de18f7..b8f38a8fdc 100755 --- a/gyp/pylib/gyp/mac_tool.py +++ b/gyp/pylib/gyp/mac_tool.py @@ -326,7 +326,7 @@ def ExecCompileXcassets(self, keys, *inputs): ]) if keys: keys = json.loads(keys) - for key, value in keys.iteritems(): + for key, value in keys.items(): arg_name = '--' + key if isinstance(value, bool): if value: @@ -487,7 +487,7 @@ def _LoadProvisioningProfile(self, profile_path): def _MergePlist(self, merged_plist, plist): """Merge |plist| into |merged_plist|.""" - for key, value in plist.iteritems(): + for key, value in plist.items(): if isinstance(value, dict): merged_value = merged_plist.get(key, {}) if isinstance(merged_value, dict): @@ -597,7 +597,7 @@ def _ExpandVariables(self, data, substitutions): the key was not found. """ if isinstance(data, str): - for key, value in substitutions.iteritems(): + for key, value in substitutions.items(): data = data.replace('$(%s)' % key, value) return data if isinstance(data, list): diff --git a/gyp/pylib/gyp/msvs_emulation.py b/gyp/pylib/gyp/msvs_emulation.py index ca67b122f0..75da78526c 100644 --- a/gyp/pylib/gyp/msvs_emulation.py +++ b/gyp/pylib/gyp/msvs_emulation.py @@ -205,7 +205,7 @@ def __init__(self, spec, generator_flags): configs = spec['configurations'] for field, default in supported_fields: setattr(self, field, {}) - for configname, config in configs.iteritems(): + for configname, config in configs.items(): getattr(self, field)[configname] = config.get(field, default()) self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) @@ -941,7 +941,7 @@ def ExpandMacros(string, expansions): """Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv for the canonical way to retrieve a suitable dict.""" if '$' in string: - for old, new in expansions.iteritems(): + for old, new in expansions.items(): assert '$(' not in new, new string = string.replace(old, new) return string @@ -985,7 +985,7 @@ def _FormatAsEnvironmentBlock(envvar_dict): CreateProcess documentation for more details.""" block = '' nul = '\0' - for key, value in envvar_dict.iteritems(): + for key, value in envvar_dict.items(): block += key + '=' + value + nul block += nul return block diff --git a/gyp/pylib/gyp/ordered_dict.py b/gyp/pylib/gyp/ordered_dict.py index a1e89f9199..6fe9c1f6c7 100644 --- a/gyp/pylib/gyp/ordered_dict.py +++ b/gyp/pylib/gyp/ordered_dict.py @@ -161,8 +161,8 @@ def itervalues(self): for k in self: yield self[k] - def iteritems(self): - 'od.iteritems -> an iterator over the (key, value) items in od' + def items(self): + 'od.items -> an iterator over the (key, value) items in od' for k in self: yield (k, self[k]) diff --git a/gyp/pylib/gyp/simple_copy.py b/gyp/pylib/gyp/simple_copy.py index 74c98c5a79..463929386e 100644 --- a/gyp/pylib/gyp/simple_copy.py +++ b/gyp/pylib/gyp/simple_copy.py @@ -38,7 +38,7 @@ def _deepcopy_list(x): def _deepcopy_dict(x): y = {} - for key, value in x.iteritems(): + for key, value in x.items(): y[deepcopy(key)] = deepcopy(value) return y d[dict] = _deepcopy_dict diff --git a/gyp/pylib/gyp/win_tool.py b/gyp/pylib/gyp/win_tool.py index 3bade00dbe..bca0b9e346 100755 --- a/gyp/pylib/gyp/win_tool.py +++ b/gyp/pylib/gyp/win_tool.py @@ -294,7 +294,7 @@ def ExecActionWrapper(self, arch, rspfile, *dir): env = self._GetEnv(arch) # TODO(scottmg): This is a temporary hack to get some specific variables # through to actions that are set after gyp-time. http://crbug.com/333738. - for k, v in os.environ.iteritems(): + for k, v in os.environ.items(): if k not in env: env[k] = v args = open(rspfile).read() diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index fd4427b86b..66f325932a 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -170,7 +170,7 @@ def __init__(self, spec): # the same for all configs are implicitly per-target settings. self.xcode_settings = {} configs = spec['configurations'] - for configname, config in configs.iteritems(): + for configname, config in configs.items(): self.xcode_settings[configname] = config.get('xcode_settings', {}) self._ConvertConditionalKeys(configname) if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET', @@ -891,7 +891,7 @@ def GetPerTargetSettings(self): result = dict(self.xcode_settings[configname]) first_pass = False else: - for key, value in self.xcode_settings[configname].iteritems(): + for key, value in self.xcode_settings[configname].items(): if key not in result: continue elif result[key] != value: @@ -1639,7 +1639,7 @@ def _AddIOSDeviceConfigurations(targets): for target_dict in targets.itervalues(): toolset = target_dict['toolset'] configs = target_dict['configurations'] - for config_name, config_dict in dict(configs).iteritems(): + for config_name, config_dict in dict(configs).items(): iphoneos_config_dict = copy.deepcopy(config_dict) configs[config_name + '-iphoneos'] = iphoneos_config_dict configs[config_name + '-iphonesimulator'] = config_dict diff --git a/gyp/pylib/gyp/xcode_ninja.py b/gyp/pylib/gyp/xcode_ninja.py index d781471005..5acd82e004 100644 --- a/gyp/pylib/gyp/xcode_ninja.py +++ b/gyp/pylib/gyp/xcode_ninja.py @@ -161,7 +161,7 @@ def CreateWrapper(target_list, target_dicts, data, params): params: Dict of global options for gyp. """ orig_gyp = params['build_files'][0] - for gyp_name, gyp_dict in data.iteritems(): + for gyp_name, gyp_dict in data.items(): if gyp_name == orig_gyp: depth = gyp_dict['_DEPTH'] @@ -228,7 +228,7 @@ def CreateWrapper(target_list, target_dicts, data, params): sources_target['configurations'] = {'Default': { 'include_dirs': [ depth ] } } sources = [] - for target, target_dict in target_dicts.iteritems(): + for target, target_dict in target_dicts.items(): base = os.path.dirname(target) files = target_dict.get('sources', []) + \ target_dict.get('mac_bundle_resources', []) diff --git a/gyp/pylib/gyp/xcodeproj_file.py b/gyp/pylib/gyp/xcodeproj_file.py index 712eefe3f8..9bd582e477 100644 --- a/gyp/pylib/gyp/xcodeproj_file.py +++ b/gyp/pylib/gyp/xcodeproj_file.py @@ -314,7 +314,7 @@ def Copy(self): """ that = self.__class__(id=self.id, parent=self.parent) - for key, value in self._properties.iteritems(): + for key, value in self._properties.items(): is_strong = self._schema[key][2] if isinstance(value, XCObject): @@ -452,7 +452,7 @@ def _HashUpdate(hash, data): digest_int_count = hash.digest_size / 4 digest_ints = struct.unpack('>' + 'I' * digest_int_count, hash.digest()) id_ints = [0, 0, 0] - for index in xrange(0, digest_int_count): + for index in range(0, digest_int_count): id_ints[index % 3] ^= digest_ints[index] self.id = '%08X%08X%08X' % tuple(id_ints) @@ -475,7 +475,7 @@ def Children(self): """Returns a list of all of this object's owned (strong) children.""" children = [] - for property, attributes in self._schema.iteritems(): + for property, attributes in self._schema.items(): (is_list, property_type, is_strong) = attributes[0:3] if is_strong and property in self._properties: if not is_list: @@ -622,7 +622,7 @@ def _XCPrintableValue(self, tabs, value, flatten_list=False): printable += end_tabs + ')' elif isinstance(value, dict): printable = '{' + sep - for item_key, item_value in sorted(value.iteritems()): + for item_key, item_value in sorted(value.items()): printable += element_tabs + \ self._XCPrintableValue(tabs + 1, item_key, flatten_list) + ' = ' + \ self._XCPrintableValue(tabs + 1, item_value, flatten_list) + ';' + \ @@ -730,7 +730,7 @@ def Print(self, file=sys.stdout): self._XCKVPrint(file, 3, 'isa', self.__class__.__name__) # The remaining elements of an object dictionary are sorted alphabetically. - for property, value in sorted(self._properties.iteritems()): + for property, value in sorted(self._properties.items()): self._XCKVPrint(file, 3, property, value) # End the object. @@ -752,7 +752,7 @@ def UpdateProperties(self, properties, do_copy=False): if properties is None: return - for property, value in properties.iteritems(): + for property, value in properties.items(): # Make sure the property is in the schema. if not property in self._schema: raise KeyError(property + ' not in ' + self.__class__.__name__) @@ -865,7 +865,7 @@ def VerifyHasRequiredProperties(self): # TODO(mark): A stronger verification mechanism is needed. Some # subclasses need to perform validation beyond what the schema can enforce. - for property, attributes in self._schema.iteritems(): + for property, attributes in self._schema.items(): (is_list, property_type, is_strong, is_required) = attributes[0:4] if is_required and not property in self._properties: raise KeyError(self.__class__.__name__ + ' requires ' + property) @@ -875,7 +875,7 @@ def _SetDefaultsFromSchema(self): overwrite properties that have already been set.""" defaults = {} - for property, attributes in self._schema.iteritems(): + for property, attributes in self._schema.items(): (is_list, property_type, is_strong, is_required) = attributes[0:4] if is_required and len(attributes) >= 5 and \ not property in self._properties: @@ -1426,7 +1426,7 @@ def PathHashables(self): xche = self while xche != None and isinstance(xche, XCHierarchicalElement): xche_hashables = xche.Hashables() - for index in xrange(0, len(xche_hashables)): + for index in range(0, len(xche_hashables)): hashables.insert(index, xche_hashables[index]) xche = xche.parent return hashables @@ -2401,7 +2401,7 @@ def HeadersPhase(self): # The headers phase should come before the resources, sources, and # frameworks phases, if any. insert_at = len(self._properties['buildPhases']) - for index in xrange(0, len(self._properties['buildPhases'])): + for index in range(0, len(self._properties['buildPhases'])): phase = self._properties['buildPhases'][index] if isinstance(phase, PBXResourcesBuildPhase) or \ isinstance(phase, PBXSourcesBuildPhase) or \ @@ -2422,7 +2422,7 @@ def ResourcesPhase(self): # The resources phase should come before the sources and frameworks # phases, if any. insert_at = len(self._properties['buildPhases']) - for index in xrange(0, len(self._properties['buildPhases'])): + for index in range(0, len(self._properties['buildPhases'])): phase = self._properties['buildPhases'][index] if isinstance(phase, PBXSourcesBuildPhase) or \ isinstance(phase, PBXFrameworksBuildPhase): @@ -2844,7 +2844,7 @@ def CompareProducts(x, y, remote_products): # determine the sort order. return cmp(x_index, y_index) - for other_pbxproject, ref_dict in self._other_pbxprojects.iteritems(): + for other_pbxproject, ref_dict in self._other_pbxprojects.items(): # Build up a list of products in the remote project file, ordered the # same as the targets that produce them. remote_products = [] @@ -2889,7 +2889,7 @@ def Print(self, file=sys.stdout): self._XCPrint(file, 0, '{ ') else: self._XCPrint(file, 0, '{\n') - for property, value in sorted(self._properties.iteritems(), + for property, value in sorted(self._properties.items(), cmp=lambda x, y: cmp(x, y)): if property == 'objects': self._PrintObjects(file) From 9eb9b39a56c044d054246093f28e8010fbaf3e38 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Sun, 19 Mar 2017 13:59:05 -0700 Subject: [PATCH 50/54] gyp: replace basestring with str, but only on Python 3. On Python 2, basestring is (unicode, str). On Python 3, basestring and unicode are gone, and there is only str. --- gyp/pylib/gyp/MSVSSettings.py | 10 ++++++---- gyp/pylib/gyp/__init__.py | 9 ++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/gyp/pylib/gyp/MSVSSettings.py b/gyp/pylib/gyp/MSVSSettings.py index 00721eb237..8073f92b8d 100644 --- a/gyp/pylib/gyp/MSVSSettings.py +++ b/gyp/pylib/gyp/MSVSSettings.py @@ -16,6 +16,8 @@ from __future__ import print_function +from gyp import string_types + import sys import re @@ -108,11 +110,11 @@ class _String(_Type): """A setting that's just a string.""" def ValidateMSVS(self, value): - if not isinstance(value, basestring): + if not isinstance(value, string_types): raise ValueError('expected string; got %r' % value) def ValidateMSBuild(self, value): - if not isinstance(value, basestring): + if not isinstance(value, string_types): raise ValueError('expected string; got %r' % value) def ConvertToMSBuild(self, value): @@ -124,11 +126,11 @@ class _StringList(_Type): """A settings that's a list of strings.""" def ValidateMSVS(self, value): - if not isinstance(value, basestring) and not isinstance(value, list): + if not isinstance(value, string_types) and not isinstance(value, list): raise ValueError('expected string list; got %r' % value) def ValidateMSBuild(self, value): - if not isinstance(value, basestring) and not isinstance(value, list): + if not isinstance(value, string_types) and not isinstance(value, list): raise ValueError('expected string list; got %r' % value) def ConvertToMSBuild(self, value): diff --git a/gyp/pylib/gyp/__init__.py b/gyp/pylib/gyp/__init__.py index 5f82f2ef2c..d5fa9ecf50 100755 --- a/gyp/pylib/gyp/__init__.py +++ b/gyp/pylib/gyp/__init__.py @@ -16,6 +16,13 @@ import traceback from gyp.common import GypError +try: + # Python 2 + string_types = basestring +except NameError: + # Python 3 + string_types = str + # Default debug modes for GYP debug = {} @@ -412,7 +419,7 @@ def gyp_main(args): for option, value in sorted(options.__dict__.items()): if option[0] == '_': continue - if isinstance(value, basestring): + if isinstance(value, string_types): DebugOutput(DEBUG_GENERAL, " %s: '%s'", option, value) else: DebugOutput(DEBUG_GENERAL, " %s: %s", option, value) From ef8b60aff5b5b06d33f8b47e89a845ddde7090ef Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Sun, 19 Mar 2017 14:04:36 -0700 Subject: [PATCH 51/54] gyp: _winreg module was renamed to winreg in Python 3. https://github.com/nodejs/node-gyp/pull/1150 Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/MSVSVersion.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gyp/pylib/gyp/MSVSVersion.py b/gyp/pylib/gyp/MSVSVersion.py index c31ff3e114..293b4145c1 100644 --- a/gyp/pylib/gyp/MSVSVersion.py +++ b/gyp/pylib/gyp/MSVSVersion.py @@ -176,12 +176,18 @@ def _RegistryGetValueUsingWinReg(key, value): contents of the registry key's value, or None on failure. Throws ImportError if _winreg is unavailable. """ - import _winreg + try: + # Python 2 + from _winreg import OpenKey, QueryValueEx + except ImportError: + # Python 3 + from winreg import OpenKey, QueryValueEx + try: root, subkey = key.split('\\', 1) assert root == 'HKLM' # Only need HKLM for now. - with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: - return _winreg.QueryValueEx(hkey, value)[0] + with OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: + return QueryValueEx(hkey, value)[0] except WindowsError: return None From ae0be8745db6c6c94f9e670f1638bc2c99303982 Mon Sep 17 00:00:00 2001 From: cclauss Date: Tue, 14 Nov 2017 07:56:07 +0100 Subject: [PATCH 52/54] gyp: fix sntex error PR-URL: https://github.com/nodejs/node-gyp/pull/1333 Reviewed-By: Refael Ackermann --- gyp/pylib/gyp/mac_tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gyp/pylib/gyp/mac_tool.py b/gyp/pylib/gyp/mac_tool.py index b8f38a8fdc..b8b7344eff 100755 --- a/gyp/pylib/gyp/mac_tool.py +++ b/gyp/pylib/gyp/mac_tool.py @@ -127,7 +127,7 @@ def _DetectInputEncoding(self, file_name): fp = open(file_name, 'rb') try: header = fp.read(3) - except e: + except Exception: fp.close() return None fp.close() From 2394a1eca27bfc99e03f899034783287f17c6b08 Mon Sep 17 00:00:00 2001 From: cclauss Date: Tue, 14 Nov 2017 09:00:29 +0100 Subject: [PATCH 53/54] gyp: fix target --> self.target target is an undefined name in this context. https://github.com/nodejs/node-gyp/pull/1334 Reviewed-By: Refael Ackermann --- 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 cfc7b05433..d549e899d8 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -1639,7 +1639,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all, postbuilds=postbuilds) else: - print("WARNING: no output for", self.type, target) + print("WARNING: no output for", self.type, self.target) # Add an alias for each target (if there are any outputs). # Installable target aliases are created below. From 020e2bdb6836b57462cccac6083a67f074019658 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Sun, 14 Oct 2018 18:17:49 -0400 Subject: [PATCH 54/54] meta: add to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6748492014..4d6b4d55b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ gyp/test node_modules test/.node-gyp +.ncu +package-lock.json