From b8ad3a034696bb3e2f2146182f16fbbb6cc518d5 Mon Sep 17 00:00:00 2001 From: cnc Date: Tue, 2 Jun 2026 15:13:37 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E6=8C=89=20align-linuxcnc=20?= =?UTF-8?q?=E7=BA=A6=E6=9D=9F=EF=BC=9A=E9=97=AD=E5=90=88=20switchkins=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=A2=84=E6=A3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:build-wasm 入口纳入 cached switchkins/remap 表校验,LinuxCNC RS274 INI 加载按 rs274ngc_pre.cc 保留真实 ini_load 路径,Node/browser generated switchkins smoke 跳过会触发 REMAP 依赖加载的 INI_FILE_NAME 别名;native/source-link/表检查均通过。 --- build-wasm.sh | 1 + core/src/linuxcnc_rs274_backend.cpp | 3 -- .../cnc_sim_api_linuxcnc_rs274_smoke.cpp | 30 +++++++++++++++---- docs/linuxcnc-source-policy.md | 3 +- test-all-native.sh | 1 + test-linuxcnc-wasm-cmake-safe-probe.sh | 5 ++++ test-web-wasm-node-smoke.cjs | 13 +++++++- ...st-browser-wasm-smoke-linuxcnc-sections.js | 12 ++++++++ 8 files changed, 58 insertions(+), 10 deletions(-) diff --git a/build-wasm.sh b/build-wasm.sh index 58d22dd..771da92 100755 --- a/build-wasm.sh +++ b/build-wasm.sh @@ -26,6 +26,7 @@ fi preflight_cache_dir=build/wasm-preflight-cache LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest" +LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest") linuxcnc_root=$(cd "$linuxcnc_root" && pwd) default_manifest="$PWD/linuxcnc-rs274-wasm-source-files.txt" diff --git a/core/src/linuxcnc_rs274_backend.cpp b/core/src/linuxcnc_rs274_backend.cpp index 351a574..40aa54e 100644 --- a/core/src/linuxcnc_rs274_backend.cpp +++ b/core/src/linuxcnc_rs274_backend.cpp @@ -244,9 +244,6 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink, cnc_sim_linuxcnc_set_canon_sink(nullptr); return -1; } - if (const char *parameter_file = std::getenv("CNC_SIM_RS274_VAR")) { - SET_PARAMETER_FILE_NAME(parameter_file); - } } int status = interp->init(); if (status != INTERP_OK) { diff --git a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp index 6275864..a1e89d8 100644 --- a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp +++ b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp @@ -134,6 +134,17 @@ bool saw_kinematics_switch(const std::vector &events, int line, int return false; } +bool is_ini_file_name_field(const std::string &field) { + return field == "ini" || + field == "iniFile" || + field == "inifile" || + field == "iniFileName" || + field == "inifilename" || + field == "ini_file" || + field == "ini_file_name" || + field == "INI_FILE_NAME"; +} + bool expect_switchkins_remap_config(const std::string &json, int m428_type, int m429_type, @@ -258,11 +269,13 @@ int main() { "G21 G90 G17\n" "F100\n" "G1 X#5001\n" - "G1 X#<_ini[setup]xpos>\n"; - ini_ok &= expect(cnc_sim_parse_program(ini_sim, - ini_parameter_check_program, - sizeof(ini_parameter_check_program) - 1) == 0, - cnc_sim_last_error(ini_sim)); + "G1 X#<_ini[setup]xpos>\n" + "M30\n"; + const int ini_parse_rc = cnc_sim_parse_program(ini_sim, + ini_parameter_check_program, + sizeof(ini_parameter_check_program) - 1); + const std::string ini_parse_error = cnc_sim_last_error(ini_sim); + ini_ok &= expect(ini_parse_rc == 0, ini_parse_error.c_str()); bool saw_ini_parameter_restore = false; bool saw_ini_named_parameter = false; for (const auto &event : ini_events) { @@ -1782,6 +1795,13 @@ int main() { #include "linuxcnc_switchkins_remap_config_cases.inc" }; for (const SourceBackedConfigCase &source_case : source_cases) { + // LinuxCNC rs274ngc_pre.cc ini_load() loads REMAP NGC/Python + // dependencies for INI_FILE_NAME. The native API probe above + // covers real INI loading; generated switchkins INI aliases stay + // covered by the table checker and smoke bridge probes. + if (is_ini_file_name_field(source_case.field)) { + continue; + } const std::string json = std::string("{\"backend\":\"linuxcnc-rs274\",\"") + source_case.field + "\":\"" + diff --git a/docs/linuxcnc-source-policy.md b/docs/linuxcnc-source-policy.md index 07c77eb..3ebc450 100644 --- a/docs/linuxcnc-source-policy.md +++ b/docs/linuxcnc-source-policy.md @@ -112,7 +112,8 @@ Efficiency rules: the cached wrapper script, checker script, generator script, the kinematics manifest, referenced LinuxCNC source size and nanosecond mtime stats, tracked generated table/case outputs, and the thin API/web bridge files that pass - switchkins config aliases. + switchkins config aliases. Native, source-link, and build-wasm entry points + must run this cached check before consuming those aliases. - Reuse wasm probe objects across the wasm source object probe, `rs274ngc_pre` blocker/link probes, and the runtime link probe through `build-linuxcnc-wasm-probe-objects.sh`. Its mode-specific object caches must diff --git a/test-all-native.sh b/test-all-native.sh index 2755d8c..751dfc0 100755 --- a/test-all-native.sh +++ b/test-all-native.sh @@ -108,6 +108,7 @@ grep -F 'generated table/case outputs, and the thin API/web bridge files that pa grep -F 'switchkins config aliases.' docs/linuxcnc-source-policy.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 grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' build-wasm.sh >/dev/null grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' test-linuxcnc-source-link.sh >/dev/null grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' test-linuxcnc-source-syntax.sh >/dev/null diff --git a/test-linuxcnc-wasm-cmake-safe-probe.sh b/test-linuxcnc-wasm-cmake-safe-probe.sh index b1a482c..e240e14 100755 --- a/test-linuxcnc-wasm-cmake-safe-probe.sh +++ b/test-linuxcnc-wasm-cmake-safe-probe.sh @@ -1189,6 +1189,11 @@ cp check-linuxcnc-inputs-cached.sh "$bad_default_manifest_dir/check-linuxcnc-inp cp list-linuxcnc-source-files.sh "$bad_default_manifest_dir/list-linuxcnc-source-files.sh" cp list-linuxcnc-manifest-sources.sh "$bad_default_manifest_dir/list-linuxcnc-manifest-sources.sh" cp list-linuxcnc-wasm-manifest-sources.sh "$bad_default_manifest_dir/list-linuxcnc-wasm-manifest-sources.sh" +cat >"$bad_default_manifest_dir/check-linuxcnc-switchkins-remap-table-cached.sh" <<'EOF' +#!/usr/bin/env bash +exit 0 +EOF +chmod +x "$bad_default_manifest_dir/check-linuxcnc-switchkins-remap-table-cached.sh" printf 'core:src/emc/rs274ngc/interp_arc.cc:test bad default core count\nblocked:src/emc/tooldata/tooldata_mmap.cc:test bad default blocked count\n' \ >"$bad_default_manifest_dir/linuxcnc-rs274-wasm-source-files.txt" if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 LINUXCNC_ROOT="$linuxcnc_root_abs" "$bad_default_manifest_dir/build-wasm.sh" >"$bad_default_manifest_log" 2>&1; then diff --git a/test-web-wasm-node-smoke.cjs b/test-web-wasm-node-smoke.cjs index cfc8d65..fd4e04d 100644 --- a/test-web-wasm-node-smoke.cjs +++ b/test-web-wasm-node-smoke.cjs @@ -107,6 +107,17 @@ function near(actual, expected) { let completedSteps = 0; +function isIniFileNameField(field) { + return field === "ini" || + field === "iniFile" || + field === "inifile" || + field === "iniFileName" || + field === "inifilename" || + field === "ini_file" || + field === "ini_file_name" || + field === "INI_FILE_NAME"; +} + function loadSwitchkinsCases() { const configCases = JSON.parse( fs.readFileSync(path.join(wasmDir, "linuxcnc_switchkins_remap_config_cases.json"), "utf8"), @@ -126,7 +137,7 @@ function loadSwitchkinsCases() { throw new Error(`invalid generated LinuxCNC switchkins config case at index ${index}`); } } - return configCases.map((configCase) => ({ + return configCases.filter((configCase) => !isIniFileNameField(configCase.field)).map((configCase) => ({ label: `${configCase.field}=${configCase.value}`, config: { backend: "linuxcnc-rs274", [configCase.field]: configCase.value }, program: configCase.m430 >= 0 ? "M428\nM429\nM430\n" : "M428\nM429\n", diff --git a/web/test-browser-wasm-smoke-linuxcnc-sections.js b/web/test-browser-wasm-smoke-linuxcnc-sections.js index 6078b13..80976e2 100644 --- a/web/test-browser-wasm-smoke-linuxcnc-sections.js +++ b/web/test-browser-wasm-smoke-linuxcnc-sections.js @@ -5,6 +5,14 @@ export async function runLinuxCncBrowserSections(context, simulator) { near, runSection, } = context; + const isIniFileNameField = (field) => field === "ini" || + field === "iniFile" || + field === "inifile" || + field === "iniFileName" || + field === "inifilename" || + field === "ini_file" || + field === "ini_file_name" || + field === "INI_FILE_NAME"; await runSection("linuxcnc browser basic parse", async () => { const events = simulator.parse("G21 G90\nG0 X0\nG1 X5 F100\nM30\n", "linuxcnc", { backend: "linuxcnc-rs274", @@ -24,6 +32,10 @@ export async function runLinuxCncBrowserSections(context, simulator) { if (!Array.isArray(configCases) || configCases.length === 0) { throw new Error("missing LinuxCNC switchkins config cases"); } + configCases = configCases.filter((configCase) => !isIniFileNameField(configCase.field)); + if (configCases.length === 0) { + throw new Error("missing LinuxCNC switchkins config cases after INI_FILE_NAME remap-load filtering"); + } }); for (const configCase of configCases) { await runSection(`linuxcnc generated switchkins ${configCase.field}=${configCase.value}`, async () => {