forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: build test add-ons like third-party add-ons
Until now we built add-ons by pointing node-gyp at the src/ directory. We've had at least one DOA release where add-ons were broken because of a header dependency issue that wasn't caught because we build our test add-ons in a non-standard way. This commit does the following: * Use tools/install.py to install the headers to test/addons/include. * Add a script to build everything in test/addons. * Remove the pile-up of hacks from the Makefile. The same logic is applied to test/addons-napi and test/gc. Everything is done in parallel as much as possible to speed up builds. Ideally, we derive the level of parallelism from MAKEFLAGS but it lacks the actual `-j<n>` flag. That's why it simply spawns as many processes as there are processors for now. The exception is tools/doc/addon-verify.js: I switched it to synchronous logic to make it easy to use from another script. Since it takes no time at all to do its work, that seemed like a reasonable trade-off to me. Refs: nodejs#11628
- Loading branch information
1 parent
30989d3
commit d427cac
Showing
9 changed files
with
157 additions
and
224 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
.buildstamp | ||
.docbuildstamp | ||
Makefile | ||
*.Makefile | ||
*.mk | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
.buildstamp | ||
.docbuildstamp | ||
Makefile | ||
*.Makefile | ||
*.mk | ||
gyp-mac-tool | ||
/*/build | ||
/Release/ | ||
/include/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ | |
{ | ||
'target_name': 'binding', | ||
'sources': ['binding.cc'], | ||
'include_dirs': ['../../../deps/zlib'], | ||
}, | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
'use strict'; | ||
|
||
const fs = require('fs'); | ||
const os = require('os'); | ||
const { spawn, spawnSync } = require('child_process'); | ||
const { resolve } = require('path'); | ||
|
||
const kTopLevelDirectory = resolve(__dirname, '..'); | ||
const kAddonsDirectory = resolve(kTopLevelDirectory, 'test/addons'); | ||
const kNapiAddonsDirectory = resolve(kTopLevelDirectory, 'test/addons-napi'); | ||
|
||
// Location where the headers are installed to. | ||
const kIncludeDirectory = kAddonsDirectory; | ||
|
||
const kPython = process.env.PYTHON || 'python'; | ||
const kNodeGyp = | ||
resolve(kTopLevelDirectory, 'deps/npm/node_modules/node-gyp/bin/node-gyp'); | ||
|
||
process.chdir(kTopLevelDirectory); | ||
|
||
// Copy headers to `${kIncludeDirectory}/include`. install.py preserves | ||
// timestamps so this won't cause unnecessary rebuilds. | ||
{ | ||
const args = [ 'tools/install.py', 'install', kIncludeDirectory, '/' ]; | ||
const env = Object.assign({}, process.env); | ||
env.HEADERS_ONLY = 'yes, please'; // Ask nicely. | ||
env.LOGLEVEL = 'WARNING'; | ||
|
||
const options = { env, stdio: 'inherit' }; | ||
const result = spawnSync(kPython, args, options); | ||
if (result.status !== 0) process.exit(1); | ||
} | ||
|
||
// Scrape embedded add-ons from doc/api/addons.md. | ||
require('./doc/addon-verify.js'); | ||
|
||
// Regenerate build files and rebuild if necessary. | ||
let failures = 0; | ||
process.on('exit', () => process.exit(failures > 0)); | ||
|
||
const jobs = []; | ||
|
||
// test/gc contains a single add-on to build. | ||
{ | ||
const path = resolve(kTopLevelDirectory, 'test/gc'); | ||
exec(path, 'configure', () => exec(path, 'build')); | ||
} | ||
|
||
for (const directory of [kAddonsDirectory, kNapiAddonsDirectory]) { | ||
for (const basedir of fs.readdirSync(directory)) { | ||
const path = resolve(directory, basedir); | ||
const gypfile = resolve(path, 'binding.gyp'); | ||
if (!fs.existsSync(gypfile)) continue; | ||
exec(path, 'configure', () => exec(path, 'build')); | ||
} | ||
} | ||
|
||
// FIXME(bnoordhuis) I would have liked to derive the desired level of | ||
// parallelism from MAKEFLAGS but it's missing the actual -j<jobs> flag. | ||
for (const _ of os.cpus()) next(); // eslint-disable-line no-unused-vars | ||
|
||
function next() { | ||
const job = jobs.shift(); | ||
if (job) job(); | ||
} | ||
|
||
function exec(path, command, done) { | ||
jobs.push(() => { | ||
if (failures > 0) return; | ||
|
||
const args = [kNodeGyp, | ||
'--loglevel=silent', | ||
'--directory=' + path, | ||
'--nodedir=' + kIncludeDirectory, | ||
'--python=' + kPython, | ||
command]; | ||
|
||
const env = Object.assign({}, process.env); | ||
env.MAKEFLAGS = '-j1'; | ||
|
||
const options = { env, stdio: 'inherit' }; | ||
const proc = spawn(process.execPath, args, options); | ||
|
||
proc.on('exit', (exitCode) => { | ||
if (exitCode !== 0) ++failures; | ||
if (done) done(); | ||
next(); | ||
}); | ||
|
||
console.log(command, path); | ||
}); | ||
} |
Oops, something went wrong.