nodejs/tools/build-addons.js

59 lines
1.7 KiB
JavaScript

'use strict';
// Usage: e.g. node build-addons.js <path to node-gyp> <directory>
const child_process = require('child_process');
const path = require('path');
const fs = require('fs').promises;
const util = require('util');
const execFile = util.promisify(child_process.execFile);
const parallelization = +process.env.JOBS || require('os').cpus().length;
const nodeGyp = process.argv[2];
async function runner(directoryQueue) {
if (directoryQueue.length === 0)
return;
const dir = directoryQueue.shift();
const next = () => runner(directoryQueue);
try {
// Only run for directories that have a `binding.gyp`.
// (https://github.com/nodejs/node/issues/14843)
await fs.stat(path.join(dir, 'binding.gyp'));
} catch (err) {
if (err.code === 'ENOENT' || err.code === 'ENOTDIR')
return next();
throw err;
}
console.log(`Building addon in ${dir}`);
const { stdout, stderr } =
await execFile(process.execPath, [nodeGyp, 'rebuild', `--directory=${dir}`],
{
stdio: 'inherit',
env: { ...process.env, MAKEFLAGS: '-j1' }
});
// We buffer the output and print it out once the process is done in order
// to avoid interleaved output from multiple builds running at once.
process.stdout.write(stdout);
process.stderr.write(stderr);
return next();
}
async function main(directory) {
const directoryQueue = (await fs.readdir(directory))
.map((subdir) => path.join(directory, subdir));
const runners = [];
for (let i = 0; i < parallelization; ++i)
runners.push(runner(directoryQueue));
return Promise.all(runners);
}
main(process.argv[3]).catch((err) => setImmediate(() => { throw err; }));