#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc} 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 self_checks=${CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS:-0} if [[ "$self_checks" != "0" && "$self_checks" != "1" ]]; then echo "CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS must be 0 or 1: $self_checks" >&2 exit 1 fi cmake_compiler_launcher_mode=none cmake_compiler_launcher_args=() if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then cmake_compiler_launcher_mode=ccache cmake_compiler_launcher_args+=( -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ) 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") wasm_probe_object_cache_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_probe_object_cache.XXXXXX.log") wasm_blockers_cache_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_blockers_cache.XXXXXX.log") wasm_link_probe_cache_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_link_probe_cache.XXXXXX.log") wasm_standalone_probe_cache_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_standalone_probe_cache.XXXXXX.log") wasm_source_syntax_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_source_syntax_build_dir.XXXXXX.log") wasm_python_c_api_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_python_c_api_build_dir.XXXXXX.log") wasm_interp_find_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_interp_find_build_dir.XXXXXX.log") wasm_tooldata_mmap_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_tooldata_mmap_build_dir.XXXXXX.log") wasm_tooldata_runtime_build_dir_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_tooldata_runtime_build_dir.XXXXXX.log") cleanup_wasm_cmake_probe_temps() { local temp_path for temp_path in \ "$missing_manifest" \ "$missing_manifest_log" \ "$missing_root_log" \ "$invalid_build_jobs_log" \ "$invalid_build_dir_log" \ "$empty_build_dir_log" \ "$whitespace_build_dir_log" \ "$wasm_probe_object_cache_log" \ "$wasm_blockers_cache_log" \ "$wasm_link_probe_cache_log" \ "$wasm_standalone_probe_cache_log" \ "$wasm_source_syntax_build_dir_log" \ "$wasm_python_c_api_build_dir_log" \ "$wasm_interp_find_build_dir_log" \ "$wasm_tooldata_mmap_build_dir_log" \ "$wasm_tooldata_runtime_build_dir_log" \ "${build_next_signature:-}" \ "${unknown_manifest_filter_log:-}" \ "${unknown_manifest_output_log:-}" \ "${missing_shim_log:-}" \ "${missing_project_source_log:-}" \ "${missing_wasm_script_manifest:-}" \ "${missing_wasm_script_manifest_log:-}" \ "${missing_source_root:-}" \ "${missing_source_log:-}" \ "${missing_interp_find_root:-}" \ "${missing_interp_find_log:-}" \ "${missing_tooldata_runtime_root:-}" \ "${missing_tooldata_runtime_log:-}" \ "${unknown_group_manifest:-}" \ "${unknown_group_log:-}" \ "${blocker_scan_log:-}" \ "${blocker_report_file:-}" \ "${missing_source_manifest:-}" \ "${empty_partition_log:-}" \ "${empty_core_manifest:-}" \ "${empty_blocked_manifest:-}" \ "${bad_default_manifest_dir:-}" \ "${bad_default_manifest_log:-}" \ "${duplicate_manifest:-}" \ "${duplicate_manifest_log:-}" \ "${comment_manifest:-}" \ "${comment_manifest_log:-}" \ "${duplicate_source_manifest:-}" \ "${duplicate_source_log:-}" \ "${duplicate_syntax_manifest:-}" \ "${duplicate_syntax_log:-}" \ "${duplicate_pre_blocker_manifest:-}" \ "${duplicate_pre_blocker_log:-}" \ "${duplicate_pre_link_manifest:-}" \ "${duplicate_pre_link_log:-}" \ "${duplicate_runtime_link_manifest:-}" \ "${duplicate_runtime_link_log:-}"; do if [[ -n "$temp_path" ]]; then rm -rf "$temp_path" fi done } trap cleanup_wasm_cmake_probe_temps EXIT manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest") linuxcnc_root=$(cd "$linuxcnc_root" && pwd) preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$build_dir/preflight-cache"} LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest" 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 'MANIFEST_HASH=' sha256sum "$manifest" printf 'COMPILER_LAUNCHER=%s\n' "$cmake_compiler_launcher_mode" printf 'CMAKE_LISTS=' sha256sum core/CMakeLists.txt printf 'CONFIGURE_RULE_VERSION=1\n' } > "$build_next_signature" configure_cmake=1 if [[ ! -f "$build_signature" ]] || ! cmp -s "$build_signature" "$build_next_signature"; then mkdir -p "$build_dir" elif [[ -f "$build_dir/CMakeCache.txt" ]]; then configure_cmake=0 fi mv "$build_next_signature" "$build_signature" if [[ "$self_checks" == "1" ]]; then rm -f "$missing_manifest" if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$missing_manifest" >"$missing_manifest_log" 2>&1; then echo "build-wasm accepted missing manifest: $missing_manifest" >&2 exit 1 fi if ! grep -F "missing manifest: $missing_manifest" "$missing_manifest_log" >/dev/null; then echo "build-wasm did not report missing manifest clearly" >&2 sed -n '1,20p' "$missing_manifest_log" >&2 exit 1 fi if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 LINUXCNC_ROOT="$missing_root" ./build-wasm.sh >"$missing_root_log" 2>&1; then echo "build-wasm accepted missing LinuxCNC root: $missing_root" >&2 exit 1 fi if ! grep -F "missing LinuxCNC root: $missing_root" "$missing_root_log" >/dev/null; then echo "build-wasm did not report missing LinuxCNC root clearly" >&2 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 grep -F -- 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-blockers.sh "$manifest"' build-wasm.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh "$manifest"' analyze-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'cache_dir=${CNC_SIM_WASM_BLOCKERS_CACHE_DIR-${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/wasm-blocker-cache}}' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not be empty' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not contain whitespace: $cache_dir' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not be the filesystem root' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'exec 8>"$cache_dir/wasm-blockers.lock"' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'stat -c '\''SOURCE=%n:%s:%y'\''' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'sha256sum test-linuxcnc-wasm-blockers.sh' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'sha256sum analyze-linuxcnc-wasm-blockers.sh' test-linuxcnc-wasm-blockers.sh >/dev/null if CNC_SIM_WASM_BLOCKERS_CACHE_DIR= ./test-linuxcnc-wasm-blockers.sh "$manifest" >"$wasm_blockers_cache_log" 2>&1; then echo "wasm blocker cache accepted an empty cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not be empty' "$wasm_blockers_cache_log" >/dev/null if CNC_SIM_WASM_BLOCKERS_CACHE_DIR='build/wasm blocker cache' ./test-linuxcnc-wasm-blockers.sh "$manifest" >"$wasm_blockers_cache_log" 2>&1; then echo "wasm blocker cache accepted a whitespace-containing cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not contain whitespace: build/wasm blocker cache' "$wasm_blockers_cache_log" >/dev/null if CNC_SIM_WASM_BLOCKERS_CACHE_DIR=/ ./test-linuxcnc-wasm-blockers.sh "$manifest" >"$wasm_blockers_cache_log" 2>&1; then echo "wasm blocker cache accepted the filesystem root as its cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not be the filesystem root' "$wasm_blockers_cache_log" >/dev/null grep -F -- './test-linuxcnc-wasm-source-syntax.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-source-syntax.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-source-objects.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-source-objects.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-cmake-safe-probe.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-tooldata-link.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-tooldata-common-link.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-tooldata-mmap-symbols.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-tooldata-runtime-symbols.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-interp-base-link.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-interp-find-link.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-python-plugin-link.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-python-c-api-symbols.sh' build-wasm.sh >/dev/null grep -F -- './test-linuxcnc-wasm-rs274ngc-pre-object.sh' build-wasm.sh >/dev/null grep -F -- 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-rs274ngc-pre-link.sh "$manifest"' build-wasm.sh >/dev/null grep -F -- 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-runtime-link.sh "$manifest"' build-wasm.sh >/dev/null test -x build-linuxcnc-wasm-probe-objects.sh grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'cache_dir=${CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR-build/wasm-probe-object-cache}' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not be empty' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not contain whitespace: $cache_dir' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not be the filesystem root' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'source-objects|rs274ngc-pre|runtime' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'wasm probe object source list contains an empty path' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'list-cmake-set-sources.sh cnc_sim_core_sources core/' list-linuxcnc-wasm-safe-project-sources.sh >/dev/null grep -F 'list-cmake-set-sources.sh cnc_sim_linuxcnc_rs274_backend_sources core/' list-linuxcnc-wasm-safe-project-sources.sh >/dev/null grep -F 'build-linuxcnc-wasm-probe-objects.sh --mode source-objects "$manifest"' test-linuxcnc-wasm-source-objects.sh >/dev/null grep -F 'build-linuxcnc-wasm-probe-objects.sh --mode rs274ngc-pre "$manifest"' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -F 'build-linuxcnc-wasm-link-probe.sh --mode rs274ngc-pre "$manifest"' test-linuxcnc-wasm-rs274ngc-pre-link.sh >/dev/null grep -F 'build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest"' test-linuxcnc-wasm-runtime-link.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'source_${object_index}.o' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F 'DEP_FILES += %s.d' build-linuxcnc-wasm-probe-objects.sh >/dev/null grep -F -- '-MMD -MP -MF %s.d' build-linuxcnc-wasm-probe-objects.sh >/dev/null if CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR= ./build-linuxcnc-wasm-probe-objects.sh --mode source-objects "$manifest" >"$wasm_probe_object_cache_log" 2>&1; then echo "wasm probe object cache accepted an empty cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not be empty' "$wasm_probe_object_cache_log" >/dev/null if CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR='build/wasm probe object cache' ./build-linuxcnc-wasm-probe-objects.sh --mode source-objects "$manifest" >"$wasm_probe_object_cache_log" 2>&1; then echo "wasm probe object cache accepted a whitespace-containing cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not contain whitespace: build/wasm probe object cache' "$wasm_probe_object_cache_log" >/dev/null if CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR=/ ./build-linuxcnc-wasm-probe-objects.sh --mode source-objects "$manifest" >"$wasm_probe_object_cache_log" 2>&1; then echo "wasm probe object cache accepted the filesystem root as its cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not be the filesystem root' "$wasm_probe_object_cache_log" >/dev/null test -x build-linuxcnc-wasm-standalone-probe.sh grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'cache_dir=${CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR-build/wasm-standalone-probe-cache}' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not be empty' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not contain whitespace: $cache_dir' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not be the filesystem root' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'tooldata-link|tooldata-common-link|interp-base-link|python-plugin-link|rs274ngc-pre-object' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'exec 8>"$mode_dir/probe.lock"' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'DEP_FILES += %s.d' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' build-linuxcnc-wasm-standalone-probe.sh >/dev/null grep -F 'build-linuxcnc-wasm-standalone-probe.sh --mode tooldata-link' test-linuxcnc-wasm-tooldata-link.sh >/dev/null grep -F 'build-linuxcnc-wasm-standalone-probe.sh --mode tooldata-common-link' test-linuxcnc-wasm-tooldata-common-link.sh >/dev/null grep -F 'build-linuxcnc-wasm-standalone-probe.sh --mode interp-base-link' test-linuxcnc-wasm-interp-base-link.sh >/dev/null grep -F 'build-linuxcnc-wasm-standalone-probe.sh --mode python-plugin-link' test-linuxcnc-wasm-python-plugin-link.sh >/dev/null grep -F 'build-linuxcnc-wasm-standalone-probe.sh --mode rs274ngc-pre-object' test-linuxcnc-wasm-rs274ngc-pre-object.sh >/dev/null if CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR= ./build-linuxcnc-wasm-standalone-probe.sh --mode python-plugin-link >"$wasm_standalone_probe_cache_log" 2>&1; then echo "wasm standalone probe cache accepted an empty cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not be empty' "$wasm_standalone_probe_cache_log" >/dev/null if CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR='build/wasm standalone probe cache' ./build-linuxcnc-wasm-standalone-probe.sh --mode python-plugin-link >"$wasm_standalone_probe_cache_log" 2>&1; then echo "wasm standalone probe cache accepted a whitespace-containing cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not contain whitespace: build/wasm standalone probe cache' "$wasm_standalone_probe_cache_log" >/dev/null if CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR=/ ./build-linuxcnc-wasm-standalone-probe.sh --mode python-plugin-link >"$wasm_standalone_probe_cache_log" 2>&1; then echo "wasm standalone probe cache accepted the filesystem root as its cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not be the filesystem root' "$wasm_standalone_probe_cache_log" >/dev/null if CNC_SIM_BUILD_JOBS=0 ./build-linuxcnc-wasm-standalone-probe.sh --mode python-plugin-link >"$wasm_standalone_probe_cache_log" 2>&1; then echo "wasm standalone probe cache accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_standalone_probe_cache_log" >/dev/null test -x build-linuxcnc-wasm-link-probe.sh grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'cache_dir=${CNC_SIM_WASM_LINK_PROBE_CACHE_DIR-build/wasm-link-probe-cache}' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not be empty' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not contain whitespace: $cache_dir' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not be the filesystem root' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'rs274ngc-pre|runtime' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'build-linuxcnc-wasm-probe-objects.sh --mode "$object_mode" "$manifest"' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'exec 8>"$mode_dir/link.lock"' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' build-linuxcnc-wasm-link-probe.sh >/dev/null grep -F 'build-linuxcnc-wasm-link-probe.sh --mode rs274ngc-pre "$manifest"' test-linuxcnc-wasm-rs274ngc-pre-link.sh >/dev/null grep -F 'build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest"' test-linuxcnc-wasm-runtime-link.sh >/dev/null grep -F 'symbol_signature="$probe_dir/runtime.symbols.signature"' test-linuxcnc-wasm-runtime-link.sh >/dev/null grep -F "printf 'SYMBOL_RULE_VERSION=1\n'" test-linuxcnc-wasm-runtime-link.sh >/dev/null grep -F "stat -c 'PROBE_STAT=%n:%s:%y' \"\$probe\"" test-linuxcnc-wasm-runtime-link.sh >/dev/null grep -F 'nm -C "$probe" > "$symbol_file"' test-linuxcnc-wasm-runtime-link.sh >/dev/null if CNC_SIM_WASM_LINK_PROBE_CACHE_DIR= ./build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest" >"$wasm_link_probe_cache_log" 2>&1; then echo "wasm link probe cache accepted an empty cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not be empty' "$wasm_link_probe_cache_log" >/dev/null if CNC_SIM_WASM_LINK_PROBE_CACHE_DIR='build/wasm link probe cache' ./build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest" >"$wasm_link_probe_cache_log" 2>&1; then echo "wasm link probe cache accepted a whitespace-containing cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not contain whitespace: build/wasm link probe cache' "$wasm_link_probe_cache_log" >/dev/null if CNC_SIM_WASM_LINK_PROBE_CACHE_DIR=/ ./build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest" >"$wasm_link_probe_cache_log" 2>&1; then echo "wasm link probe cache accepted the filesystem root as its cache directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not be the filesystem root' "$wasm_link_probe_cache_log" >/dev/null if CNC_SIM_BUILD_JOBS=0 ./build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest" >"$wasm_link_probe_cache_log" 2>&1; then echo "wasm link probe cache accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_link_probe_cache_log" >/dev/null grep -F 'build_dir=${CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR-build/wasm-source-syntax-test}' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not be empty' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not be the filesystem root' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir"' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'wasm_source_syntax_signature="$build_dir/wasm-source-syntax.signature"' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$wasm_source_syntax_makefile"' test-linuxcnc-wasm-source-syntax.sh >/dev/null grep -F -- '-MMD -MP -MF %s/source_%s.d' test-linuxcnc-wasm-source-syntax.sh >/dev/null if CNC_SIM_BUILD_JOBS=0 ./test-linuxcnc-wasm-source-syntax.sh "$manifest" >"$wasm_source_syntax_build_dir_log" 2>&1; then echo "wasm source syntax probe accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_source_syntax_build_dir_log" >/dev/null if CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR= ./test-linuxcnc-wasm-source-syntax.sh "$manifest" >"$wasm_source_syntax_build_dir_log" 2>&1; then echo "wasm source syntax probe accepted an empty build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not be empty' "$wasm_source_syntax_build_dir_log" >/dev/null if CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR='build/wasm source syntax test' ./test-linuxcnc-wasm-source-syntax.sh "$manifest" >"$wasm_source_syntax_build_dir_log" 2>&1; then echo "wasm source syntax probe accepted a whitespace-containing build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not contain whitespace: build/wasm source syntax test' "$wasm_source_syntax_build_dir_log" >/dev/null if CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR=/ ./test-linuxcnc-wasm-source-syntax.sh "$manifest" >"$wasm_source_syntax_build_dir_log" 2>&1; then echo "wasm source syntax probe accepted the filesystem root as its build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not be the filesystem root' "$wasm_source_syntax_build_dir_log" >/dev/null grep -F 'build_dir=${CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR-build/wasm-python-c-api-symbols}' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not be empty' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not be the filesystem root' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'signature="$build_dir/python-c-api.signature"' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'source_symbols_signature="$build_dir/python-c-api.source-symbols.signature"' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F "printf 'SOURCE_SYMBOL_RULE_VERSION=1\n'" test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'object_symbols_signature="$build_dir/python-c-api.object-symbols.signature"' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F "printf 'OBJECT_SYMBOL_RULE_VERSION=1\n'" test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null grep -F -- '-MMD -MP -MF %s.d' test-linuxcnc-wasm-python-c-api-symbols.sh >/dev/null if CNC_SIM_BUILD_JOBS=0 ./test-linuxcnc-wasm-python-c-api-symbols.sh >"$wasm_python_c_api_build_dir_log" 2>&1; then echo "wasm Python C API probe accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_python_c_api_build_dir_log" >/dev/null if CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR= ./test-linuxcnc-wasm-python-c-api-symbols.sh >"$wasm_python_c_api_build_dir_log" 2>&1; then echo "wasm Python C API probe accepted an empty build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not be empty' "$wasm_python_c_api_build_dir_log" >/dev/null if CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR='build/wasm python c api' ./test-linuxcnc-wasm-python-c-api-symbols.sh >"$wasm_python_c_api_build_dir_log" 2>&1; then echo "wasm Python C API probe accepted a whitespace-containing build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not contain whitespace: build/wasm python c api' "$wasm_python_c_api_build_dir_log" >/dev/null if CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR=/ ./test-linuxcnc-wasm-python-c-api-symbols.sh >"$wasm_python_c_api_build_dir_log" 2>&1; then echo "wasm Python C API probe accepted the filesystem root as its build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not be the filesystem root' "$wasm_python_c_api_build_dir_log" >/dev/null grep -F 'build_dir=${CNC_SIM_WASM_INTERP_FIND_BUILD_DIR-build/wasm-interp-find-link}' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not be empty' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not be the filesystem root' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'signature="$build_dir/interp-find.signature"' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' test-linuxcnc-wasm-interp-find-link.sh >/dev/null grep -F -- '-MMD -MP -MF %s.d' test-linuxcnc-wasm-interp-find-link.sh >/dev/null if CNC_SIM_BUILD_JOBS=0 ./test-linuxcnc-wasm-interp-find-link.sh >"$wasm_interp_find_build_dir_log" 2>&1; then echo "wasm interp_find probe accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_interp_find_build_dir_log" >/dev/null if CNC_SIM_WASM_INTERP_FIND_BUILD_DIR= ./test-linuxcnc-wasm-interp-find-link.sh >"$wasm_interp_find_build_dir_log" 2>&1; then echo "wasm interp_find probe accepted an empty build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not be empty' "$wasm_interp_find_build_dir_log" >/dev/null if CNC_SIM_WASM_INTERP_FIND_BUILD_DIR='build/wasm interp find' ./test-linuxcnc-wasm-interp-find-link.sh >"$wasm_interp_find_build_dir_log" 2>&1; then echo "wasm interp_find probe accepted a whitespace-containing build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not contain whitespace: build/wasm interp find' "$wasm_interp_find_build_dir_log" >/dev/null if CNC_SIM_WASM_INTERP_FIND_BUILD_DIR=/ ./test-linuxcnc-wasm-interp-find-link.sh >"$wasm_interp_find_build_dir_log" 2>&1; then echo "wasm interp_find probe accepted the filesystem root as its build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not be the filesystem root' "$wasm_interp_find_build_dir_log" >/dev/null grep -F 'build_dir=${CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR-build/wasm-tooldata-mmap-symbols}' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not be empty' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not be the filesystem root' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'signature="$build_dir/tooldata-mmap-symbols.signature"' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'symbols_signature="$build_dir/tooldata-mmap-symbols.nm.signature"' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F "printf 'SYMBOL_RULE_VERSION=1\n'" test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null grep -F -- '-MMD -MP -MF %s.d' test-linuxcnc-wasm-tooldata-mmap-symbols.sh >/dev/null if CNC_SIM_BUILD_JOBS=0 ./test-linuxcnc-wasm-tooldata-mmap-symbols.sh >"$wasm_tooldata_mmap_build_dir_log" 2>&1; then echo "wasm tooldata_mmap symbol probe accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_tooldata_mmap_build_dir_log" >/dev/null if CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR= ./test-linuxcnc-wasm-tooldata-mmap-symbols.sh >"$wasm_tooldata_mmap_build_dir_log" 2>&1; then echo "wasm tooldata_mmap symbol probe accepted an empty build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not be empty' "$wasm_tooldata_mmap_build_dir_log" >/dev/null if CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR='build/wasm tooldata mmap' ./test-linuxcnc-wasm-tooldata-mmap-symbols.sh >"$wasm_tooldata_mmap_build_dir_log" 2>&1; then echo "wasm tooldata_mmap symbol probe accepted a whitespace-containing build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not contain whitespace: build/wasm tooldata mmap' "$wasm_tooldata_mmap_build_dir_log" >/dev/null if CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR=/ ./test-linuxcnc-wasm-tooldata-mmap-symbols.sh >"$wasm_tooldata_mmap_build_dir_log" 2>&1; then echo "wasm tooldata_mmap symbol probe accepted the filesystem root as its build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not be the filesystem root' "$wasm_tooldata_mmap_build_dir_log" >/dev/null grep -F 'build_dir=${CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR-build/wasm-tooldata-runtime-symbols}' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not be empty' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not be the filesystem root' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'signature="$build_dir/tooldata-runtime-symbols.signature"' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'symbols_signature="$build_dir/tooldata-runtime-symbols.nm.signature"' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F "printf 'SYMBOL_RULE_VERSION=1\n'" test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null grep -F -- '-MMD -MP -MF %s.d' test-linuxcnc-wasm-tooldata-runtime-symbols.sh >/dev/null if CNC_SIM_BUILD_JOBS=0 ./test-linuxcnc-wasm-tooldata-runtime-symbols.sh >"$wasm_tooldata_runtime_build_dir_log" 2>&1; then echo "wasm tooldata runtime symbol probe accepted invalid CNC_SIM_BUILD_JOBS" >&2 exit 1 fi grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: 0' "$wasm_tooldata_runtime_build_dir_log" >/dev/null if CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR= ./test-linuxcnc-wasm-tooldata-runtime-symbols.sh >"$wasm_tooldata_runtime_build_dir_log" 2>&1; then echo "wasm tooldata runtime symbol probe accepted an empty build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not be empty' "$wasm_tooldata_runtime_build_dir_log" >/dev/null if CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR='build/wasm tooldata runtime' ./test-linuxcnc-wasm-tooldata-runtime-symbols.sh >"$wasm_tooldata_runtime_build_dir_log" 2>&1; then echo "wasm tooldata runtime symbol probe accepted a whitespace-containing build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not contain whitespace: build/wasm tooldata runtime' "$wasm_tooldata_runtime_build_dir_log" >/dev/null if CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR=/ ./test-linuxcnc-wasm-tooldata-runtime-symbols.sh >"$wasm_tooldata_runtime_build_dir_log" 2>&1; then echo "wasm tooldata runtime symbol probe accepted the filesystem root as its build directory" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not be the filesystem root' "$wasm_tooldata_runtime_build_dir_log" >/dev/null if grep -F '} > "$report_file" || true' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null; then echo "rs274ngc_pre blocker scan still hides report pipeline failures with || true" >&2 exit 1 fi grep -Fx 'keep_report_file=0' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -Fx 'trap cleanup_rs274ngc_pre_blocker_temps EXIT' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -Fx 'keep_report_file=1' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null if ! awk ' index($0, "if [[ \"$keep_report_file\" -eq 0 && -n \"${report_file:-}\" ]]; then") { cleanup_line = NR } index($0, "keep_report_file=1") { keep_line = NR } index($0, "echo \"wrote $report_file\"") { wrote_line = NR } END { exit !(cleanup_line && keep_line && wrote_line && cleanup_line < keep_line && keep_line < wrote_line) } ' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh; then echo "rs274ngc_pre blocker scan does not clean failed reports before preserving successful ones" >&2 exit 1 fi if ! awk ' index($0, "check-linuxcnc-inputs-cached.sh --cache-dir \"$preflight_cache_dir\" \"$manifest\"") { check_line = NR } index($0, "cache_dir=${CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR-build/wasm-rs274ngc-pre-link-blockers}") { report_line = NR } END { exit !(check_line && report_line && check_line < report_line) } ' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh; then echo "rs274ngc_pre blocker scan prepares its report cache before input validation" >&2 exit 1 fi grep -F 'CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -F 'rs274ngc-pre-link-blockers.lock' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -F "printf 'FILTER_RULE_VERSION=1\n'" test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -F "stat -c 'OBJECT=%n:%s:%y'" test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null grep -F 'cmp -s "$signature" "$next_signature"' test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >/dev/null for build_dir_probe_script in \ test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh; do if ! awk ' $0 ~ /^trap .* EXIT$/ { trap_line = NR } (index($0, "./check-linuxcnc-inputs.sh") || index($0, "./check-linuxcnc-inputs-cached.sh") || index($0, "./build-linuxcnc-wasm-probe-objects.sh")) && !check_line { check_line = NR } END { exit !(trap_line && check_line && trap_line < check_line) } ' "$build_dir_probe_script"; then echo "$build_dir_probe_script installs build_dir cleanup after failure-prone input setup" >&2 exit 1 fi done grep -F 'trap '\''rm -f "$missing_manifest" "$missing_manifest_log" "$missing_root_log" "$missing_source_manifest" "$missing_source_log" "$duplicate_manifest" "$duplicate_manifest_log" "$missing_replacement_manifest" "$missing_replacement_log"'\'' EXIT' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'self_checks=${CNC_SIM_WASM_BLOCKERS_SELF_CHECKS:-0}' test-linuxcnc-wasm-blockers.sh >/dev/null grep -F 'CNC_SIM_WASM_BLOCKERS_SELF_CHECKS must be 0 or 1: $self_checks' test-linuxcnc-wasm-blockers.sh >/dev/null if grep -F 'rm -f "$missing_source_manifest" "$missing_source_log"' test-linuxcnc-wasm-blockers.sh >/dev/null; then echo "wasm blocker scan still relies on manual cleanup for missing-source temporaries" >&2 exit 1 fi grep -Fx 'trap cleanup_wasm_cmake_probe_temps EXIT' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null if ! awk ' /cleanup_wasm_cmake_probe_temps\(\)/ { in_cleanup = 1 } in_cleanup && index($0, "\"$missing_manifest\"") { found_missing_manifest = 1 } in_cleanup && index($0, "\"${missing_wasm_script_manifest:-}\"") { found_missing_script_manifest = 1 } in_cleanup && /^}/ { in_cleanup = 0 } END { exit !(found_missing_manifest && found_missing_script_manifest) } ' test-linuxcnc-wasm-cmake-safe-probe.sh; then echo "wasm CMake safe probe cleanup no longer removes fixed missing-manifest paths" >&2 exit 1 fi for forbidden_manual_cleanup in \ 'rm -f "$missing_manifest_log"' \ 'rm -f "$unknown_manifest_filter_log"' \ 'rm -f "$unknown_manifest_output_log"' \ 'rm -f "$missing_shim_log"' \ 'rm -f "$missing_project_source_log"' \ 'rm -f "$missing_wasm_script_manifest_log"' \ 'rm -rf "$missing_source_root"' \ 'rm -f "$missing_source_log"' \ 'rm -rf "$missing_interp_find_root"' \ 'rm -f "$missing_interp_find_log"' \ 'rm -rf "$missing_tooldata_runtime_root"' \ 'rm -f "$missing_tooldata_runtime_log"' \ 'rm -f "$unknown_group_manifest" "$unknown_group_log"' \ 'rm -f "$blocker_report_file" "$blocker_scan_log"' \ 'rm -f "$missing_source_manifest" "$missing_source_log"' \ 'rm -f "$empty_core_manifest" "$empty_blocked_manifest" "$empty_partition_log"' \ 'rm -rf "$bad_default_manifest_dir"' \ 'rm -f "$bad_default_manifest_log"' \ 'rm -f "$duplicate_manifest" "$duplicate_manifest_log"' \ 'rm -f "$comment_manifest" "$comment_manifest_log"' \ 'rm -f "$duplicate_source_manifest" "$duplicate_source_log"' \ 'rm -f "$duplicate_syntax_manifest" "$duplicate_syntax_log"' \ 'rm -f "$duplicate_pre_blocker_manifest" "$duplicate_pre_blocker_log"' \ 'rm -f "$duplicate_pre_link_manifest" "$duplicate_pre_link_log"' \ 'rm -f "$duplicate_runtime_link_manifest" "$duplicate_runtime_link_log"'; do if grep -Fx "$forbidden_manual_cleanup" test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null; then echo "wasm CMake safe probe still relies on manual cleanup: $forbidden_manual_cleanup" >&2 exit 1 fi done forbidden_common_flags_process_substitution='readarray -t common_flags < <(' forbidden_common_flags_helper='./list-linuxcnc-wasm-common-cxxflags.sh' if grep -RInF "${forbidden_common_flags_process_substitution}LINUXCNC_ROOT=\"\$linuxcnc_root\" ${forbidden_common_flags_helper}" test-linuxcnc-wasm-*.sh >/dev/null; then echo "wasm probes still read common flags through process substitution" >&2 grep -RInF "${forbidden_common_flags_process_substitution}LINUXCNC_ROOT=\"\$linuxcnc_root\" ${forbidden_common_flags_helper}" test-linuxcnc-wasm-*.sh >&2 exit 1 fi grep -F 'preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}' list-linuxcnc-wasm-common-cxxflags.sh >/dev/null grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' list-linuxcnc-wasm-common-cxxflags.sh >/dev/null grep -F -- '-DCNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST="$manifest"' build-wasm.sh >/dev/null grep -F -- 'for required_tool in cmake emcmake emcc node; do' build-wasm.sh >/dev/null 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 'cmake_compiler_launcher_mode=none' build-wasm.sh >/dev/null grep -F 'cmake_compiler_launcher_mode=ccache' build-wasm.sh >/dev/null grep -F 'wasm_build_signature=build/wasm/wasm-build.signature' build-wasm.sh >/dev/null grep -F 'wasm_build_next_signature=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_build.signature.XXXXXX")' build-wasm.sh >/dev/null grep -F 'sha256sum "$manifest"' build-wasm.sh >/dev/null grep -F 'sha256sum core/CMakeLists.txt' build-wasm.sh >/dev/null grep -F "printf 'CONFIGURE_RULE_VERSION=1\n'" build-wasm.sh >/dev/null grep -F 'run_parallel_wasm_probe() {' build-wasm.sh >/dev/null grep -F 'wait_parallel_wasm_probes() {' build-wasm.sh >/dev/null grep -F 'parallel_probe_pids+=("$!")' build-wasm.sh >/dev/null grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" "$@"' 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 'configure_wasm=1' build-wasm.sh >/dev/null grep -F 'elif [[ -f build/wasm/CMakeCache.txt ]]; then' build-wasm.sh >/dev/null grep -F 'configure_wasm=0' build-wasm.sh >/dev/null if grep -F 'rm -rf build/wasm' build-wasm.sh >/dev/null; then echo "build-wasm configure signature changes must reconfigure build/wasm in place" >&2 exit 1 fi 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 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 'sha256sum "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null grep -F "printf 'CONFIGURE_RULE_VERSION=1\n'" test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null if awk ' BEGIN { forbidden = "rm -rf " "\"$build_dir\"" } $0 ~ "^[[:space:]]*" forbidden { found = 1 } END { exit !found } ' test-linuxcnc-wasm-cmake-safe-probe.sh; then echo "wasm CMake probe signature changes must reconfigure build_dir in place" >&2 exit 1 fi for signature_script in \ build-wasm.sh \ build-linuxcnc-wasm-probe-objects.sh \ build-linuxcnc-wasm-link-probe.sh \ build-linuxcnc-wasm-standalone-probe.sh \ test-linuxcnc-source-syntax.sh \ test-linuxcnc-wasm-cmake-safe-probe.sh \ test-linuxcnc-wasm-interp-find-link.sh \ test-linuxcnc-wasm-python-c-api-symbols.sh \ test-linuxcnc-wasm-source-syntax.sh \ test-linuxcnc-wasm-tooldata-mmap-symbols.sh \ test-linuxcnc-wasm-tooldata-runtime-symbols.sh; do if grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' "$signature_script" >/dev/null; then echo "$signature_script signature must not depend on CNC_SIM_BUILD_JOBS" >&2 exit 1 fi done for hot_signature_script in \ build-linuxcnc-wasm-link-probe.sh \ build-linuxcnc-wasm-probe-objects.sh \ build-linuxcnc-wasm-standalone-probe.sh \ test-linuxcnc-wasm-interp-find-link.sh \ test-linuxcnc-wasm-python-c-api-symbols.sh \ test-linuxcnc-wasm-source-syntax.sh \ test-linuxcnc-wasm-tooldata-mmap-symbols.sh \ test-linuxcnc-wasm-tooldata-runtime-symbols.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 if grep -F 'sha256sum build-wasm.sh' build-wasm.sh >/dev/null; then echo "build-wasm configure signature must use CONFIGURE_RULE_VERSION instead of the whole script hash" >&2 exit 1 fi 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 cnc_sim_wasm --parallel "$build_jobs"' build-wasm.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 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 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 '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 if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|webkitRequestFileSystem|FileReader' web/src; then echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2 exit 1 fi 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;' web/src/wasm-core.d.ts >/dev/null grep -F 'moveFile(fromPath: string, toPath: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'exists(path: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'stat(path: string): Promise;' 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 fi if [[ "$(grep -Fc 'cp build/wasm/cnc_sim.wasm' build-wasm.sh)" -ne 1 ]]; then echo "build-wasm should copy cnc_sim.wasm exactly once" >&2 exit 1 fi if ! awk ' index($0, "mkdir -p web/public") { mkdir_line = NR } index($0, "cp build/wasm/cnc_sim.js web/public/cnc_sim.js") { cp_line = NR } END { exit !(mkdir_line && cp_line && mkdir_line < cp_line) } ' build-wasm.sh; then echo "build-wasm must create web/public before copying wasm artifacts" >&2 exit 1 fi if ! awk ' index($0, "run_parallel_wasm_probe \"LinuxCNC wasm tooldata shim link probe\"") { parallel_start_line = NR } index($0, "wait_parallel_wasm_probes") && parallel_start_line { wait_line = NR } index($0, "LinuxCNC wasm rs274ngc_pre link blocker scan") { pre_link_line = NR } END { exit !(parallel_start_line && wait_line && pre_link_line && parallel_start_line < wait_line && wait_line < pre_link_line) } ' build-wasm.sh; then echo "build-wasm must wait for independent wasm probes before rs274ngc_pre link checks" >&2 exit 1 fi if ! awk ' index($0, "cp build/wasm/cnc_sim.js web/public/cnc_sim.js") { cp_js_line = NR } index($0, "cp build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm") { cp_wasm_line = NR } index($0, "cmp -s build/wasm/cnc_sim.js web/public/cnc_sim.js") { cmp_js_line = NR } index($0, "cmp -s build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm") { cmp_wasm_line = NR } index($0, "./test-web-wasm-node-smoke.sh") { node_line = NR } index($0, "./test-web-wasm-browser-smoke.sh") { browser_line = NR } END { exit !(cp_js_line && cp_wasm_line && cmp_js_line && cmp_wasm_line && node_line && browser_line && cp_js_line < cmp_js_line && cp_wasm_line < cmp_wasm_line && cmp_js_line < node_line && cmp_wasm_line < node_line && node_line < browser_line) } ' build-wasm.sh; then echo "build-wasm must verify copied wasm artifacts before running the Node and browser smokes" >&2 exit 1 fi if ! awk ' index($0, "cmake --build build/wasm --target cnc_sim_wasm_runtime_probe cnc_sim_wasm --parallel \"$build_jobs\"") { runtime_pos = index($0, "cnc_sim_wasm_runtime_probe") wasm_pos = index($0, " cnc_sim_wasm ") } END { exit !(runtime_pos && wasm_pos && runtime_pos < wasm_pos) } ' build-wasm.sh; then echo "build-wasm does not build the CMake runtime probe before the browser WASM target" >&2 exit 1 fi grep -F -- 'default_manifest="$PWD/linuxcnc-rs274-wasm-source-files.txt"' build-wasm.sh >/dev/null grep -F -- 'manifest_core_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core)' build-wasm.sh >/dev/null grep -F -- 'manifest_blocked_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked)' build-wasm.sh >/dev/null grep -F -- 'count_nonempty_lines() {' 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 -- 'LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest" --require-rs274-complete' build-wasm.sh >/dev/null if grep -F 'grep -c . <<<"$manifest_core_output" || true' build-wasm.sh >/dev/null; then echo "build-wasm still counts manifest output through grep -c with || true" >&2 exit 1 fi grep -F -- 'if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 26 || "$manifest_blocked_count" -ne 9 ]]; then' build-wasm.sh >/dev/null grep -F 'LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null ./list-linuxcnc-wasm-safe-shims.sh >/dev/null ./list-linuxcnc-wasm-safe-project-sources.sh >/dev/null ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core >/dev/null wasm_manifest_core=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core) grep -Fx "src/emc/rs274ngc/interp_arc.cc" <<<"$wasm_manifest_core" >/dev/null if grep -E '\.(hh|h)$' <<<"$wasm_manifest_core" >/dev/null; then echo "wasm manifest core compile group includes headers" >&2 exit 1 fi wasm_manifest_header=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" header) grep -Fx "src/emc/rs274ngc/rs274ngc_interp.hh" <<<"$wasm_manifest_header" >/dev/null wasm_manifest_metadata=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" metadata) grep -Fx "src/emc/rs274ngc/Submakefile" <<<"$wasm_manifest_metadata" >/dev/null grep -Fx "src/emc/rs274ngc/meson.build" <<<"$wasm_manifest_metadata" >/dev/null wasm_rs274ngc_manifest_entries=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" all | grep '^src/emc/rs274ngc/' | sort) wasm_rs274ngc_source_entries=$(find "$linuxcnc_root/src/emc/rs274ngc" -maxdepth 1 -type f -printf 'src/emc/rs274ngc/%f\n' | sort) if ! diff -u <(printf '%s\n' "$wasm_rs274ngc_source_entries") <(printf '%s\n' "$wasm_rs274ngc_manifest_entries") >/dev/null; then echo "wasm rs274ngc manifest no longer covers the full LinuxCNC source directory" >&2 diff -u <(printf '%s\n' "$wasm_rs274ngc_source_entries") <(printf '%s\n' "$wasm_rs274ngc_manifest_entries") >&2 || true exit 1 fi wasm_manifest_blocked=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked) grep -Fx "src/emc/tooldata/tooldata_mmap.cc" <<<"$wasm_manifest_blocked" >/dev/null wasm_manifest_blocked_header=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked-header) grep -Fx "src/emc/rs274ngc/boost_pyenum_macros.hh" <<<"$wasm_manifest_blocked_header" >/dev/null unknown_manifest_filter_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_unknown_wasm_manifest_filter.XXXXXX.log") if ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" bogus >"$unknown_manifest_filter_log" 2>&1; then echo "wasm manifest source lister accepted unknown filter" >&2 exit 1 fi if ! grep -F "unknown manifest source filter: bogus" "$unknown_manifest_filter_log" >/dev/null; then echo "wasm manifest source lister did not report unknown filter clearly" >&2 sed -n '1,20p' "$unknown_manifest_filter_log" >&2 exit 1 fi unknown_manifest_output_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_unknown_wasm_manifest_output.XXXXXX.log") if ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core bogus >"$unknown_manifest_output_log" 2>&1; then echo "wasm manifest source lister accepted unknown output mode" >&2 exit 1 fi if ! grep -F "unknown manifest source output mode: bogus" "$unknown_manifest_output_log" >/dev/null; then echo "wasm manifest source lister did not report unknown output mode clearly" >&2 sed -n '1,20p' "$unknown_manifest_output_log" >&2 exit 1 fi wasm_manifest_core_full=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full) grep -Fx "$linuxcnc_root/src/emc/rs274ngc/interp_arc.cc" <<<"$wasm_manifest_core_full" >/dev/null dlfcn_shim=$(./list-linuxcnc-wasm-safe-shims.sh dlfcn.cc) grep -Fx "core/wasm_shims/dlfcn.cc" <<<"$dlfcn_shim" >/dev/null python_plugin_shim=$(./list-linuxcnc-wasm-safe-shims.sh python_plugin.cc) grep -Fx "core/wasm_shims/pythonplugin/python_plugin.cc" <<<"$python_plugin_shim" >/dev/null grep -F 'LinuxCNC source basis: src/emc/pythonplugin/python_plugin.cc provides the' core/wasm_shims/pythonplugin/python_plugin.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/pythonplugin/python_plugin.hh declares this' core/wasm_shims/pythonplugin/python_plugin.hh >/dev/null python_c_api_shim=$(./list-linuxcnc-wasm-safe-shims.sh python_c_api_shim.cc) grep -Fx "core/wasm_shims/python_c_api_shim.cc" <<<"$python_c_api_shim" >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_python.cc,' core/wasm_shims/python_c_api_shim.cc >/dev/null grep -F 'LinuxCNC source basis: RS274 Python/remap sources include Python.h through' core/wasm_shims/Python.h >/dev/null rtapi_compat_shim=$(./list-linuxcnc-wasm-safe-shims.sh rtapi_compat.cc) grep -Fx "core/wasm_shims/rtapi_compat.cc" <<<"$rtapi_compat_shim" >/dev/null tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc) grep -Fx "core/wasm_shims/tooldata/tooldata_mmap_backend.cc" <<<"$tooldata_mmap_backend_shim" >/dev/null tooldata_runtime_stubs_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_runtime_stubs.cc) grep -Fx "core/wasm_shims/tooldata/tooldata_runtime_stubs.cc" <<<"$tooldata_runtime_stubs_shim" >/dev/null grep -F 'LinuxCNC source basis: src/emc/tooldata/tooldata.hh declares the tooldata' core/wasm_shims/tooldata/tooldata.hh >/dev/null grep -F 'LinuxCNC source basis: src/emc/tooldata/tooldata_mmap.cc provides these' core/wasm_shims/tooldata/tooldata_mmap_backend.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/tooldata/tooldata_nml.cc and tooldata_db.cc' core/wasm_shims/tooldata/tooldata_runtime_stubs.cc >/dev/null wasm_bridge_source=$(./list-linuxcnc-wasm-safe-project-sources.sh linuxcnc_canon_bridge.cpp) grep -Fx "core/src/linuxcnc_canon_bridge.cpp" <<<"$wasm_bridge_source" >/dev/null missing_shim_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_wasm_safe_shim.XXXXXX.log") if ./list-linuxcnc-wasm-safe-shims.sh does_not_exist.cc >"$missing_shim_log" 2>&1; then echo "wasm-safe shim lister accepted missing shim filter" >&2 exit 1 fi if ! grep -F "missing wasm-safe shim in CMake list: does_not_exist.cc" "$missing_shim_log" >/dev/null; then echo "wasm-safe shim lister did not report missing shim filter clearly" >&2 sed -n '1,20p' "$missing_shim_log" >&2 exit 1 fi missing_project_source_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_wasm_safe_project_source.XXXXXX.log") if ./list-linuxcnc-wasm-safe-project-sources.sh does_not_exist.cc >"$missing_project_source_log" 2>&1; then echo "wasm-safe project source lister accepted missing source filter" >&2 exit 1 fi if ! grep -F "missing wasm-safe project source in CMake list: does_not_exist.cc" "$missing_project_source_log" >/dev/null; then echo "wasm-safe project source lister did not report missing source filter clearly" >&2 sed -n '1,20p' "$missing_project_source_log" >&2 exit 1 fi missing_wasm_script_manifest=${TMPDIR:-/tmp}/cnc_sim_missing_wasm_script_manifest.txt missing_wasm_script_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_wasm_script_manifest.XXXXXX.log") rm -f "$missing_wasm_script_manifest" for script in \ list-linuxcnc-wasm-manifest-sources.sh \ test-linuxcnc-wasm-source-syntax.sh \ test-linuxcnc-wasm-source-objects.sh \ test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh \ test-linuxcnc-wasm-rs274ngc-pre-link.sh \ test-linuxcnc-wasm-runtime-link.sh; do if "./$script" "$missing_wasm_script_manifest" >"$missing_wasm_script_manifest_log" 2>&1; then echo "$script accepted missing manifest: $missing_wasm_script_manifest" >&2 exit 1 fi if ! grep -F "missing manifest: $missing_wasm_script_manifest" "$missing_wasm_script_manifest_log" >/dev/null; then echo "$script did not report missing manifest clearly" >&2 sed -n '1,20p' "$missing_wasm_script_manifest_log" >&2 exit 1 fi done missing_root_scripts=( test-linuxcnc-wasm-interp-base-link.sh test-linuxcnc-wasm-interp-find-link.sh test-linuxcnc-wasm-python-c-api-symbols.sh test-linuxcnc-wasm-python-plugin-link.sh test-linuxcnc-wasm-rs274ngc-pre-object.sh test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh test-linuxcnc-wasm-rs274ngc-pre-link.sh test-linuxcnc-wasm-runtime-link.sh test-linuxcnc-wasm-source-objects.sh test-linuxcnc-wasm-source-syntax.sh test-linuxcnc-wasm-tooldata-common-link.sh test-linuxcnc-wasm-tooldata-link.sh test-linuxcnc-wasm-tooldata-mmap-symbols.sh test-linuxcnc-wasm-tooldata-runtime-symbols.sh ) for script in "${missing_root_scripts[@]}"; do if LINUXCNC_ROOT="$missing_root" "./$script" >"$missing_root_log" 2>&1; then echo "$script accepted missing LinuxCNC root: $missing_root" >&2 exit 1 fi if ! grep -F "missing LinuxCNC root: $missing_root" "$missing_root_log" >/dev/null; then echo "$script did not report missing LinuxCNC root clearly" >&2 sed -n '1,20p' "$missing_root_log" >&2 exit 1 fi done missing_source_root=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_missing_linuxcnc_source_root.XXXXXX") missing_source_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_linuxcnc_source.XXXXXX.log") mkdir -p "$missing_source_root/src" "$missing_source_root/include" fixed_source_scripts=( "test-linuxcnc-wasm-interp-base-link.sh:src/emc/rs274ngc/interp_base.cc" "test-linuxcnc-wasm-interp-find-link.sh:src/emc/tooldata/tooldata_common.cc" "test-linuxcnc-wasm-python-c-api-symbols.sh:src/emc/rs274ngc/interp_namedparams.cc" "test-linuxcnc-wasm-rs274ngc-pre-object.sh:src/emc/rs274ngc/rs274ngc_pre.cc" "test-linuxcnc-wasm-tooldata-common-link.sh:src/emc/tooldata/tooldata_common.cc" "test-linuxcnc-wasm-tooldata-link.sh:src/emc/tooldata/tooldata_common.cc" "test-linuxcnc-wasm-tooldata-mmap-symbols.sh:src/emc/tooldata/tooldata_mmap.cc" "test-linuxcnc-wasm-tooldata-runtime-symbols.sh:src/emc/tooldata/tooldata_db.cc" ) for script_and_path in "${fixed_source_scripts[@]}"; do script=${script_and_path%%:*} source_path=${script_and_path#*:} if LINUXCNC_ROOT="$missing_source_root" "./$script" >"$missing_source_log" 2>&1; then echo "$script accepted missing LinuxCNC source: $source_path" >&2 exit 1 fi if ! grep -F "missing LinuxCNC source: $source_path" "$missing_source_log" >/dev/null; then echo "$script did not report missing LinuxCNC source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi done missing_interp_find_root=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_missing_interp_find_source_root.XXXXXX") missing_interp_find_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_interp_find_source.XXXXXX.log") mkdir -p "$missing_interp_find_root/src/emc/tooldata" "$missing_interp_find_root/src/emc/rs274ngc" "$missing_interp_find_root/include" touch "$missing_interp_find_root/src/emc/tooldata/tooldata_common.cc" if LINUXCNC_ROOT="$missing_interp_find_root" ./test-linuxcnc-wasm-interp-find-link.sh >"$missing_interp_find_log" 2>&1; then echo "test-linuxcnc-wasm-interp-find-link.sh accepted missing LinuxCNC source: src/emc/rs274ngc/interp_find.cc" >&2 exit 1 fi if ! grep -F "missing LinuxCNC source: src/emc/rs274ngc/interp_find.cc" "$missing_interp_find_log" >/dev/null; then echo "test-linuxcnc-wasm-interp-find-link.sh did not report missing interp_find source clearly" >&2 sed -n '1,20p' "$missing_interp_find_log" >&2 exit 1 fi missing_tooldata_runtime_root=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_missing_tooldata_runtime_source_root.XXXXXX") missing_tooldata_runtime_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_tooldata_runtime_source.XXXXXX.log") mkdir -p "$missing_tooldata_runtime_root/src/emc/tooldata" "$missing_tooldata_runtime_root/include" touch "$missing_tooldata_runtime_root/src/emc/tooldata/tooldata_db.cc" if LINUXCNC_ROOT="$missing_tooldata_runtime_root" ./test-linuxcnc-wasm-tooldata-runtime-symbols.sh >"$missing_tooldata_runtime_log" 2>&1; then echo "test-linuxcnc-wasm-tooldata-runtime-symbols.sh accepted missing LinuxCNC source: src/emc/tooldata/tooldata_nml.cc" >&2 exit 1 fi if ! grep -F "missing LinuxCNC source: src/emc/tooldata/tooldata_nml.cc" "$missing_tooldata_runtime_log" >/dev/null; then echo "test-linuxcnc-wasm-tooldata-runtime-symbols.sh did not report missing tooldata_nml source clearly" >&2 sed -n '1,20p' "$missing_tooldata_runtime_log" >&2 exit 1 fi unknown_group_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_unknown_wasm_manifest_group.XXXXXX.txt") unknown_group_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_unknown_wasm_manifest_group.XXXXXX.log") printf 'bogus:src/emc/rs274ngc/interp_arc.cc:test unknown group\n' >"$unknown_group_manifest" if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$unknown_group_manifest" >"$unknown_group_log" 2>&1; then echo "build-wasm accepted unknown manifest group" >&2 exit 1 fi if ! grep -F "unknown manifest group: bogus" "$unknown_group_log" >/dev/null; then echo "build-wasm did not report unknown manifest group clearly" >&2 sed -n '1,20p' "$unknown_group_log" >&2 exit 1 fi for script in \ analyze-linuxcnc-wasm-blockers.sh \ test-linuxcnc-wasm-source-syntax.sh \ test-linuxcnc-wasm-source-objects.sh \ test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh \ test-linuxcnc-wasm-rs274ngc-pre-link.sh \ test-linuxcnc-wasm-runtime-link.sh; do if "./$script" "$unknown_group_manifest" >"$unknown_group_log" 2>&1; then echo "$script accepted unknown manifest group" >&2 exit 1 fi if ! grep -F "unknown manifest group: bogus" "$unknown_group_log" >/dev/null; then echo "$script did not report unknown manifest group clearly" >&2 sed -n '1,20p' "$unknown_group_log" >&2 exit 1 fi done blocker_scan_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_blocker_scan.XXXXXX.log") ./test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh >"$blocker_scan_log" 2>&1 blocker_report_file=$(awk '/^wrote / { print $2 }' "$blocker_scan_log") if [[ -z "$blocker_report_file" || ! -f "$blocker_report_file" ]]; then echo "wasm rs274ngc_pre blocker scan did not preserve its report file" >&2 sed -n '1,20p' "$blocker_scan_log" >&2 exit 1 fi missing_source_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_wasm_manifest_source.XXXXXX.txt") missing_source_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_wasm_manifest_source.XXXXXX.log") printf 'core:src/emc/rs274ngc/does_not_exist.cc:test missing source\n' >"$missing_source_manifest" if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then echo "build-wasm accepted missing manifest source" >&2 exit 1 fi if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$missing_source_log" >/dev/null; then echo "build-wasm did not report missing manifest source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi if ./test-linuxcnc-wasm-source-syntax.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then echo "wasm source syntax probe accepted missing manifest source" >&2 exit 1 fi if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$missing_source_log" >/dev/null; then echo "wasm source syntax probe did not report missing manifest source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi if ./test-linuxcnc-wasm-source-objects.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then echo "wasm source object probe accepted missing manifest source" >&2 exit 1 fi if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$missing_source_log" >/dev/null; then echo "wasm source object probe did not report missing manifest source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi if ./test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then echo "wasm rs274ngc_pre blocker scan accepted missing manifest source" >&2 exit 1 fi if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$missing_source_log" >/dev/null; then echo "wasm rs274ngc_pre blocker scan did not report missing manifest source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi if ./test-linuxcnc-wasm-rs274ngc-pre-link.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then echo "wasm rs274ngc_pre link probe accepted missing manifest source" >&2 exit 1 fi if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$missing_source_log" >/dev/null; then echo "wasm rs274ngc_pre link probe did not report missing manifest source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi if ./test-linuxcnc-wasm-runtime-link.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then echo "wasm runtime link probe accepted missing manifest source" >&2 exit 1 fi if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$missing_source_log" >/dev/null; then echo "wasm runtime link probe did not report missing manifest source clearly" >&2 sed -n '1,20p' "$missing_source_log" >&2 exit 1 fi empty_partition_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_empty_wasm_manifest_partition.XXXXXX.log") empty_core_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_empty_wasm_manifest_core.XXXXXX.txt") empty_blocked_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_empty_wasm_manifest_blocked.XXXXXX.txt") printf 'blocked:src/emc/tooldata/tooldata_mmap.cc:test empty core partition\n' >"$empty_core_manifest" if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$empty_core_manifest" >"$empty_partition_log" 2>&1; then echo "build-wasm accepted empty core manifest partition" >&2 exit 1 fi if ! grep -F "unexpected wasm manifest partition: core=0 blocked=1" "$empty_partition_log" >/dev/null; then echo "build-wasm did not report empty core manifest partition clearly" >&2 sed -n '1,20p' "$empty_partition_log" >&2 exit 1 fi printf 'core:src/emc/rs274ngc/interp_arc.cc:test empty blocked partition\n' >"$empty_blocked_manifest" if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$empty_blocked_manifest" >"$empty_partition_log" 2>&1; then echo "build-wasm accepted empty blocked manifest partition" >&2 exit 1 fi if ! grep -F "unexpected wasm manifest partition: core=1 blocked=0" "$empty_partition_log" >/dev/null; then echo "build-wasm did not report empty blocked manifest partition clearly" >&2 sed -n '1,20p' "$empty_partition_log" >&2 exit 1 fi bad_default_manifest_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_bad_default_wasm_manifest.XXXXXX") bad_default_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_bad_default_wasm_manifest.XXXXXX.log") linuxcnc_root_abs=$(cd "$linuxcnc_root" && pwd) cp build-wasm.sh "$bad_default_manifest_dir/build-wasm.sh" cp check-linuxcnc-inputs.sh "$bad_default_manifest_dir/check-linuxcnc-inputs.sh" cp check-linuxcnc-inputs-cached.sh "$bad_default_manifest_dir/check-linuxcnc-inputs-cached.sh" 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" 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 echo "build-wasm accepted bad default wasm manifest partition" >&2 exit 1 fi if ! grep -F "unexpected wasm manifest partition: core=1 blocked=1" "$bad_default_manifest_log" >/dev/null; then echo "build-wasm did not enforce default wasm manifest partition for no-arg entry" >&2 sed -n '1,20p' "$bad_default_manifest_log" >&2 exit 1 fi duplicate_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_manifest.XXXXXX.txt") duplicate_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_manifest.XXXXXX.log") cat >"$duplicate_manifest" <<'EOF' core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry blocked:src/emc/tooldata/tooldata_mmap.cc:blocked entry EOF if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$duplicate_manifest" >"$duplicate_manifest_log" 2>&1; then echo "build-wasm accepted duplicate manifest source" >&2 exit 1 fi if ! grep -F "duplicate manifest source: src/emc/rs274ngc/interp_arc.cc" "$duplicate_manifest_log" >/dev/null; then echo "build-wasm did not report duplicate manifest source clearly" >&2 sed -n '1,20p' "$duplicate_manifest_log" >&2 exit 1 fi comment_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_comment_wasm_manifest.XXXXXX.txt") comment_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_comment_wasm_manifest.XXXXXX.log") cat >"$comment_manifest" <<'EOF' # LinuxCNC rs274 source subset for browser-safe source-link probing. # Format: group:path:note core:src/emc/rs274ngc/interp_arc.cc:commented core entry blocked:src/emc/tooldata/tooldata_mmap.cc:commented blocked entry EOF if CNC_SIM_BUILD_WASM_SKIP_LOCK=1 ./build-wasm.sh "$comment_manifest" >"$comment_manifest_log" 2>&1; then : fi if grep -F "duplicate manifest source" "$comment_manifest_log" >/dev/null; then echo "build-wasm rejected commented manifest lines as duplicates" >&2 sed -n '1,20p' "$comment_manifest_log" >&2 exit 1 fi duplicate_source_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_source_manifest.XXXXXX.txt") duplicate_source_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_source_manifest.XXXXXX.log") cat >"$duplicate_source_manifest" <<'EOF' core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry blocked:src/emc/tooldata/tooldata_mmap.cc:blocked entry EOF if ./test-linuxcnc-wasm-source-objects.sh "$duplicate_source_manifest" >"$duplicate_source_log" 2>&1; then echo "source object probe accepted duplicate manifest source" >&2 exit 1 fi if ! grep -F "duplicate manifest source: src/emc/rs274ngc/interp_arc.cc" "$duplicate_source_log" >/dev/null; then echo "source object probe did not report duplicate manifest source clearly" >&2 sed -n '1,20p' "$duplicate_source_log" >&2 exit 1 fi duplicate_syntax_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_syntax_manifest.XXXXXX.txt") duplicate_syntax_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_syntax_manifest.XXXXXX.log") cat >"$duplicate_syntax_manifest" <<'EOF' core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry blocked:src/emc/tooldata/tooldata_mmap.cc:blocked entry EOF if ./test-linuxcnc-wasm-source-syntax.sh "$duplicate_syntax_manifest" >"$duplicate_syntax_log" 2>&1; then echo "syntax probe accepted duplicate manifest source" >&2 exit 1 fi if ! grep -F "duplicate manifest source: src/emc/rs274ngc/interp_arc.cc" "$duplicate_syntax_log" >/dev/null; then echo "syntax probe did not report duplicate manifest source clearly" >&2 sed -n '1,20p' "$duplicate_syntax_log" >&2 exit 1 fi duplicate_pre_blocker_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_pre_blocker_manifest.XXXXXX.txt") duplicate_pre_blocker_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_pre_blocker_manifest.XXXXXX.log") cat >"$duplicate_pre_blocker_manifest" <<'EOF' core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry blocked:src/emc/tooldata/tooldata_mmap.cc:blocked entry EOF if ./test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh "$duplicate_pre_blocker_manifest" >"$duplicate_pre_blocker_log" 2>&1; then echo "rs274ngc_pre blocker scan accepted duplicate manifest source" >&2 exit 1 fi if ! grep -F "duplicate manifest source: src/emc/rs274ngc/interp_arc.cc" "$duplicate_pre_blocker_log" >/dev/null; then echo "rs274ngc_pre blocker scan did not report duplicate manifest source clearly" >&2 sed -n '1,20p' "$duplicate_pre_blocker_log" >&2 exit 1 fi duplicate_pre_link_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_pre_link_manifest.XXXXXX.txt") duplicate_pre_link_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_pre_link_manifest.XXXXXX.log") cat >"$duplicate_pre_link_manifest" <<'EOF' core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry blocked:src/emc/tooldata/tooldata_mmap.cc:blocked entry EOF if ./test-linuxcnc-wasm-rs274ngc-pre-link.sh "$duplicate_pre_link_manifest" >"$duplicate_pre_link_log" 2>&1; then echo "rs274ngc_pre link probe accepted duplicate manifest source" >&2 exit 1 fi if ! grep -F "duplicate manifest source: src/emc/rs274ngc/interp_arc.cc" "$duplicate_pre_link_log" >/dev/null; then echo "rs274ngc_pre link probe did not report duplicate manifest source clearly" >&2 sed -n '1,20p' "$duplicate_pre_link_log" >&2 exit 1 fi duplicate_runtime_link_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_runtime_link_manifest.XXXXXX.txt") duplicate_runtime_link_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_duplicate_wasm_runtime_link_manifest.XXXXXX.log") cat >"$duplicate_runtime_link_manifest" <<'EOF' core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry core:src/emc/rs274ngc/interp_arc.cc:duplicate core entry blocked:src/emc/tooldata/tooldata_mmap.cc:blocked entry EOF if ./test-linuxcnc-wasm-runtime-link.sh "$duplicate_runtime_link_manifest" >"$duplicate_runtime_link_log" 2>&1; then echo "runtime link probe accepted duplicate manifest source" >&2 exit 1 fi if ! grep -F "duplicate manifest source: src/emc/rs274ngc/interp_arc.cc" "$duplicate_runtime_link_log" >/dev/null; then echo "runtime link probe did not report duplicate manifest source clearly" >&2 sed -n '1,20p' "$duplicate_runtime_link_log" >&2 exit 1 fi linuxcnc_root=$(cd "$linuxcnc_root" && pwd) default_manifest="$PWD/linuxcnc-rs274-wasm-source-files.txt" manifest_core_count=0 manifest_blocked_count=0 manifest_core_sources="$build_dir/wasm_core_sources.txt" manifest_blocked_sources="$build_dir/wasm_blocked_sources.txt" CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core > "$manifest_core_sources" CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked > "$manifest_blocked_sources" manifest_core_count=$(wc -l < "$manifest_core_sources") manifest_blocked_count=$(wc -l < "$manifest_blocked_sources") required_shim_sources="$build_dir/wasm_safe_shim_sources.txt" ./list-linuxcnc-wasm-safe-shims.sh > "$required_shim_sources" required_project_sources="$build_dir/wasm_safe_project_sources.txt" ./list-linuxcnc-wasm-safe-project-sources.sh > "$required_project_sources" if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 26 || "$manifest_blocked_count" -ne 9 ]]; then echo "unexpected wasm manifest partition: core=$manifest_core_count blocked=$manifest_blocked_count" >&2 exit 1 fi if [[ "$manifest_core_count" -eq 0 || "$manifest_blocked_count" -eq 0 ]]; then echo "unexpected wasm manifest partition: core=$manifest_core_count blocked=$manifest_blocked_count" >&2 exit 1 fi while IFS= read -r shim; do [[ -z "$shim" ]] && continue cmake_shim=${shim#core/} if ! grep -F "$cmake_shim" core/CMakeLists.txt >/dev/null; then echo "missing CMake wasm-safe shim: $cmake_shim" >&2 exit 1 fi done < "$required_shim_sources" while IFS= read -r source; do [[ -z "$source" ]] && continue cmake_source=${source#core/} if ! grep -F "$cmake_source" core/CMakeLists.txt >/dev/null; then echo "missing CMake wasm-safe project source: $cmake_source" >&2 exit 1 fi done < "$required_project_sources" grep -F "add_executable(linuxcnc_rs274_wasm_safe_probe EXCLUDE_FROM_ALL" core/CMakeLists.txt >/dev/null grep -F "wasm_shims/rs274ngc_pre_probe_main.cc" core/CMakeLists.txt >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/rs274ngc_pre.cc provides' core/wasm_shims/rs274ngc_pre_probe_main.cc >/dev/null grep -F "target_compile_definitions(linuxcnc_rs274_wasm_safe_probe" core/CMakeLists.txt >/dev/null grep -F "wasm_shims/cnc_sim_wasm_runtime_probe_main.cc" core/CMakeLists.txt >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/rs274ngc_pre.cc provides read(),' core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc >/dev/null grep -F "add_executable(cnc_sim_wasm_runtime_probe EXCLUDE_FROM_ALL" core/CMakeLists.txt >/dev/null grep -F "target_link_libraries(linuxcnc_rs274_wasm_safe_probe PRIVATE fmt)" core/CMakeLists.txt >/dev/null grep -F "target_link_libraries(cnc_sim_wasm_runtime_probe PRIVATE fmt)" core/CMakeLists.txt >/dev/null if grep -F "target_link_libraries(cnc_sim_wasm PRIVATE fmt)" core/CMakeLists.txt >/dev/null; then echo "wasm target still links host fmt library instead of using header-only fmt" >&2 exit 1 fi grep -F "add_custom_target(linuxcnc_rs274_wasm_blocked_sources" core/CMakeLists.txt >/dev/null grep -F "LinuxCNC source root does not exist" core/CMakeLists.txt >/dev/null grep -F 'if(NOT IS_DIRECTORY "${CNC_SIM_LINUXCNC_ROOT_ABS}")' core/CMakeLists.txt >/dev/null grep -F "Missing LinuxCNC wasm source manifest" core/CMakeLists.txt >/dev/null grep -F 'if(NOT EXISTS "${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}")' core/CMakeLists.txt >/dev/null grep -F "LinuxCNC wasm source manifest is not a file" core/CMakeLists.txt >/dev/null grep -F 'if(IS_DIRECTORY "${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}")' core/CMakeLists.txt >/dev/null grep -F "Bad LinuxCNC wasm source manifest line" core/CMakeLists.txt >/dev/null grep -F 'manifest_group STREQUAL "header"' core/CMakeLists.txt >/dev/null grep -F 'manifest_group STREQUAL "metadata"' core/CMakeLists.txt >/dev/null grep -F 'manifest_group STREQUAL "blocked-header"' core/CMakeLists.txt >/dev/null grep -F "LinuxCNC wasm manifest source does not exist" core/CMakeLists.txt >/dev/null grep -F 'if(NOT EXISTS "${manifest_source}")' core/CMakeLists.txt >/dev/null grep -F "LinuxCNC wasm manifest source is not a file" core/CMakeLists.txt >/dev/null grep -F 'if(IS_DIRECTORY "${manifest_source}")' core/CMakeLists.txt >/dev/null awk ' /set\(manifest_source/ { manifest_source = NR } /Unknown LinuxCNC wasm source manifest group/ { unknown_group = NR } END { exit !(unknown_group && manifest_source && unknown_group < manifest_source) } ' core/CMakeLists.txt grep -F "LinuxCNC wasm source manifest has no core entries" core/CMakeLists.txt >/dev/null grep -F "LinuxCNC wasm source manifest has no blocked entries" core/CMakeLists.txt >/dev/null grep -F "WASM builds must enable CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE so LinuxCNC rs274 sources are linked" core/CMakeLists.txt >/dev/null grep -F -- '-DCNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE=ON' build-wasm.sh >/dev/null grep -F 'if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)' core/CMakeLists.txt >/dev/null grep -F 'list(APPEND cnc_sim_core_sources ${cnc_sim_linuxcnc_rs274_backend_sources})' core/CMakeLists.txt >/dev/null grep -F 'set(cnc_sim_linuxcnc_kinematics_c_sources' core/CMakeLists.txt >/dev/null grep -F 'project(cnc_sim_wasm_core LANGUAGES C CXX)' core/CMakeLists.txt >/dev/null grep -F 'set(cnc_sim_wasm_safe_preinclude_options "SHELL:-include wctype.h")' core/CMakeLists.txt >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_internal.hh maps _() to' core/wasm_shims/gettext_shim.cc >/dev/null grep -F 'if(EMSCRIPTEN)' core/CMakeLists.txt >/dev/null grep -F 'list(APPEND cnc_sim_wasm_safe_preinclude_options "SHELL:-include libgen.h")' core/CMakeLists.txt >/dev/null grep -F 'find_path(CNC_SIM_FMT_INCLUDE_DIR fmt/format.h' core/CMakeLists.txt >/dev/null grep -F 'NO_CMAKE_FIND_ROOT_PATH' core/CMakeLists.txt >/dev/null grep -F 'list(APPEND cnc_sim_wasm_safe_preinclude_options "SHELL:-idirafter ${CNC_SIM_FMT_INCLUDE_DIR}")' core/CMakeLists.txt >/dev/null grep -F 'FMT_HEADER_ONLY=1' core/CMakeLists.txt >/dev/null grep -F '${CNC_SIM_FMT_INCLUDE_DIR}' core/CMakeLists.txt >/dev/null grep -F 'target_compile_options(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE' core/CMakeLists.txt >/dev/null grep -F '${cnc_sim_wasm_safe_preinclude_options}' core/CMakeLists.txt >/dev/null grep -F 'set(cnc_sim_wasm_safe_section_options -ffunction-sections -fdata-sections)' core/CMakeLists.txt >/dev/null grep -F 'set(cnc_sim_wasm_safe_link_options "-Wl,--gc-sections")' core/CMakeLists.txt >/dev/null grep -F 'target_link_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_link_options})' core/CMakeLists.txt >/dev/null grep -F 'target_link_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_link_options})' core/CMakeLists.txt >/dev/null grep -F 'target_compile_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null grep -F 'target_compile_options(cnc_sim_objects PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null grep -F 'target_compile_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null test -f core/wasm_shims/boost/noncopyable.hpp grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_base.hh derives InterpBase' core/wasm_shims/boost/noncopyable.hpp >/dev/null grep -F 'class noncopyable' core/wasm_shims/boost/noncopyable.hpp >/dev/null grep -F 'noncopyable(const noncopyable &) = delete;' core/wasm_shims/boost/noncopyable.hpp >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_python.cc,' core/wasm_shims/boost/python/object.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_o_word.cc, interp_namedparams.cc, and' core/wasm_shims/boost/python/list.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_o_word.cc, interp_namedparams.cc, and' core/wasm_shims/boost/python/dict.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_o_word.cc, interp_namedparams.cc, and' core/wasm_shims/boost/python/tuple.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_python.cc, interp_namedparams.cc,' core/wasm_shims/boost/python/extract.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_python.cc, rs274ngc_pre.cc, and' core/wasm_shims/boost/python/import.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_python.cc and python_plugin.cc use' core/wasm_shims/boost/python/str.hpp >/dev/null grep -F 'LinuxCNC source basis: rs274ngc_pre.cc uses boost::python::scope' core/wasm_shims/boost/python/scope.hpp >/dev/null grep -F 'LinuxCNC source basis: interpmodule.cc, pyblock.cc, pyemctypes.cc, and' core/wasm_shims/boost/python/class.hpp >/dev/null grep -F 'LinuxCNC source basis: canonmodule.cc and interpmodule.cc include' core/wasm_shims/boost/python/def.hpp >/dev/null grep -F 'LinuxCNC source basis: canonmodule.cc and interpmodule.cc use' core/wasm_shims/boost/python/module.hpp >/dev/null grep -F 'LinuxCNC source basis: canonmodule.cc, boost_pyenum_macros.hh, and array1.hh' core/wasm_shims/boost/python/enum.hpp >/dev/null grep -F 'LinuxCNC source basis: interpmodule.cc uses' core/wasm_shims/boost/python/exception_translator.hpp >/dev/null grep -F 'LinuxCNC source basis: pyarrays.cc uses boost::python::return_internal_reference' core/wasm_shims/boost/python/return_internal_reference.hpp >/dev/null grep -F 'LinuxCNC source basis: pyarrays.cc includes boost/python/detail/caller.hpp' core/wasm_shims/boost/python/detail/caller.hpp >/dev/null grep -F 'LinuxCNC source basis: array1.hh includes boost/python/converter/registry.hpp' core/wasm_shims/boost/python/converter/registry.hpp >/dev/null grep -F 'LinuxCNC source basis: array1.hh includes boost/python/object/class_detail.hpp' core/wasm_shims/boost/python/object/class_detail.hpp >/dev/null grep -F 'LinuxCNC source basis: interp_internal.hh forward-declares Boost.Python' core/wasm_shims/boost/python/object_fwd.hpp >/dev/null grep -F 'LinuxCNC source basis: interpmodule.cc, pyblock.cc, pyparamclass.cc, and' core/wasm_shims/boost/python/suite/indexing/map_indexing_suite.hpp >/dev/null test -f core/wasm_shims/libgen.h grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_o_word.cc uses basename()' core/wasm_shims/libgen.h >/dev/null grep -F 'inline char *basename(const char *path)' core/wasm_shims/libgen.h >/dev/null grep -F 'return basename(const_cast(path));' core/wasm_shims/libgen.h >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/gcodemodule.cc includes' core/wasm_shims/structmember.h >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_base.cc uses dlopen(),' core/wasm_shims/dlfcn.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_base.cc native loader flags.' core/wasm_shims/dlfcn.h >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/gcodemodule.cc defines _task=0' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/task/taskclass.cc and' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/interp_namedparams.cc fetch_hal_param()' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/rs274ngc/rs274ngc_pre.cc uses wordexp()' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null grep -F 'extern "C" int wordexp(const char *words, wordexp_t *pwordexp, int)' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null grep -F 'extern "C" void wordfree(wordexp_t *pwordexp)' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null grep -F 'LinuxCNC source basis: src/emc/sai/dummyemcstat.cc defines the same' core/wasm_shims/emc_status_shim.cc >/dev/null grep -F 'EMC_STAT *emcStatus = new EMC_STAT;' core/wasm_shims/emc_status_shim.cc >/dev/null grep -F 'LinuxCNC source basis: src/libnml/nml/nmlmsg.cc and stat_msg.cc provide' core/wasm_shims/nml_status_shim.cc >/dev/null grep -F 'wasm_shims/nml_status_shim.cc' core/CMakeLists.txt >/dev/null grep -F 'LinuxCNC source basis: src/libnml/rcs/rcs_print.cc provides these RCS' core/wasm_shims/rcs_print_shim.cc >/dev/null grep -F 'wasm_shims/rcs_print_shim.cc' core/CMakeLists.txt >/dev/null grep -F 'LinuxCNC source basis: src/rtapi/uspace_common.h provides rtapi_snprintf()' core/wasm_shims/rtapi_compat.cc >/dev/null grep -F '$' core/CMakeLists.txt >/dev/null grep -F '$' core/CMakeLists.txt >/dev/null grep -F 'CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND' core/CMakeLists.txt >/dev/null grep -F '#ifndef CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE' core/src/linuxcnc_rs274_backend.cpp >/dev/null fi if ! command -v cmake >/dev/null 2>&1; then echo "cmake not found; skipping linuxcnc wasm-safe CMake probe target" exit 0 fi if [[ "$configure_cmake" -eq 1 ]]; then cmake -S core -B "$build_dir" \ -DCMAKE_BUILD_TYPE=Release \ -DCNC_SIM_LINUXCNC_ROOT="$linuxcnc_root" \ -DCNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST="$manifest" \ -DCNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE=ON \ "${cmake_compiler_launcher_args[@]}" fi cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe cnc_sim_wasm_runtime_probe --parallel "$build_jobs" "$build_dir/linuxcnc_rs274_wasm_safe_probe" "$build_dir/cnc_sim_wasm_runtime_probe" echo "linuxcnc wasm-safe CMake probe target passed"