647 lines
19 KiB
JavaScript
647 lines
19 KiB
JavaScript
'use strict';
|
|
var __assign =
|
|
(this && this.__assign) ||
|
|
function () {
|
|
__assign =
|
|
Object.assign ||
|
|
function (t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s)
|
|
if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __awaiter =
|
|
(this && this.__awaiter) ||
|
|
function (thisArg, _arguments, P, generator) {
|
|
function adopt(value) {
|
|
return value instanceof P ? value : (
|
|
new P(function (resolve) {
|
|
resolve(value);
|
|
})
|
|
);
|
|
}
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) {
|
|
try {
|
|
step(generator.next(value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
function rejected(value) {
|
|
try {
|
|
step(generator['throw'](value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
function step(result) {
|
|
result.done ?
|
|
resolve(result.value)
|
|
: adopt(result.value).then(fulfilled, rejected);
|
|
}
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
var __generator =
|
|
(this && this.__generator) ||
|
|
function (thisArg, body) {
|
|
var _ = {
|
|
label: 0,
|
|
sent: function () {
|
|
if (t[0] & 1) throw t[1];
|
|
return t[1];
|
|
},
|
|
trys: [],
|
|
ops: [],
|
|
},
|
|
f,
|
|
y,
|
|
t,
|
|
g;
|
|
return (
|
|
(g = { next: verb(0), throw: verb(1), return: verb(2) }),
|
|
typeof Symbol === 'function' &&
|
|
(g[Symbol.iterator] = function () {
|
|
return this;
|
|
}),
|
|
g
|
|
);
|
|
function verb(n) {
|
|
return function (v) {
|
|
return step([n, v]);
|
|
};
|
|
}
|
|
function step(op) {
|
|
if (f) throw new TypeError('Generator is already executing.');
|
|
while (_)
|
|
try {
|
|
if (
|
|
((f = 1),
|
|
y &&
|
|
(t =
|
|
op[0] & 2 ? y['return']
|
|
: op[0] ? y['throw'] || ((t = y['return']) && t.call(y), 0)
|
|
: y.next) &&
|
|
!(t = t.call(y, op[1])).done)
|
|
)
|
|
return t;
|
|
if (((y = 0), t)) op = [op[0] & 2, t.value];
|
|
switch (op[0]) {
|
|
case 0:
|
|
case 1:
|
|
t = op;
|
|
break;
|
|
case 4:
|
|
_.label++;
|
|
return { value: op[1], done: false };
|
|
case 5:
|
|
_.label++;
|
|
y = op[1];
|
|
op = [0];
|
|
continue;
|
|
case 7:
|
|
op = _.ops.pop();
|
|
_.trys.pop();
|
|
continue;
|
|
default:
|
|
if (
|
|
!((t = _.trys), (t = t.length > 0 && t[t.length - 1])) &&
|
|
(op[0] === 6 || op[0] === 2)
|
|
) {
|
|
_ = 0;
|
|
continue;
|
|
}
|
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
|
|
_.label = op[1];
|
|
break;
|
|
}
|
|
if (op[0] === 6 && _.label < t[1]) {
|
|
_.label = t[1];
|
|
t = op;
|
|
break;
|
|
}
|
|
if (t && _.label < t[2]) {
|
|
_.label = t[2];
|
|
_.ops.push(op);
|
|
break;
|
|
}
|
|
if (t[2]) _.ops.pop();
|
|
_.trys.pop();
|
|
continue;
|
|
}
|
|
op = body.call(thisArg, _);
|
|
} catch (e) {
|
|
op = [6, e];
|
|
y = 0;
|
|
} finally {
|
|
f = t = 0;
|
|
}
|
|
if (op[0] & 5) throw op[1];
|
|
return { value: op[0] ? op[1] : void 0, done: true };
|
|
}
|
|
};
|
|
var __spreadArray =
|
|
(this && this.__spreadArray) ||
|
|
function (to, from, pack) {
|
|
if (pack || arguments.length === 2)
|
|
for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
if (ar || !(i in from)) {
|
|
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
ar[i] = from[i];
|
|
}
|
|
}
|
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
};
|
|
var __importDefault =
|
|
(this && this.__importDefault) ||
|
|
function (mod) {
|
|
return mod && mod.__esModule ? mod : { default: mod };
|
|
};
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
var zlib_1 = require('zlib');
|
|
var crypto_1 = __importDefault(require('crypto'));
|
|
var fs_extra_1 = __importDefault(require('fs-extra'));
|
|
var os_1 = __importDefault(require('os'));
|
|
var path_1 = __importDefault(require('path'));
|
|
var stream_1 = require('stream');
|
|
var util_1 = require('util');
|
|
var tar_fs_1 = __importDefault(require('tar-fs'));
|
|
var places_1 = require('./places');
|
|
var utils_1 = require('./utils');
|
|
var system_1 = require('./system');
|
|
var log_1 = require('./log');
|
|
var patches_json_1 = __importDefault(require('../patches/patches.json'));
|
|
var buildPath = path_1.default.resolve(
|
|
process.env.PKG_BUILD_PATH ||
|
|
path_1.default.join(
|
|
os_1.default.tmpdir(),
|
|
'pkg.' + crypto_1.default.randomBytes(12).toString('hex')
|
|
)
|
|
);
|
|
var nodePath = path_1.default.join(buildPath, 'node');
|
|
var patchesPath = path_1.default.resolve(__dirname, '../patches');
|
|
var nodeRepo = 'https://nodejs.org/dist';
|
|
var nodeArchivePath = path_1.default.join(places_1.cachePath, 'node');
|
|
function getMajor(nodeVersion) {
|
|
var _a = nodeVersion.match(/^v?(\d+)/) || ['', 0],
|
|
version = _a[1];
|
|
return Number(version) | 0;
|
|
}
|
|
function getConfigureArgs(major, targetPlatform) {
|
|
var args = [];
|
|
// first of all v8_inspector introduces the use
|
|
// of `prime_rehash_policy` symbol that requires
|
|
// GLIBCXX_3.4.18 on some systems
|
|
// also we don't support any kind of debugging
|
|
// against packaged apps, hence v8_inspector is useless
|
|
args.push('--without-inspector');
|
|
if (system_1.hostPlatform === 'alpine') {
|
|
// Statically Link against libgcc and libstdc++ libraries. See vercel/pkg#555.
|
|
// libgcc and libstdc++ grant GCC Runtime Library Exception of GPL
|
|
args.push('--partly-static');
|
|
}
|
|
if (targetPlatform === 'linuxstatic') {
|
|
args.push('--fully-static');
|
|
}
|
|
// Link Time Optimization
|
|
if (major >= 12) {
|
|
if (system_1.hostPlatform !== 'win') {
|
|
args.push('--enable-lto');
|
|
}
|
|
}
|
|
// production binaries do NOT take NODE_OPTIONS from end-users
|
|
args.push('--without-node-options');
|
|
// DTrace
|
|
args.push('--without-dtrace');
|
|
// bundled npm package manager
|
|
args.push('--without-npm');
|
|
// Small ICU
|
|
args.push('--with-intl=small-icu');
|
|
// Workaround for nodejs/node#39313
|
|
// All supported macOS versions have zlib as a system library
|
|
if (targetPlatform === 'macos') {
|
|
args.push('--shared-zlib');
|
|
}
|
|
return args;
|
|
}
|
|
function tarFetch(nodeVersion) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var distUrl, tarName, archivePath, hashPath, _a, _b, _c;
|
|
return __generator(this, function (_d) {
|
|
switch (_d.label) {
|
|
case 0:
|
|
log_1.log.info('Fetching Node.js source archive from nodejs.org...');
|
|
distUrl = nodeRepo + '/' + nodeVersion;
|
|
tarName = 'node-' + nodeVersion + '.tar.gz';
|
|
archivePath = path_1.default.join(nodeArchivePath, tarName);
|
|
hashPath = path_1.default.join(
|
|
nodeArchivePath,
|
|
tarName + '.sha256sum'
|
|
);
|
|
if (
|
|
fs_extra_1.default.existsSync(hashPath) &&
|
|
fs_extra_1.default.existsSync(archivePath)
|
|
) {
|
|
return [2 /*return*/];
|
|
}
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.remove(hashPath).catch(function () {
|
|
return undefined;
|
|
}),
|
|
];
|
|
case 1:
|
|
_d.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.remove(archivePath).catch(function () {
|
|
return undefined;
|
|
}),
|
|
];
|
|
case 2:
|
|
_d.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.downloadUrl)(distUrl + '/SHASUMS256.txt', hashPath),
|
|
];
|
|
case 3:
|
|
_d.sent();
|
|
_b = (_a = fs_extra_1.default).writeFile;
|
|
_c = [hashPath];
|
|
return [4 /*yield*/, fs_extra_1.default.readFile(hashPath, 'utf8')];
|
|
case 4:
|
|
return [
|
|
4 /*yield*/,
|
|
_b.apply(
|
|
_a,
|
|
_c.concat([
|
|
_d
|
|
.sent()
|
|
.split('\n')
|
|
.filter(function (l) {
|
|
return l.includes(tarName);
|
|
})[0],
|
|
])
|
|
),
|
|
];
|
|
case 5:
|
|
_d.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.downloadUrl)(distUrl + '/' + tarName, archivePath),
|
|
];
|
|
case 6:
|
|
_d.sent();
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function tarExtract(nodeVersion) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var tarName, expectedHash, actualHash, pipe, source, gunzip, extract;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
log_1.log.info('Extracting Node.js source archive...');
|
|
tarName = 'node-' + nodeVersion + '.tar.gz';
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.readFile(
|
|
path_1.default.join(nodeArchivePath, tarName + '.sha256sum'),
|
|
'utf8'
|
|
),
|
|
];
|
|
case 1:
|
|
expectedHash = _a.sent().split(' ')[0];
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.hash)(path_1.default.join(nodeArchivePath, tarName)),
|
|
];
|
|
case 2:
|
|
actualHash = _a.sent();
|
|
if (!(expectedHash !== actualHash)) return [3 /*break*/, 5];
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.remove(
|
|
path_1.default.join(nodeArchivePath, tarName)
|
|
),
|
|
];
|
|
case 3:
|
|
_a.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.remove(
|
|
path_1.default.join(nodeArchivePath, tarName + '.sha256sum')
|
|
),
|
|
];
|
|
case 4:
|
|
_a.sent();
|
|
throw (0, log_1.wasReported)('Hash mismatch for ' + tarName);
|
|
case 5:
|
|
pipe = (0, util_1.promisify)(stream_1.pipeline);
|
|
source = fs_extra_1.default.createReadStream(
|
|
path_1.default.join(nodeArchivePath, tarName)
|
|
);
|
|
gunzip = (0, zlib_1.createGunzip)();
|
|
extract = tar_fs_1.default.extract(nodePath, {
|
|
strip: 1,
|
|
map: function (header) {
|
|
log_1.log.info(header.name);
|
|
return header;
|
|
},
|
|
});
|
|
return [4 /*yield*/, pipe(source, gunzip, extract)];
|
|
case 6:
|
|
_a.sent();
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function applyPatches(nodeVersion) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var storedPatches,
|
|
storedPatch,
|
|
patches,
|
|
_i,
|
|
patches_1,
|
|
patch,
|
|
patchPath,
|
|
args;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
log_1.log.info('Applying patches');
|
|
storedPatches = patches_json_1.default[nodeVersion];
|
|
storedPatch =
|
|
'patches' in storedPatches ? storedPatches.patches : storedPatches;
|
|
patches =
|
|
'sameAs' in storedPatch ?
|
|
patches_json_1.default[storedPatch.sameAs]
|
|
: storedPatch;
|
|
(_i = 0), (patches_1 = patches);
|
|
_a.label = 1;
|
|
case 1:
|
|
if (!(_i < patches_1.length)) return [3 /*break*/, 4];
|
|
patch = patches_1[_i];
|
|
patchPath = path_1.default.join(patchesPath, patch);
|
|
args = ['-p1', '-i', patchPath];
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.spawn)('patch', args, {
|
|
cwd: nodePath,
|
|
stdio: 'inherit',
|
|
}),
|
|
];
|
|
case 2:
|
|
_a.sent();
|
|
_a.label = 3;
|
|
case 3:
|
|
_i++;
|
|
return [3 /*break*/, 1];
|
|
case 4:
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function compileOnWindows(nodeVersion, targetArch, targetPlatform) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var args, major, config_flags;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
args = ['/c', 'vcbuild.bat', targetArch];
|
|
major = getMajor(nodeVersion);
|
|
config_flags = getConfigureArgs(major, targetPlatform);
|
|
// Event Tracing for Windows
|
|
args.push('noetw');
|
|
// Performance counters on Windows
|
|
if (major <= 10) {
|
|
args.push('noperfctr');
|
|
}
|
|
// Link Time Code Generation
|
|
if (major >= 12) {
|
|
args.push('ltcg');
|
|
}
|
|
// Can't cross compile for arm64 with small-icu
|
|
if (
|
|
system_1.hostArch !== targetArch &&
|
|
!config_flags.includes('--with-intl=full-icu')
|
|
) {
|
|
config_flags.push('--without-intl');
|
|
}
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.spawn)('cmd', args, {
|
|
cwd: nodePath,
|
|
env: __assign(__assign({}, process.env), {
|
|
config_flags: config_flags.join(' '),
|
|
}),
|
|
stdio: 'inherit',
|
|
}),
|
|
];
|
|
case 1:
|
|
_a.sent();
|
|
if (major <= 10) {
|
|
return [
|
|
2 /*return*/,
|
|
path_1.default.join(nodePath, 'Release/node.exe'),
|
|
];
|
|
}
|
|
return [
|
|
2 /*return*/,
|
|
path_1.default.join(nodePath, 'out/Release/node.exe'),
|
|
];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
var _a = process.env.MAKE_JOB_COUNT,
|
|
MAKE_JOB_COUNT = _a === void 0 ? os_1.default.cpus().length : _a;
|
|
function compileOnUnix(nodeVersion, targetArch, targetPlatform) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var args, cpu, output;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
args = [];
|
|
cpu = {
|
|
x86: 'ia32',
|
|
x64: 'x64',
|
|
armv6: 'arm',
|
|
armv7: 'arm',
|
|
arm64: 'arm64',
|
|
ppc64: 'ppc64',
|
|
s390x: 's390x',
|
|
}[targetArch];
|
|
if (cpu) {
|
|
args.push('--dest-cpu', cpu);
|
|
}
|
|
if (system_1.hostArch !== targetArch) {
|
|
log_1.log.warn('Cross compiling!');
|
|
log_1.log.warn(
|
|
'You are responsible for appropriate env like CC, CC_host, etc.'
|
|
);
|
|
args.push('--cross-compiling');
|
|
}
|
|
args.push.apply(
|
|
args,
|
|
getConfigureArgs(getMajor(nodeVersion), targetPlatform)
|
|
);
|
|
// TODO same for windows?
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.spawn)(
|
|
'/bin/sh',
|
|
__spreadArray(['./configure'], args, true),
|
|
{
|
|
cwd: nodePath,
|
|
stdio: 'inherit',
|
|
}
|
|
),
|
|
];
|
|
case 1:
|
|
// TODO same for windows?
|
|
_a.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.spawn)(
|
|
system_1.hostPlatform === 'freebsd' ? 'gmake' : 'make',
|
|
['-j', String(MAKE_JOB_COUNT)],
|
|
{
|
|
cwd: nodePath,
|
|
stdio: 'inherit',
|
|
}
|
|
),
|
|
];
|
|
case 2:
|
|
_a.sent();
|
|
output = path_1.default.join(nodePath, 'out/Release/node');
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.spawn)(
|
|
process.env.STRIP || 'strip',
|
|
__spreadArray(
|
|
__spreadArray(
|
|
[],
|
|
targetPlatform === 'macos' ? ['-x'] : [],
|
|
true
|
|
),
|
|
[output],
|
|
false
|
|
),
|
|
{
|
|
stdio: 'inherit',
|
|
}
|
|
),
|
|
];
|
|
case 3:
|
|
_a.sent();
|
|
if (!(targetPlatform === 'macos')) return [3 /*break*/, 5];
|
|
// Newer versions of Apple Clang automatically ad-hoc sign the compiled executable.
|
|
// However, for final executable to be signable, base binary MUST NOT have an existing signature.
|
|
return [
|
|
4 /*yield*/,
|
|
(0, utils_1.spawn)('codesign', ['--remove-signature', output], {
|
|
stdio: 'inherit',
|
|
}),
|
|
];
|
|
case 4:
|
|
// Newer versions of Apple Clang automatically ad-hoc sign the compiled executable.
|
|
// However, for final executable to be signable, base binary MUST NOT have an existing signature.
|
|
_a.sent();
|
|
_a.label = 5;
|
|
case 5:
|
|
return [2 /*return*/, output];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function compile(nodeVersion, targetArch, targetPlatform) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var win;
|
|
return __generator(this, function (_a) {
|
|
log_1.log.info('Compiling Node.js from sources...');
|
|
win = system_1.hostPlatform === 'win';
|
|
if (win) {
|
|
return [
|
|
2 /*return*/,
|
|
compileOnWindows(nodeVersion, targetArch, targetPlatform),
|
|
];
|
|
}
|
|
return [
|
|
2 /*return*/,
|
|
compileOnUnix(nodeVersion, targetArch, targetPlatform),
|
|
];
|
|
});
|
|
});
|
|
}
|
|
function build(nodeVersion, targetArch, targetPlatform, local) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var output, outputHash;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
return [4 /*yield*/, fs_extra_1.default.remove(buildPath)];
|
|
case 1:
|
|
_a.sent();
|
|
return [4 /*yield*/, fs_extra_1.default.mkdirp(nodePath)];
|
|
case 2:
|
|
_a.sent();
|
|
return [4 /*yield*/, fs_extra_1.default.mkdirp(nodeArchivePath)];
|
|
case 3:
|
|
_a.sent();
|
|
return [4 /*yield*/, tarFetch(nodeVersion)];
|
|
case 4:
|
|
_a.sent();
|
|
return [4 /*yield*/, tarExtract(nodeVersion)];
|
|
case 5:
|
|
_a.sent();
|
|
return [4 /*yield*/, applyPatches(nodeVersion)];
|
|
case 6:
|
|
_a.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
compile(nodeVersion, targetArch, targetPlatform),
|
|
];
|
|
case 7:
|
|
output = _a.sent();
|
|
return [4 /*yield*/, (0, utils_1.hash)(output)];
|
|
case 8:
|
|
outputHash = _a.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.mkdirp(path_1.default.dirname(local)),
|
|
];
|
|
case 9:
|
|
_a.sent();
|
|
return [4 /*yield*/, fs_extra_1.default.copy(output, local)];
|
|
case 10:
|
|
_a.sent();
|
|
return [
|
|
4 /*yield*/,
|
|
fs_extra_1.default.promises.writeFile(
|
|
local + '.sha256sum',
|
|
outputHash + ' ' + path_1.default.basename(local) + '\n'
|
|
),
|
|
];
|
|
case 11:
|
|
_a.sent();
|
|
return [4 /*yield*/, fs_extra_1.default.remove(buildPath)];
|
|
case 12:
|
|
_a.sent();
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
exports.default = build;
|
|
//# sourceMappingURL=build.js.map
|