mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
7a216d5fd6
We define a new type called `node_api_nogc_env` as the `const` version of `napi_env` and `node_api_nogc_finalize` as a variant of `napi_finalize` that accepts a `node_api_nogc_env` as its first argument. We then modify those APIs which do not affect GC state as accepting a `node_api_nogc_env`. APIs accepting finalizer callbacks are modified to accept `node_api_nogc_finalize` callbacks. Thus, the only way to attach a `napi_finalize` callback, wherein Node-APIs affecting GC state may be called is to call `node_api_post_finalizer` from a `node_api_nogc_finalize` callback. In keeping with the process of introducing new Node-APIs, this feature is guarded by `NAPI_EXPERIMENTAL`. Since this feature modifies APIs already marked as stable, it is additionally guared by `NODE_API_EXPERIMENTAL_NOGC_ENV`, so as to provide a further buffer to adoption. Nevertheless, both guards must be removed upon releasing a new version of Node-API. PR-URL: https://github.com/nodejs/node/pull/50060 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Vladimir Morozov <vmorozov@microsoft.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
66 lines
1.9 KiB
JavaScript
Executable File
66 lines
1.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
// Usage: e.g. node build-addons.mjs <path to node-gyp> <directory>
|
|
|
|
import child_process from 'node:child_process';
|
|
import path from 'node:path';
|
|
import fs from 'node:fs/promises';
|
|
import util from 'node:util';
|
|
import process from 'node:process';
|
|
import os from 'node:os';
|
|
|
|
const execFile = util.promisify(child_process.execFile);
|
|
|
|
const parallelization = +process.env.JOBS || os.availableParallelism();
|
|
const nodeGyp = process.argv[2];
|
|
const directory = process.argv[3];
|
|
|
|
async function buildAddon(dir) {
|
|
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;
|
|
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);
|
|
}
|
|
|
|
async function parallel(jobQueue, limit) {
|
|
const next = async () => {
|
|
if (jobQueue.length === 0) {
|
|
return;
|
|
}
|
|
const job = jobQueue.shift();
|
|
await job();
|
|
await next();
|
|
};
|
|
|
|
const workerCnt = Math.min(limit, jobQueue.length);
|
|
await Promise.all(Array.from({ length: workerCnt }, next));
|
|
}
|
|
|
|
const jobs = [];
|
|
for await (const dirent of await fs.opendir(directory)) {
|
|
if (dirent.isDirectory()) {
|
|
jobs.push(() => buildAddon(path.join(directory, dirent.name)));
|
|
} else if (dirent.isFile() && dirent.name === 'binding.gyp') {
|
|
jobs.push(() => buildAddon(directory));
|
|
}
|
|
}
|
|
await parallel(jobs, parallelization);
|