继续按 align-linuxcnc 约束:闭合 switchkins 构建预检

结论: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/表检查均通过。
This commit is contained in:
cnc
2026-06-02 15:13:37 +08:00
parent 0abf801856
commit b8ad3a0346
8 changed files with 58 additions and 10 deletions

View File

@@ -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"

View File

@@ -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) {

View File

@@ -134,6 +134,17 @@ bool saw_kinematics_switch(const std::vector<CncSimEvent> &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 +
"\":\"" +

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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",

View File

@@ -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 () => {