From abd96dfdde47e8a6eed55312df300c640b4f23fe Mon Sep 17 00:00:00 2001 From: cnc Date: Thu, 4 Jun 2026 16:37:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=82=E8=80=83=E6=89=80=E6=9C=89=E5=88=86?= =?UTF-8?q?=E7=BB=84=EF=BC=8C=E5=AE=8C=E6=88=90=E5=B0=BD=E9=87=8F=E5=A4=9A?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9=E3=80=82=E7=A6=81=E6=AD=A2=E9=A1=BA?= =?UTF-8?q?=E6=89=8B=E6=89=A9=E5=8A=9F=E8=83=BD=20smoke=EF=BC=9A=E9=94=81?= =?UTF-8?q?=E5=AE=9A=E6=9E=84=E5=BB=BA=E6=BA=90=E7=A0=81=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E7=BB=93=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check-linuxcnc-build-source-map.sh | 179 +++++++++++++++++++++++++++++ docs/linuxcnc-build-source-map.md | 62 ++++++++++ test-all-native.sh | 6 + test-linuxcnc-source-link.sh | 1 + test-native.sh | 1 + 5 files changed, 249 insertions(+) create mode 100755 check-linuxcnc-build-source-map.sh create mode 100644 docs/linuxcnc-build-source-map.md diff --git a/check-linuxcnc-build-source-map.sh b/check-linuxcnc-build-source-map.sh new file mode 100755 index 0000000..9958faa --- /dev/null +++ b/check-linuxcnc-build-source-map.sh @@ -0,0 +1,179 @@ +#!/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 or expand smoke parsing. +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 'LinuxCNC source basis: the wasm build preflights and compiles the' build-wasm.sh >/dev/null +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", +]: + 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 diff --git a/docs/linuxcnc-build-source-map.md b/docs/linuxcnc-build-source-map.md new file mode 100644 index 0000000..28693cc --- /dev/null +++ b/docs/linuxcnc-build-source-map.md @@ -0,0 +1,62 @@ +# LinuxCNC build source map + +This map records the source basis and boundaries for native, source-link, and +WASM build entry points. It is a build-policy guard only; it must not add CNC +behavior and must not expand the temporary smoke parser. + +## LinuxCNC Source Basis + +- `src/emc/rs274ngc/Submakefile` defines `LIBRS274SRCS`, including + `rs274ngc_pre.cc`, and links RS274 against LinuxCNC INI, HAL, Python plugin, + and tooldata libraries. +- `src/emc/tooldata/Submakefile` defines the LinuxCNC tooldata common, mmap, + NML, database, reader, and watcher sources tracked by native and WASM + manifests. +- `src/emc/ini/Submakefile` defines `liblinuxcncini` and exported INI headers + used by source-linked and WASM-safe probes. +- `src/emc/pythonplugin/Submakefile` defines `libpyplugin`, which remains a + source-tracked Python/remap dependency for source-link and WASM blocker + coverage. +- `src/emc/kinematics/Submakefile` and `src/emc/kinematics/kinematics.h` + define the kinematics source/header surface consumed by switchkins and RTCP + build coverage. + +## Build Coverage + +| Entry | Boundary | +| --- | --- | +| `test-native.sh` | Runs source-map guards, cached manifest checks, native bridge/API/RS274 probes, and Node/browser smoke after LinuxCNC source-backed native coverage. | +| `test-linuxcnc-source-link.sh` | Compiles manifest-selected LinuxCNC RS274 objects directly with source-link support objects and project dump bridges. | +| `test-linuxcnc-source-syntax.sh` | Keeps native source syntax validation on persistent dependency-tracked stamps. | +| `test-linuxcnc-wasm-cmake-safe-probe.sh` | Configures source-backed WASM-safe probe targets with persistent CMake signatures. | +| `build-wasm.sh` | Runs blocker, syntax, object, CMake, tooldata, interp, Python, `rs274ngc_pre`, and runtime probes before copying browser artifacts. | + +## Boundaries + +- Default WASM manifest partition must remain 26 wasm-safe `core` sources and + 9 `blocked` sources. +- Build paths must keep `CNC_SIM_BUILD_JOBS` as scheduling only. Persistent + object/configure signatures must not include it. +- Hot object probes must use explicit `BUILD_RULE_VERSION` or + `CONFIGURE_RULE_VERSION` fields instead of hashing whole scripts. +- `build-wasm.sh` must configure with `CNC_SIM_ENABLE_SMOKE_BACKEND=OFF` and + `CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE=ON`. +- `build-wasm.sh` must build `cnc_sim_wasm_runtime_probe` before + `cnc_sim_wasm`, copy `cnc_sim.js` and `cnc_sim.wasm` exactly once, compare + copied artifacts with `cmp -s`, and run Node smoke before browser smoke. +- Build directory overrides must be non-empty, whitespace-free, and outside the + filesystem root. + +## Checks + +Run: + +```bash +./check-linuxcnc-build-source-map.sh +./test-native.sh +./test-linuxcnc-source-link.sh +``` + +`check-linuxcnc-build-source-map.sh` keeps this document, LinuxCNC build-source +anchors, manifest partition assumptions, build script ordering, and +source-backed build-policy boundaries synchronized. diff --git a/test-all-native.sh b/test-all-native.sh index 0b3d9e6..581e2e9 100755 --- a/test-all-native.sh +++ b/test-all-native.sh @@ -153,6 +153,9 @@ grep -F './check-linuxcnc-switchkins-remap-source-map.sh' test-linuxcnc-source-l grep -F 'LinuxCNC source basis: this guard ties Node/browser WASM smoke coverage' check-linuxcnc-wasm-smoke-source-map.sh >/dev/null grep -F './check-linuxcnc-wasm-smoke-source-map.sh' test-native.sh >/dev/null grep -F './check-linuxcnc-wasm-smoke-source-map.sh' test-linuxcnc-source-link.sh >/dev/null +grep -F 'LinuxCNC source basis: this guard ties native/source-link/WASM build entry' check-linuxcnc-build-source-map.sh >/dev/null +grep -F './check-linuxcnc-build-source-map.sh' test-native.sh >/dev/null +grep -F './check-linuxcnc-build-source-map.sh' test-linuxcnc-source-link.sh >/dev/null grep -F 'LinuxCNC source basis: this guard ties the documented WASM blocker map' check-linuxcnc-wasm-blockers-source-map.sh >/dev/null grep -F 'LinuxCNC source basis: this guard ties the documented wasm-safe shim map' check-linuxcnc-wasm-shims-source-map.sh >/dev/null grep -F 'LinuxCNC source basis: the cached input checker keys check-linuxcnc-inputs.sh' check-linuxcnc-inputs-cached.sh >/dev/null @@ -236,6 +239,9 @@ grep -F 'must not expand the temporary smoke parser' docs/linuxcnc-wasm-shims-so grep -F 'LinuxCNC WASM smoke source map' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null grep -F 'Node smoke must leave OPFS disabled' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null grep -F 'Generated switchkins config smoke cases must continue to come from' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null +grep -F 'LinuxCNC build source map' docs/linuxcnc-build-source-map.md >/dev/null +grep -F 'Default WASM manifest partition must remain 26 wasm-safe `core` sources' 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 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' test-native.sh >/dev/null grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' test-linuxcnc-source-link.sh >/dev/null grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' build-wasm.sh >/dev/null diff --git a/test-linuxcnc-source-link.sh b/test-linuxcnc-source-link.sh index 3e8d42c..c350022 100755 --- a/test-linuxcnc-source-link.sh +++ b/test-linuxcnc-source-link.sh @@ -38,6 +38,7 @@ LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$p ./check-linuxcnc-switchkins-remap-source-map.sh ./check-linuxcnc-wasm-smoke-source-map.sh +./check-linuxcnc-build-source-map.sh LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt # The LinuxCNC source-linked dump path is not concurrency-safe under parallel execution. exec 9>"${TMPDIR:-/tmp}/cnc_sim_rs274_source_link.lock" diff --git a/test-native.sh b/test-native.sh index 53301cc..d0db353 100755 --- a/test-native.sh +++ b/test-native.sh @@ -39,6 +39,7 @@ preflight_cache_dir="$build_dir/preflight-cache" ./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-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt grep -F 'tooldata:src/emc/tooldata/tooldata_nml.cc:NML tool table backend selected by LinuxCNC TOOL_NML_FLAG' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'tooldata:src/emc/tooldata/tool_mmap_read.cc:LinuxCNC tooldata mmap reader utility source from tooldata Submakefile' linuxcnc-rs274-source-files.txt >/dev/null