mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Runtime packs: variants of a unit that do not read their defines, and flavors that compile a unit the same way, produce identical objects and bitcode. The pack build now points those manifest entries at one file (shareIdenticalArtifacts) and deletes the copies. Each link selects one flavor and one variant per unit, so no link names a shared file twice. The linux-x64-gnu pack keeps 1,191 of its 1,448 artifact files. Native CLI packages: - The comptime evaluator builds with -g0 and the executable strip flags, and the Windows build no longer ships its .pdb. - The copied tsc-ts executable is stripped with llvm-strip, which rewrites the linker-signed code signature of Mach-O executables. - On arm64 macOS, verify-native-cli.mjs --run checks the code signatures of the compiler, tsc-ts and the comptime evaluator. - SCRIPTC_NATIVE_KEEP_SYMBOLS=1 keeps the symbols of all three. - The copied runtime sources and declarations get LF line endings. A Windows checkout converts them to CRLF, so the Windows CLI shipped files that differed from @scriptc/runtime's.
80 lines
3.2 KiB
TypeScript
80 lines
3.2 KiB
TypeScript
import { existsSync } from "node:fs";
|
|
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join } from "node:path";
|
|
import { expect, test } from "vitest";
|
|
import { shareIdenticalArtifacts } from "../scripts/share-artifacts.mjs";
|
|
|
|
type Artifact = { path: string; sha256: string; size: number; bitcode?: Artifact };
|
|
|
|
async function artifact(root: string, path: string, sha256: string): Promise<Artifact> {
|
|
await mkdir(dirname(join(root, path)), { recursive: true });
|
|
await writeFile(join(root, path), sha256);
|
|
return { path, sha256, size: sha256.length };
|
|
}
|
|
|
|
test("identical artifacts of one unit share the first flavor's file", async () => {
|
|
const root = await mkdtemp(join(tmpdir(), "scriptc-share-artifacts-"));
|
|
try {
|
|
const unit = async (flavor: string, source: string, ids: Record<string, string>) => ({
|
|
source,
|
|
variants: await Promise.all(
|
|
Object.entries(ids).map(async ([id, sha]) => ({
|
|
id,
|
|
...(await artifact(root, `artifacts/${flavor}/runtime/${id}/${source}.o`, sha)),
|
|
})),
|
|
),
|
|
});
|
|
const release = {
|
|
runtime_units: [
|
|
await unit("release", "scr_a", { default: "a1", "default-workers": "a1" }),
|
|
await unit("release", "scr_b", { default: "b1" }),
|
|
],
|
|
};
|
|
release.runtime_units[1]!.variants[0]!.bitcode = await artifact(
|
|
root,
|
|
"artifacts/release/runtime/default/scr_b.bc",
|
|
"b-bitcode",
|
|
);
|
|
const speed = {
|
|
runtime_units: [
|
|
await unit("speed", "scr_a", { default: "a2" }),
|
|
// The same bytes as another unit's object stay a separate file.
|
|
await unit("speed", "scr_b", { default: "b1", other: "a1" }),
|
|
],
|
|
};
|
|
speed.runtime_units[1]!.variants[0]!.bitcode = await artifact(
|
|
root,
|
|
"artifacts/speed/runtime/default/scr_b.bc",
|
|
"b-bitcode",
|
|
);
|
|
const flavors = { release, speed };
|
|
await shareIdenticalArtifacts(flavors, root);
|
|
const paths = (flavor: typeof release) =>
|
|
flavor.runtime_units.map((unit) =>
|
|
unit.variants.map((variant: Artifact) => [variant.path, variant.bitcode?.path]),
|
|
);
|
|
expect(paths(release)).toEqual([
|
|
[
|
|
["artifacts/release/runtime/default/scr_a.o", undefined],
|
|
["artifacts/release/runtime/default/scr_a.o", undefined],
|
|
],
|
|
[["artifacts/release/runtime/default/scr_b.o", "artifacts/release/runtime/default/scr_b.bc"]],
|
|
]);
|
|
expect(paths(speed)).toEqual([
|
|
[["artifacts/speed/runtime/default/scr_a.o", undefined]],
|
|
[
|
|
["artifacts/release/runtime/default/scr_b.o", "artifacts/release/runtime/default/scr_b.bc"],
|
|
["artifacts/speed/runtime/other/scr_b.o", undefined],
|
|
],
|
|
]);
|
|
expect(existsSync(join(root, "artifacts/release/runtime/default-workers"))).toBe(false);
|
|
expect(existsSync(join(root, "artifacts/speed/runtime/default/scr_b.o"))).toBe(false);
|
|
expect(existsSync(join(root, "artifacts/speed/runtime/default/scr_b.bc"))).toBe(false);
|
|
expect(existsSync(join(root, "artifacts/speed/runtime/default/scr_a.o"))).toBe(true);
|
|
expect(existsSync(join(root, "artifacts/speed/runtime/other/scr_b.o"))).toBe(true);
|
|
} finally {
|
|
await rm(root, { recursive: true, force: true });
|
|
}
|
|
});
|