Files
wasm-simulator/check-linuxcnc-build-source-map.sh

203 lines
10 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
# LinuxCNC source basis: this guard ties native/source-link/WASM build entry
# points to LinuxCNC Submakefile source ownership, source manifests, persistent
# build signatures, and source-backed WASM artifact ordering. It validates
# build policy only; it does not add CNC behavior, expand smoke parsing, or
# interpret G-code.
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
grep -F 'LIBRS274SRCS := $(addprefix emc/rs274ngc/,' \
"$linuxcnc_root/src/emc/rs274ngc/Submakefile" >/dev/null
grep -F 'rs274ngc_pre.cc \' "$linuxcnc_root/src/emc/rs274ngc/Submakefile" >/dev/null
grep -F '../lib/libtooldata.so.0' "$linuxcnc_root/src/emc/rs274ngc/Submakefile" >/dev/null
grep -F 'LIBTOOLDATA_SRCS += emc/tooldata/tooldata_common.cc' \
"$linuxcnc_root/src/emc/tooldata/Submakefile" >/dev/null
grep -F 'LIBTOOLDATA_SRCS += emc/tooldata/tooldata_mmap.cc' \
"$linuxcnc_root/src/emc/tooldata/Submakefile" >/dev/null
grep -F 'LIBTOOLDATA_SRCS += emc/tooldata/tooldata_db.cc' \
"$linuxcnc_root/src/emc/tooldata/Submakefile" >/dev/null
grep -F 'LIBLCNCINISRCS := emc/ini/inifile.cc' \
"$linuxcnc_root/src/emc/ini/Submakefile" >/dev/null
grep -F 'LIBPPSRCS := $(addprefix emc/pythonplugin/,' \
"$linuxcnc_root/src/emc/pythonplugin/Submakefile" >/dev/null
grep -F 'GENSERKINSSRCS := emc/kinematics/ugenserkins.c' \
"$linuxcnc_root/src/emc/kinematics/Submakefile" >/dev/null
grep -F 'extern int kinematicsInverse(const struct EmcPose * world,' \
"$linuxcnc_root/src/emc/kinematics/kinematics.h" >/dev/null
grep -F 'LinuxCNC build source map' docs/linuxcnc-build-source-map.md >/dev/null
grep -F 'must not add CNC' docs/linuxcnc-build-source-map.md >/dev/null
grep -F 'must not expand the temporary smoke parser' docs/linuxcnc-build-source-map.md >/dev/null
grep -F '`src/emc/rs274ngc/Submakefile` defines `LIBRS274SRCS`' \
docs/linuxcnc-build-source-map.md >/dev/null
grep -F '`src/emc/tooldata/Submakefile` defines the LinuxCNC tooldata' \
docs/linuxcnc-build-source-map.md >/dev/null
grep -F 'Default WASM manifest partition must remain 26 wasm-safe `core` sources and' \
docs/linuxcnc-build-source-map.md >/dev/null
grep -F '`build-wasm.sh` must configure with `CNC_SIM_ENABLE_SMOKE_BACKEND=OFF`' \
docs/linuxcnc-build-source-map.md >/dev/null
grep -F '`test-native.sh`, `test-linuxcnc-source-link.sh`, and `build-wasm.sh` must' \
docs/linuxcnc-build-source-map.md >/dev/null
grep -F 'LinuxCNC source basis: the wasm build preflights and compiles the' build-wasm.sh >/dev/null
source_map_guards=(
'./check-linuxcnc-rs274-source-map.sh'
'./check-linuxcnc-kinematics-source-map.sh'
'./check-linuxcnc-opfs-source-map.sh'
'./check-linuxcnc-switchkins-remap-source-map.sh'
'./check-linuxcnc-wasm-smoke-source-map.sh'
'./check-linuxcnc-build-source-map.sh'
'./check-linuxcnc-browser-app-source-map.sh'
'./check-linuxcnc-workstreams-source-map.sh'
'./check-linuxcnc-tooldata-source-map.sh'
'./check-linuxcnc-wasm-shims-source-map.sh'
'./check-linuxcnc-wasm-blockers-source-map.sh'
)
for guarded_entry in test-native.sh test-linuxcnc-source-link.sh build-wasm.sh; do
for source_map_guard in "${source_map_guards[@]}"; do
grep -F "$source_map_guard" "$guarded_entry" >/dev/null
done
done
grep -F 'manifest_core_count=$(count_nonempty_lines "$manifest_core_output")' build-wasm.sh >/dev/null
grep -F 'manifest_blocked_count=$(count_nonempty_lines "$manifest_blocked_output")' build-wasm.sh >/dev/null
grep -F 'manifest_core_count" -ne 26 || "$manifest_blocked_count" -ne 9' build-wasm.sh >/dev/null
grep -F 'run_parallel_wasm_probe "LinuxCNC wasm tooldata shim link probe" ./test-linuxcnc-wasm-tooldata-link.sh' build-wasm.sh >/dev/null
grep -F 'run_parallel_wasm_probe "LinuxCNC wasm rs274ngc_pre object probe" ./test-linuxcnc-wasm-rs274ngc-pre-object.sh' build-wasm.sh >/dev/null
grep -F 'wait_parallel_wasm_probes' build-wasm.sh >/dev/null
grep -F 'for required_tool in cmake emcmake emcc node; do' build-wasm.sh >/dev/null
grep -F 'CONFIGURE_RULE_VERSION=2' build-wasm.sh >/dev/null
grep -F -- '-DCNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE=ON' build-wasm.sh >/dev/null
grep -F -- '-DCNC_SIM_ENABLE_SMOKE_BACKEND=OFF' build-wasm.sh >/dev/null
grep -F 'cmake --build build/wasm --target cnc_sim_wasm_runtime_probe cnc_sim_wasm --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F 'cmp -s build/wasm/cnc_sim.js web/public/cnc_sim.js' build-wasm.sh >/dev/null
grep -F 'cmp -s build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm' build-wasm.sh >/dev/null
grep -F './test-web-wasm-node-smoke.sh' build-wasm.sh >/dev/null
grep -F './test-web-wasm-browser-smoke.sh' build-wasm.sh >/dev/null
grep -F 'LinuxCNC source basis: this source-link test compiles the manifest-selected' \
test-linuxcnc-source-link.sh >/dev/null
grep -F 'BUILD_RULE_VERSION=1' test-linuxcnc-source-link.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$source_link_makefile"' \
test-linuxcnc-source-link.sh >/dev/null
grep -F 'LinuxCNC source basis: this syntax probe checks the native RS274 manifest' \
test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'LinuxCNC source basis: the wasm syntax probe compiles the' \
test-linuxcnc-wasm-source-syntax.sh >/dev/null
grep -F "printf 'CONFIGURE_RULE_VERSION=1\n'" \
test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe cnc_sim_wasm_runtime_probe --parallel "$build_jobs"' \
test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
if grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' build-wasm.sh >/dev/null; then
echo "build-wasm configure signature must not depend on CNC_SIM_BUILD_JOBS" >&2
exit 1
fi
for hot_signature_script in \
build-linuxcnc-wasm-link-probe.sh \
build-linuxcnc-wasm-probe-objects.sh \
build-linuxcnc-wasm-standalone-probe.sh \
build-linuxcnc-native-bridge-objects.sh \
test-linuxcnc-api-native.sh \
test-linuxcnc-bridge-native.sh \
test-linuxcnc-rs274-native.sh \
test-linuxcnc-source-link.sh \
test-linuxcnc-source-objects.sh \
test-linuxcnc-source-syntax.sh \
test-native.sh; do
if grep -F "sha256sum $hot_signature_script" "$hot_signature_script" >/dev/null; then
echo "$hot_signature_script hot object signature must use BUILD_RULE_VERSION instead of the whole script hash" >&2
exit 1
fi
done
python3 - <<'PY'
from pathlib import Path
import subprocess
source_map = Path("docs/linuxcnc-build-source-map.md").read_text(encoding="utf-8")
wasm_manifest = Path("linuxcnc-rs274-wasm-source-files.txt")
core_count = len(subprocess.check_output(
["./list-linuxcnc-wasm-manifest-sources.sh", str(wasm_manifest), "core"],
text=True,
).splitlines())
blocked_count = len(subprocess.check_output(
["./list-linuxcnc-wasm-manifest-sources.sh", str(wasm_manifest), "blocked"],
text=True,
).splitlines())
if core_count != 26 or blocked_count != 9:
raise SystemExit(f"unexpected default WASM manifest partition: core={core_count} blocked={blocked_count}")
for entry in [
"test-native.sh",
"test-linuxcnc-source-link.sh",
"test-linuxcnc-source-syntax.sh",
"test-linuxcnc-wasm-cmake-safe-probe.sh",
"build-wasm.sh",
]:
if f"| `{entry}` |" not in source_map:
raise SystemExit(f"docs/linuxcnc-build-source-map.md missing build entry: {entry}")
for phrase in [
"must not add CNC",
"must not expand the temporary smoke parser",
"CNC_SIM_BUILD_JOBS",
"BUILD_RULE_VERSION",
"CONFIGURE_RULE_VERSION",
"CNC_SIM_ENABLE_SMOKE_BACKEND=OFF",
"Node smoke before browser smoke",
"does not interpret",
"G-code",
]:
if phrase not in source_map:
raise SystemExit(f"docs/linuxcnc-build-source-map.md missing boundary phrase: {phrase}")
build_wasm = Path("build-wasm.sh").read_text(encoding="utf-8").splitlines()
positions = {}
for index, line in enumerate(build_wasm, start=1):
if 'run_parallel_wasm_probe "LinuxCNC wasm tooldata shim link probe"' in line:
positions["parallel_start"] = index
if "wait_parallel_wasm_probes" in line and "parallel_start" in positions and "wait" not in positions:
positions["wait"] = index
if "LinuxCNC wasm rs274ngc_pre link blocker scan" in line:
positions["pre_link"] = index
if "for required_tool in cmake emcmake emcc node; do" in line:
positions["tools"] = index
if "emcmake cmake -S core -B build/wasm" in line:
positions["configure"] = index
if "cmake --build build/wasm --target cnc_sim_wasm_runtime_probe cnc_sim_wasm" in line:
positions["build"] = index
if "cp build/wasm/cnc_sim.js web/public/cnc_sim.js" in line:
positions["cp_js"] = index
if "cp build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm" in line:
positions["cp_wasm"] = index
if "cmp -s build/wasm/cnc_sim.js web/public/cnc_sim.js" in line:
positions["cmp_js"] = index
if "cmp -s build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm" in line:
positions["cmp_wasm"] = index
if "./test-web-wasm-node-smoke.sh" in line:
positions["node"] = index
if "./test-web-wasm-browser-smoke.sh" in line:
positions["browser"] = index
required = [
"parallel_start", "wait", "pre_link", "tools", "configure", "build",
"cp_js", "cp_wasm", "cmp_js", "cmp_wasm", "node", "browser",
]
missing = [name for name in required if name not in positions]
if missing:
raise SystemExit(f"build-wasm.sh missing ordered build anchors: {', '.join(missing)}")
if not (positions["parallel_start"] < positions["wait"] < positions["pre_link"]):
raise SystemExit("build-wasm.sh must wait for parallel probes before rs274ngc_pre link checks")
if not (positions["tools"] < positions["configure"] < positions["build"]):
raise SystemExit("build-wasm.sh must check tools, then configure, then build")
if not (positions["cp_js"] < positions["cmp_js"] < positions["node"] < positions["browser"]):
raise SystemExit("build-wasm.js artifact JS copy/compare or smoke ordering changed")
if not (positions["cp_wasm"] < positions["cmp_wasm"] < positions["node"] < positions["browser"]):
raise SystemExit("build-wasm.wasm artifact copy/compare or smoke ordering changed")
PY