mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-02 08:35:07 +08:00
* feat: ship the self-hosted native scriptc CLI - Run the shared compiler and CLI natively, including library builds and compile-time evaluation. - Install native platform packages and ship relocatable standalone distributions. - Preserve program semantics and reuse validated build artifacts for fast rebuilds. * fix: complete native CLI integration and validation - Preserve library diagnostics and run recursive compiler work on the main stack. - Restore packaged helper permissions and exercise native npm and Wasm library builds. - Recover interrupted Sandbox status probes within the original command deadline.
51 lines
2.4 KiB
TypeScript
51 lines
2.4 KiB
TypeScript
/** Native tool invocation without a JavaScript host or shell command construction. */
|
|
import { execFileSync } from "node:child_process";
|
|
import { readFileSync, statSync } from "node:fs";
|
|
import type { NativeHelperSpec, NativeTargetSpec } from "./targets.js";
|
|
import { validateNativeCodegenVersion, type NativeCodegenOutputKind } from "./native-codegen-core.js";
|
|
|
|
export function runNativeTool(executable: string, args: string[], cwd?: string, env?: NodeJS.ProcessEnv): string {
|
|
return execFileSync(executable, args, { encoding: "utf8", stdio: "pipe", maxBuffer: 64 * 1024 * 1024,
|
|
cwd: cwd ?? process.cwd(), env: env ?? process.env });
|
|
}
|
|
|
|
export function requireNativeArtifact(path: string): void {
|
|
const info = statSync(path);
|
|
if (!info.isFile() || info.size === 0) throw new Error(`native tool produced no artifact: ${path}`);
|
|
}
|
|
|
|
export function emitNativeObject(options: {
|
|
executable: string;
|
|
packageRoot: string;
|
|
compilerVersion: string;
|
|
target: NativeTargetSpec;
|
|
helper: NativeHelperSpec;
|
|
inputPath: string;
|
|
outputPath: string;
|
|
sourcePath: string;
|
|
optimization: "release" | "dev";
|
|
outputKind?: NativeCodegenOutputKind;
|
|
}): void {
|
|
verifyNativeHelper(options);
|
|
runNativeTool(options.executable, [
|
|
"emit", "--input", options.inputPath, "--output", options.outputPath, "--filetype", options.outputKind ?? "obj",
|
|
"--target", options.target.llvmTriple, "--opt-level", options.optimization === "dev" ? "0" : "2",
|
|
"--relocation-model", options.target.relocationModel, "--diagnostic-format", "json",
|
|
"--source-path", options.sourcePath,
|
|
]);
|
|
requireNativeArtifact(options.outputPath);
|
|
}
|
|
|
|
/** Verify installed identity even when a caller can reuse a cached object. */
|
|
export function verifyNativeHelper(options: {
|
|
executable: string; packageRoot: string; compilerVersion: string;
|
|
target: NativeTargetSpec; helper: NativeHelperSpec;
|
|
}): void {
|
|
const identity = JSON.parse(readFileSync(options.packageRoot + "/package.json", "utf8")) as { name: string; version: string };
|
|
if (identity.name !== options.helper.packageName || identity.version !== options.compilerVersion) {
|
|
throw new Error(`LLVM helper package mismatch: expected ${options.helper.packageName}@${options.compilerVersion}`);
|
|
}
|
|
const version = JSON.parse(runNativeTool(options.executable, ["version", "--format=json"])) as Record<string, unknown>;
|
|
validateNativeCodegenVersion(version, options.target, options.helper, options.compilerVersion);
|
|
}
|