Files
cnc_wams/wasm-port/tools/generate_hal_component_sources.mjs
2026-07-10 21:26:42 -04:00

73 lines
2.7 KiB
JavaScript
Executable File

#!/usr/bin/env node
import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const upstream = path.resolve(root, "../linuxcnc");
const generator = path.join(upstream, "bin/halcompile");
const outDir = path.join(root, "build/generated/hal-components");
const components = ["and2", "or2", "not", "mux2", "scale"];
const sha256 = (data) => crypto.createHash("sha256").update(data).digest("hex");
const baseline = fs.readFileSync(path.join(root, "tools/upstream-baseline.txt"), "utf8").trim();
const head = spawnSync("git", ["-C", upstream, "rev-parse", "HEAD"], { encoding: "utf8" });
assert.equal(head.status, 0, head.stderr);
assert.equal(head.stdout.trim(), baseline, "LinuxCNC baseline drift");
fs.mkdirSync(outDir, { recursive: true });
const generatorSha256 = sha256(fs.readFileSync(generator));
const rows = [];
for (const component of components) {
const sourcePath = `vendor/linuxcnc/src/hal/components/${component}.comp`;
const generatedPath = `build/generated/hal-components/${component}.c`;
const source = path.join(root, sourcePath);
const generated = path.join(root, generatedPath);
const result = spawnSync(generator, ["--preprocess", "-o", generated, sourcePath], {
cwd: root,
encoding: "utf8",
});
assert.equal(result.status, 0, result.stderr || result.stdout);
const normalized = `${fs
.readFileSync(generated, "utf8")
.replace(/^\/\* Autogenerated by .*? -- do not edit \*\//, "/* Autogenerated by locked LinuxCNC halcompile -- do not edit */")}
int halcomp_${component}_start(char *instance_names, int instance_count) {
names = instance_names;
count = instance_count;
int result = rtapi_app_main();
names = "";
count = 0;
return result;
}
void halcomp_${component}_reset(void) {
__comp_first_inst = NULL;
__comp_last_inst = NULL;
names = "";
count = 0;
}
`;
fs.writeFileSync(generated, normalized);
rows.push({
component,
sourcePath,
sourceSha256: sha256(fs.readFileSync(source)),
generatedPath,
generatedSha256: sha256(normalized),
generator: "../linuxcnc/bin/halcompile --preprocess",
generatorSha256,
commandFingerprint: sha256(`halcompile:${generatorSha256}:--preprocess:${sourcePath}`),
});
}
const report = {
apiName: "hal_component_generation_report",
schemaVersion: 1,
upstreamCommit: baseline,
components: rows,
};
fs.writeFileSync(path.join(outDir, "generation-report.json"), `${JSON.stringify(report, null, 2)}\n`);
console.log(`hal_component_generated_count=${rows.length}`);
console.log("hal_component_generation=ok");