第 6 组:源码链接、构建和文档约束闭环完成

This commit is contained in:
cnc
2026-06-01 06:11:08 +08:00
parent 1498d9830d
commit 4c55ab3435
43 changed files with 8414 additions and 636 deletions

View File

@@ -4,20 +4,47 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_cmake_safe_probe.XXXXXX")
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR-build/wasm-cmake-safe-probe}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not contain whitespace: $build_dir" >&2
exit 1
fi
mkdir -p "$build_dir"
build_dir=$(cd "$build_dir" && pwd)
if [[ "$build_dir" == "/" ]]; then
echo "CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
missing_manifest=${TMPDIR:-/tmp}/cnc_sim_missing_build_wasm_manifest.txt
missing_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_build_wasm_manifest.XXXXXX.log")
missing_root=/tmp/does-not-exist-linuxcnc
missing_root_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_build_wasm_missing_root.XXXXXX.log")
invalid_build_jobs_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_build_wasm_invalid_jobs.XXXXXX.log")
invalid_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_build_wasm_invalid_dir.XXXXXX.log")
empty_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_build_wasm_empty_dir.XXXXXX.log")
whitespace_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_build_wasm_whitespace_dir.XXXXXX.log")
cleanup_wasm_cmake_probe_temps() {
local temp_path
for temp_path in \
"$build_dir" \
"$missing_manifest" \
"$missing_manifest_log" \
"$missing_root_log" \
"$invalid_build_jobs_log" \
"$invalid_build_dir_log" \
"$empty_build_dir_log" \
"$whitespace_build_dir_log" \
"${build_next_signature:-}" \
"${unknown_manifest_filter_log:-}" \
"${unknown_manifest_output_log:-}" \
"${missing_shim_log:-}" \
@@ -62,6 +89,22 @@ cleanup_wasm_cmake_probe_temps() {
trap cleanup_wasm_cmake_probe_temps EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
build_signature="$build_dir/wasm-cmake-safe-probe.signature"
build_next_signature=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_cmake_safe_probe.signature.XXXXXX")
{
printf 'CXX=%s\n' "${CXX:-g++}"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'BUILD_JOBS=%s\n' "$build_jobs"
} > "$build_next_signature"
if [[ ! -f "$build_signature" ]] || ! cmp -s "$build_signature" "$build_next_signature"; then
rm -rf "$build_dir"
mkdir -p "$build_dir"
fi
mv "$build_next_signature" "$build_signature"
rm -f "$missing_manifest"
if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$missing_manifest" >"$missing_manifest_log" 2>&1; then
@@ -83,6 +126,43 @@ if ! grep -F "missing LinuxCNC root: $missing_root" "$missing_root_log" >/dev/nu
sed -n '1,20p' "$missing_root_log" >&2
exit 1
fi
if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 CNC_SIM_BUILD_JOBS=0 ./build-wasm.sh >"$invalid_build_jobs_log" 2>&1; then
echo "build-wasm accepted invalid CNC_SIM_BUILD_JOBS" >&2
exit 1
fi
if ! grep -F "CNC_SIM_BUILD_JOBS must be a positive integer: 0" "$invalid_build_jobs_log" >/dev/null; then
echo "build-wasm did not report invalid CNC_SIM_BUILD_JOBS clearly" >&2
sed -n '1,20p' "$invalid_build_jobs_log" >&2
exit 1
fi
if CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR=/ ./test-linuxcnc-wasm-cmake-safe-probe.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-wasm-cmake-safe-probe.sh accepted filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-wasm-cmake-safe-probe.sh did not report filesystem-root build dir clearly" >&2
sed -n '1,20p' "$invalid_build_dir_log" >&2
exit 1
fi
if CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR= ./test-linuxcnc-wasm-cmake-safe-probe.sh >"$empty_build_dir_log" 2>&1; then
echo "test-linuxcnc-wasm-cmake-safe-probe.sh accepted empty build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be empty" "$empty_build_dir_log" >/dev/null; then
echo "test-linuxcnc-wasm-cmake-safe-probe.sh did not report empty build dir clearly" >&2
sed -n '1,20p' "$empty_build_dir_log" >&2
exit 1
fi
if CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR="build/wasm safe probe" ./test-linuxcnc-wasm-cmake-safe-probe.sh >"$whitespace_build_dir_log" 2>&1; then
echo "test-linuxcnc-wasm-cmake-safe-probe.sh accepted whitespace in build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not contain whitespace: build/wasm safe probe" "$whitespace_build_dir_log" >/dev/null; then
echo "test-linuxcnc-wasm-cmake-safe-probe.sh did not report whitespace build dir clearly" >&2
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
grep -F 'exec 9>"${TMPDIR:-/tmp}/cnc_sim_build_wasm.lock"' build-wasm.sh >/dev/null
grep -F "flock 9" build-wasm.sh >/dev/null
grep -F -- './test-linuxcnc-wasm-blockers.sh "$manifest"' build-wasm.sh >/dev/null
@@ -207,9 +287,50 @@ grep -F -- 'for required_tool in cmake emcmake emcc node; do' build-wasm.sh >/de
grep -F -- 'missing_tools+=("$required_tool")' build-wasm.sh >/dev/null
grep -F "WASM build tools are required. Missing:" build-wasm.sh >/dev/null
grep -F "Install/activate cmake, emsdk, and Node.js so cmake, emcmake, emcc, and node are in PATH." build-wasm.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' build-wasm.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' build-wasm.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'build_dir=${CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR-build/wasm-cmake-safe-probe}' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be empty' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be the filesystem root' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'build_signature="$build_dir/wasm-cmake-safe-probe.signature"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'build_next_signature=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_cmake_safe_probe.signature.XXXXXX")' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'if [[ ! -f "$build_signature" ]] || ! cmp -s "$build_signature" "$build_next_signature"; then' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''LINUXCNC_ROOT=%s\n'\'' "$linuxcnc_root"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''MANIFEST=%s\n'\'' "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-native.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-native.sh >/dev/null
grep -F 'build_dir=${CNC_SIM_NATIVE_BUILD_DIR-build/native-test}' test-native.sh >/dev/null
grep -F 'CNC_SIM_NATIVE_BUILD_DIR must not be empty' test-native.sh >/dev/null
grep -F 'CNC_SIM_NATIVE_BUILD_DIR must not contain whitespace: $build_dir' test-native.sh >/dev/null
grep -F 'exec 9>"$build_dir/native-test.lock"' test-native.sh >/dev/null
grep -F 'native_signature="$build_dir/native-build.signature"' test-native.sh >/dev/null
grep -F 'if [[ ! -f "$native_signature" ]] || ! cmp -s "$native_signature" "$native_next_signature"; then' test-native.sh >/dev/null
grep -F 'printf '\''PWD=%s\n'\'' "$PWD"' test-native.sh >/dev/null
grep -F 'printf '\''\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n'\''' test-native.sh >/dev/null
grep -F 'printf '\''\n-include $(DEP_FILES)\n'\''' test-native.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$native_makefile"' test-native.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-source-link.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-source-link.sh >/dev/null
grep -F 'build_dir=${CNC_SIM_SOURCE_LINK_BUILD_DIR-build/source-link-test}' test-linuxcnc-source-link.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_LINK_BUILD_DIR must not be empty' test-linuxcnc-source-link.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_LINK_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-source-link.sh >/dev/null
grep -F 'source_link_signature="$build_dir/source-link-build.signature"' test-linuxcnc-source-link.sh >/dev/null
grep -F 'if [[ ! -f "$source_link_signature" ]] || ! cmp -s "$source_link_signature" "$source_link_next_signature"; then' test-linuxcnc-source-link.sh >/dev/null
grep -F 'printf '\''PWD=%s\n'\'' "$PWD"' test-linuxcnc-source-link.sh >/dev/null
grep -F 'printf '\''LINUXCNC_ROOT=%s\n'\'' "$(cd "$linuxcnc_root" && pwd)"' test-linuxcnc-source-link.sh >/dev/null
grep -F 'printf '\''\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n'\''' test-linuxcnc-source-link.sh >/dev/null
grep -F 'printf '\''\n-include $(DEP_FILES)\n'\''' 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 -- 'emcmake cmake -S core -B build/wasm \' build-wasm.sh >/dev/null
grep -F -- 'cmake --build build/wasm --target cnc_sim_wasm_runtime_probe' build-wasm.sh >/dev/null
grep -F -- 'cmake --build build/wasm --target cnc_sim_wasm' build-wasm.sh >/dev/null
grep -F -- 'cmake --build build/wasm --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F -- 'cmake --build build/wasm --target cnc_sim_wasm --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F -- 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe_objects --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F -- 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F -- 'cmake --build "$build_dir" --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F -- 'mkdir -p web/public' build-wasm.sh >/dev/null
grep -F -- 'cp build/wasm/cnc_sim.js web/public/cnc_sim.js' build-wasm.sh >/dev/null
grep -F -- 'cp build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm' build-wasm.sh >/dev/null
@@ -217,6 +338,41 @@ grep -F -- 'cmp -s build/wasm/cnc_sim.js web/public/cnc_sim.js' build-wasm.sh >/
grep -F -- 'cmp -s build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm' build-wasm.sh >/dev/null
grep -F -- 'node test-web-wasm-node-smoke.cjs' build-wasm.sh >/dev/null
grep -F -- './test-web-wasm-browser-smoke.sh' build-wasm.sh >/dev/null
grep -F 'const opfsOptions = options.opfs ?? (isOpfsAvailable() ? {} : false)' web/src/wasm-core.js >/dev/null
grep -F 'OPFS cannot be disabled in browser contexts with OPFS support' web/src/wasm-core.js >/dev/null
grep -F 'async function opfsEntryExists(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null
grep -F 'async function statOpfsEntry(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null
grep -F 'async function readOpfsDirectoryTree(workspacePath, relativePath, relativeRoot = "")' web/src/wasm-core.js >/dev/null
grep -F 'function readWasmDirectoryTree(module, rootPath, relativeRoot = "")' web/src/wasm-core.js >/dev/null
grep -F 'function writeWasmFileReplacingPath(module, path, data)' web/src/wasm-core.js >/dev/null
grep -F 'copyFile(fromPath: string, toPath: string): Promise<Uint8Array>;' web/src/wasm-core.d.ts >/dev/null
grep -F 'moveFile(fromPath: string, toPath: string): Promise<void>;' web/src/wasm-core.d.ts >/dev/null
grep -F 'exists(path: string): Promise<boolean>;' web/src/wasm-core.d.ts >/dev/null
grep -F 'stat(path: string): Promise<WasmOpfsEntryStat>;' web/src/wasm-core.d.ts >/dev/null
grep -F 'LinuxCNC source basis: rs274ngc_pre.cc restore_parameters() reads the' web/src/wasm-core.js >/dev/null
grep -F 'before replacing the main file and managing filename + ".bak".' web/src/wasm-core.js >/dev/null
grep -F 'await removeOpfsEntry(workspacePath, `${path}.new`, false);' web/src/wasm-core.js >/dev/null
grep -F 'OPFS workspace is required for browser program parsing' web/src/app.js >/dev/null
grep -F 'const events = await simulator.parseFileWithParameterFile(programPath, parameterPath, "linuxcnc", parseOptions);' web/src/app.js >/dev/null
grep -F 'default browser simulator did not create an OPFS workspace' web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null
grep -F 'browser simulator allowed OPFS to be disabled' web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null
grep -F 'app frame did not restore current program from OPFS after reload' web/test-browser-wasm-smoke-app-sections.js >/dev/null
grep -F 'app frame did not report OPFS program restore after reload' web/test-browser-wasm-smoke-app-sections.js >/dev/null
grep -F 'app frame did not persist LinuxCNC parameter state into OPFS' web/test-browser-wasm-smoke-app-sections.js >/dev/null
grep -F 'app frame did not reload LinuxCNC parameter state from OPFS after reload' web/test-browser-wasm-smoke-app-sections.js >/dev/null
grep -F '"parameters/missing-main.var.new", "stale temporary without main file' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
grep -F 'OPFS copyFile did not create the backup file' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null
grep -F 'OPFS copyFile did not update the WASM mirror destination' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null
grep -F 'OPFS moveFile did not replace the destination file' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null
grep -F 'OPFS moveFile left the WASM mirror source behind' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null
grep -F 'OPFS metadata queries polluted the WASM filesystem mirror' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
grep -F 'OPFS persistDirectory did not preserve an empty directory' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
grep -F 'OPFS readDirectory did not mirror an empty directory into WASM FS' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
grep -F 'OPFS readFile did not replace the WASM mirror directory with a file' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
grep -F 'stale LinuxCNC missing-parameter temporary file remained in OPFS' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
grep -F 'stale LinuxCNC missing-parameter temporary file remained in WASM FS' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
grep -F 'LinuxCNC out-of-order parameter file remained in WASM FS after restore failure' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
grep -F 'LinuxCNC out-of-range parameter file remained in WASM FS after restore failure' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
if [[ "$(grep -Fc 'cp build/wasm/cnc_sim.js' build-wasm.sh)" -ne 1 ]]; then
echo "build-wasm should copy cnc_sim.js exactly once" >&2
exit 1
@@ -251,8 +407,8 @@ if ! awk '
exit 1
fi
if ! awk '
index($0, "cmake --build build/wasm --target cnc_sim_wasm_runtime_probe") { runtime_probe_line = NR }
index($0, "cmake --build build/wasm --target cnc_sim_wasm") &&
index($0, "cmake --build build/wasm --target cnc_sim_wasm_runtime_probe --parallel \"$build_jobs\"") { runtime_probe_line = NR }
index($0, "cmake --build build/wasm --target cnc_sim_wasm --parallel \"$build_jobs\"") &&
!index($0, "cnc_sim_wasm_runtime_probe") { wasm_line = NR }
END { exit !(runtime_probe_line && wasm_line && runtime_probe_line < wasm_line) }
' build-wasm.sh; then
@@ -838,10 +994,10 @@ cmake -S core -B "$build_dir" \
-DCNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST="$manifest" \
-DCNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE=ON
cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe_objects
cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe
cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe_objects --parallel "$build_jobs"
cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe --parallel "$build_jobs"
"$build_dir/linuxcnc_rs274_wasm_safe_probe"
cmake --build "$build_dir" --target cnc_sim_wasm_runtime_probe
cmake --build "$build_dir" --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"
"$build_dir/cnc_sim_wasm_runtime_probe"
echo "linuxcnc wasm-safe CMake probe target passed"