每轮只推进合理适量的上下文、禁止顺手扩功能 smoke:源码链接构建约束

This commit is contained in:
cnc
2026-06-01 19:54:04 +08:00
parent 6f9431a389
commit 5ec10abf38
41 changed files with 3301 additions and 670 deletions

View File

@@ -6,7 +6,8 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh "$manifest"
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
python_blockers=()
core_python_sources=()
@@ -53,19 +54,38 @@ wasm_safe_shim_in_build() {
return 1
}
core_source_output=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core)
mapfile -t core_sources <<<"$core_source_output"
blocked_source_output=$(./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked)
mapfile -t blocked_sources <<<"$blocked_source_output"
core_sources=()
blocked_sources=()
while IFS=: read -r group path note extra; do
case "$group" in
""|\#*)
continue
;;
core)
core_sources+=("$path")
;;
blocked)
blocked_sources+=("$path")
;;
header|metadata|blocked-header)
;;
*)
echo "unknown manifest group: $group" >&2
exit 1
;;
esac
done < "$manifest"
core_count=${#core_sources[@]}
blocked_count=${#blocked_sources[@]}
scan_source() {
local group=$1
local path=$2
full_path=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh \
--missing-message "missing manifest source" \
"$path")
full_path="$linuxcnc_root/$path"
if [[ ! -f "$full_path" ]]; then
echo "missing manifest source: $path" >&2
exit 1
fi
if [[ "$group" == "blocked" ]]; then
if ! replacement=$(blocked_replacement_for "$path"); then
echo "missing blocked replacement mapping: $path" >&2

View File

@@ -0,0 +1,101 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
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
cache_dir=${CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR-build/native-bridge-object-cache}
if [[ -z "$cache_dir" ]]; then
echo "CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR must not be empty" >&2
exit 1
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
exec 8>"$cache_dir/native-bridge-objects.lock"
flock 8
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$cache_dir/preflight-cache"}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
source_output=$(./list-linuxcnc-bridge-smoke-project-sources.sh)
mapfile -t sources <<<"$source_output"
common_flag_output=$(
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" \
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh \
--no-ulapi \
--core-include \
--core-src
)
mapfile -t common_flags <<<"$common_flag_output"
objects=()
source_index=0
for source in "${sources[@]}"; do
objects+=("$cache_dir/source_${source_index}.o")
source_index=$((source_index + 1))
done
signature="$cache_dir/native-bridge-objects.signature"
next_signature="$cache_dir/native-bridge-objects.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$cache_dir"/source_*.o "$cache_dir"/source_*.d
fi
mv "$next_signature" "$signature"
makefile="$cache_dir/native-bridge-objects.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: $(OBJECTS)\n\n'
source_index=0
for source in "${sources[@]}"; do
printf '%s: %s\n' "${objects[$source_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' \
"${objects[$source_index]}" "$source" "${objects[$source_index]}"
source_index=$((source_index + 1))
done
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
printf '%s\n' "${objects[@]}"

145
build-linuxcnc-wasm-link-probe.sh Executable file
View File

@@ -0,0 +1,145 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
usage() {
echo "usage: $0 --mode rs274ngc-pre|runtime [manifest]" >&2
}
mode=
manifest=linuxcnc-rs274-wasm-source-files.txt
while [[ "$#" -gt 0 ]]; do
case "$1" in
--mode)
if [[ "$#" -lt 2 ]]; then
echo "missing --mode value" >&2
exit 1
fi
mode=$2
shift 2
;;
--help|-h)
usage
exit 0
;;
--*)
usage
echo "unknown wasm link probe option: $1" >&2
exit 1
;;
*)
manifest=$1
shift
;;
esac
done
case "$mode" in
rs274ngc-pre|runtime)
;;
"")
usage
echo "missing --mode" >&2
exit 1
;;
*)
usage
echo "unknown wasm link probe mode: $mode" >&2
exit 1
;;
esac
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
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
cache_dir=${CNC_SIM_WASM_LINK_PROBE_CACHE_DIR-build/wasm-link-probe-cache}
if [[ -z "$cache_dir" ]]; then
echo "CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not be empty" >&2
exit 1
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_WASM_LINK_PROBE_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$cache_dir/preflight-cache"}
object_mode=$mode
main_source=core/wasm_shims/rs274ngc_pre_probe_main.cc
target_name=rs274ngc_pre_probe
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile core20-sections)
mapfile -t common_flags <<<"$common_flag_output"
case "$mode" in
runtime)
object_mode=runtime
main_source=core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc
target_name=cnc_sim_wasm_runtime_probe
common_flags+=(-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND)
;;
esac
object_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./build-linuxcnc-wasm-probe-objects.sh --mode "$object_mode" "$manifest")
mapfile -t objects <<<"$object_output"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
mode_dir="$cache_dir/$mode"
mkdir -p "$mode_dir"
exec 8>"$mode_dir/link.lock"
flock 8
main_object="$mode_dir/main.o"
target="$mode_dir/$target_name"
signature="$mode_dir/link.signature"
next_signature="$mode_dir/link.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'MODE=%s\n' "$mode"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'MAIN_SOURCE=%s\n' "$main_source"
printf 'OBJECTS:\n'
printf '%s\n' "${objects[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$main_object" "$main_object.d" "$target" "$mode_dir/runtime.symbols"
fi
mv "$next_signature" "$signature"
makefile="$mode_dir/link.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf '.PHONY: all\n'
printf 'all: %s\n\n' "$target"
printf '%s: %s\n' "$main_object" "$main_source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "$main_object" "$main_source" "$main_object"
printf '%s: $(OBJECTS) %s\n' "$target" "$main_object"
printf '\t@$(CXX) $(OBJECTS) %s -Wl,--gc-sections -lfmt -o %s\n\n' "$main_object" "$target"
printf '\n-include %s.d\n' "$main_object"
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
printf '%s\n' "$target"

View File

@@ -0,0 +1,196 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
usage() {
echo "usage: $0 --mode source-objects|rs274ngc-pre|runtime [manifest]" >&2
}
mode=
manifest=linuxcnc-rs274-wasm-source-files.txt
while [[ "$#" -gt 0 ]]; do
case "$1" in
--mode)
if [[ "$#" -lt 2 ]]; then
echo "missing --mode value" >&2
exit 1
fi
mode=$2
shift 2
;;
--help|-h)
usage
exit 0
;;
--*)
usage
echo "unknown wasm probe object cache option: $1" >&2
exit 1
;;
*)
manifest=$1
shift
;;
esac
done
case "$mode" in
source-objects|rs274ngc-pre|runtime)
;;
"")
usage
echo "missing --mode" >&2
exit 1
;;
*)
usage
echo "unknown wasm probe object cache mode: $mode" >&2
exit 1
;;
esac
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
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
cache_dir=${CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR-build/wasm-probe-object-cache}
if [[ -z "$cache_dir" ]]; then
echo "CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not be empty" >&2
exit 1
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_WASM_PROBE_OBJECT_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$cache_dir/preflight-cache"}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest" --require-rs274-complete
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
common_flag_profile=core20-sections
case "$mode" in
source-objects)
common_flag_profile=core20
;;
esac
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile "$common_flag_profile")
mapfile -t common_flags <<<"$common_flag_output"
case "$mode" in
runtime)
common_flags+=(-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND)
;;
esac
sources=()
shim_output=$(./list-linuxcnc-wasm-safe-shims.sh)
mapfile -t shim_sources <<<"$shim_output"
sources+=("${shim_sources[@]}")
case "$mode" in
source-objects)
;;
rs274ngc-pre)
project_source_output=$(./list-linuxcnc-wasm-safe-project-sources.sh)
if [[ -n "$project_source_output" ]]; then
mapfile -t project_sources <<<"$project_source_output"
sources+=("${project_sources[@]}")
fi
;;
runtime)
core_source_output=$(./list-cmake-set-sources.sh cnc_sim_core_sources core/)
mapfile -t core_sources <<<"$core_source_output"
sources+=("${core_sources[@]}")
backend_source_output=$(./list-cmake-set-sources.sh cnc_sim_linuxcnc_rs274_backend_sources core/)
mapfile -t backend_sources <<<"$backend_source_output"
sources+=("${backend_sources[@]}")
;;
esac
source_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full)
mapfile -t linuxcnc_sources <<<"$source_output"
sources+=("${linuxcnc_sources[@]}")
for source in "${sources[@]}"; do
if [[ -z "$source" ]]; then
echo "wasm probe object source list contains an empty path" >&2
exit 1
fi
done
mode_dir="$cache_dir/$mode"
mkdir -p "$mode_dir"
exec 8>"$mode_dir/objects.lock"
flock 8
objects=()
object_index=0
for source in "${sources[@]}"; do
objects+=("$mode_dir/source_${object_index}.o")
object_index=$((object_index + 1))
done
signature="$mode_dir/objects.signature"
next_signature="$mode_dir/objects.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'MODE=%s\n' "$mode"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$mode_dir"/source_*.o "$mode_dir"/source_*.d
fi
mv "$next_signature" "$signature"
makefile="$mode_dir/objects.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: $(OBJECTS)\n\n'
object_index=0
for source in "${sources[@]}"; do
source_flags=()
case "$source" in
core/src/linuxcnc_corexykins_adapter.c|core/src/linuxcnc_genserfuncs_adapter.c|core/src/linuxcnc_xyzab_tdr_kins_adapter.c)
source_flags+=(-fpermissive)
;;
esac
printf '%s: %s\n' "${objects[$object_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS)'
printf ' %s' "${source_flags[@]}"
printf ' -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
object_index=$((object_index + 1))
done
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
printf '%s\n' "${objects[@]}"

View File

@@ -0,0 +1,196 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
usage() {
echo "usage: $0 --mode tooldata-link|tooldata-common-link|interp-base-link|python-plugin-link|rs274ngc-pre-object" >&2
}
mode=
while [[ "$#" -gt 0 ]]; do
case "$1" in
--mode)
if [[ "$#" -lt 2 ]]; then
echo "missing --mode value" >&2
exit 1
fi
mode=$2
shift 2
;;
--help|-h)
usage
exit 0
;;
*)
usage
echo "unknown wasm standalone probe option: $1" >&2
exit 1
;;
esac
done
case "$mode" in
tooldata-link|tooldata-common-link|interp-base-link|python-plugin-link|rs274ngc-pre-object)
;;
"")
usage
echo "missing --mode" >&2
exit 1
;;
*)
usage
echo "unknown wasm standalone probe mode: $mode" >&2
exit 1
;;
esac
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
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
cache_dir=${CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR-build/wasm-standalone-probe-cache}
if [[ -z "$cache_dir" ]]; then
echo "CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not be empty" >&2
exit 1
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$cache_dir/preflight-cache"}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
common_flag_args=()
sources=()
target_name=
case "$mode" in
tooldata-link|tooldata-common-link)
if [[ "$mode" == "tooldata-common-link" ]]; then
common_flag_args+=(--tooldata-include)
fi
tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc)
tooldata_runtime_stubs_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_runtime_stubs.cc)
tooldata_common_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/tooldata/tooldata_common.cc)
sources+=(
"$tooldata_common_source"
"$tooldata_mmap_backend_shim"
"$tooldata_runtime_stubs_shim"
)
if [[ "$mode" == "tooldata-link" ]]; then
sources+=(core/wasm_shims/tooldata/tooldata_probe_main.cc)
target_name=tooldata_probe
else
sources+=(core/wasm_shims/tooldata/tooldata_common_probe_main.cc)
target_name=tooldata_common_probe
fi
;;
interp-base-link)
dlfcn_shim=$(./list-linuxcnc-wasm-safe-shims.sh dlfcn.cc)
interp_base_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/rs274ngc/interp_base.cc)
sources+=(
"$dlfcn_shim"
"$interp_base_source"
core/wasm_shims/interp_base_probe_main.cc
)
target_name=interp_base_probe
;;
python-plugin-link)
python_plugin_shim=$(./list-linuxcnc-wasm-safe-shims.sh python_plugin.cc)
sources+=(
"$python_plugin_shim"
core/wasm_shims/pythonplugin/python_plugin_probe_main.cc
)
target_name=python_plugin_probe
;;
rs274ngc-pre-object)
rs274ngc_pre_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/rs274ngc/rs274ngc_pre.cc)
sources+=("$rs274ngc_pre_source")
target_name=rs274ngc_pre.o
;;
esac
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh "${common_flag_args[@]}")
mapfile -t common_flags <<<"$common_flag_output"
mode_dir="$cache_dir/$mode"
mkdir -p "$mode_dir"
exec 8>"$mode_dir/probe.lock"
flock 8
objects=()
object_index=0
for source in "${sources[@]}"; do
objects+=("$mode_dir/source_${object_index}.o")
object_index=$((object_index + 1))
done
target="$mode_dir/$target_name"
if [[ "$mode" == "rs274ngc-pre-object" ]]; then
target=${objects[0]}
fi
signature="$mode_dir/probe.signature"
next_signature="$mode_dir/probe.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MODE=%s\n' "$mode"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$mode_dir"/source_*.o "$mode_dir"/source_*.d "$target"
fi
mv "$next_signature" "$signature"
makefile="$mode_dir/probe.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: %s\n\n' "$target"
object_index=0
for source in "${sources[@]}"; do
printf '%s: %s\n' "${objects[$object_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' \
"${objects[$object_index]}" "$source" "${objects[$object_index]}"
object_index=$((object_index + 1))
done
if [[ "$mode" != "rs274ngc-pre-object" ]]; then
printf '%s: $(OBJECTS)\n' "$target"
printf '\t@$(CXX) $(OBJECTS) -o %s\n\n' "$target"
fi
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
printf '%s\n' "$target"

View File

@@ -10,15 +10,18 @@ if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&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
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
preflight_cache_dir=build/wasm-preflight-cache
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
default_manifest="$PWD/linuxcnc-rs274-wasm-source-files.txt"
@@ -37,6 +40,51 @@ count_nonempty_lines() {
printf '%s\n' "$count"
}
parallel_probe_labels=()
parallel_probe_logs=()
parallel_probe_pids=()
run_parallel_wasm_probe() {
local label=$1
shift
local probe_index=${#parallel_probe_pids[@]}
local log_dir=build/wasm-preflight-cache/parallel-probe-logs
local log="$log_dir/probe_${probe_index}.log"
mkdir -p "$log_dir"
(
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" "$@"
) >"$log" 2>&1 &
parallel_probe_labels+=("$label")
parallel_probe_logs+=("$log")
parallel_probe_pids+=("$!")
}
wait_parallel_wasm_probes() {
local failed=0
local probe_index
local status
for probe_index in "${!parallel_probe_pids[@]}"; do
echo "${parallel_probe_labels[$probe_index]}"
if wait "${parallel_probe_pids[$probe_index]}"; then
cat "${parallel_probe_logs[$probe_index]}"
else
status=$?
cat "${parallel_probe_logs[$probe_index]}" >&2 || true
echo "${parallel_probe_labels[$probe_index]} failed with status $status" >&2
failed=1
fi
done
parallel_probe_labels=()
parallel_probe_logs=()
parallel_probe_pids=()
if [[ "$failed" -ne 0 ]]; then
exit 1
fi
}
# This script writes fixed build and public artifact paths, so serialize it.
if [[ "${CNC_SIM_BUILD_WASM_SKIP_LOCK:-0}" != "1" ]]; then
exec 9>"${TMPDIR:-/tmp}/cnc_sim_build_wasm.lock"
@@ -45,8 +93,8 @@ fi
manifest_core_count=0
manifest_blocked_count=0
manifest_core_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core)
manifest_blocked_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked)
manifest_core_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core)
manifest_blocked_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked)
manifest_core_count=$(count_nonempty_lines "$manifest_core_output")
manifest_blocked_count=$(count_nonempty_lines "$manifest_blocked_output")
@@ -58,55 +106,39 @@ if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 25
echo "unexpected wasm manifest partition: core=$manifest_core_count blocked=$manifest_blocked_count" >&2
exit 1
fi
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest" --require-rs274-complete
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest" --require-rs274-complete
echo "LinuxCNC wasm blocker scan"
./test-linuxcnc-wasm-blockers.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-blockers.sh "$manifest"
echo "LinuxCNC wasm-safe source syntax probe"
./test-linuxcnc-wasm-source-syntax.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-source-syntax.sh "$manifest"
echo "LinuxCNC wasm-safe source object probe"
./test-linuxcnc-wasm-source-objects.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-source-objects.sh "$manifest"
echo "LinuxCNC wasm-safe CMake probe target"
./test-linuxcnc-wasm-cmake-safe-probe.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-cmake-safe-probe.sh "$manifest"
echo "LinuxCNC wasm tooldata shim link probe"
./test-linuxcnc-wasm-tooldata-link.sh
echo "LinuxCNC wasm tooldata_common link probe"
./test-linuxcnc-wasm-tooldata-common-link.sh
echo "LinuxCNC wasm tooldata_mmap symbol probe"
./test-linuxcnc-wasm-tooldata-mmap-symbols.sh
echo "LinuxCNC wasm tooldata runtime symbol probe"
./test-linuxcnc-wasm-tooldata-runtime-symbols.sh
echo "LinuxCNC wasm interp_base link probe"
./test-linuxcnc-wasm-interp-base-link.sh
echo "LinuxCNC wasm interp_find link probe"
./test-linuxcnc-wasm-interp-find-link.sh
echo "LinuxCNC wasm python_plugin link probe"
./test-linuxcnc-wasm-python-plugin-link.sh
echo "LinuxCNC wasm Python C API symbol probe"
./test-linuxcnc-wasm-python-c-api-symbols.sh
echo "LinuxCNC wasm rs274ngc_pre object probe"
./test-linuxcnc-wasm-rs274ngc-pre-object.sh
run_parallel_wasm_probe "LinuxCNC wasm tooldata shim link probe" ./test-linuxcnc-wasm-tooldata-link.sh
run_parallel_wasm_probe "LinuxCNC wasm tooldata_common link probe" ./test-linuxcnc-wasm-tooldata-common-link.sh
run_parallel_wasm_probe "LinuxCNC wasm tooldata_mmap symbol probe" ./test-linuxcnc-wasm-tooldata-mmap-symbols.sh
run_parallel_wasm_probe "LinuxCNC wasm tooldata runtime symbol probe" ./test-linuxcnc-wasm-tooldata-runtime-symbols.sh
run_parallel_wasm_probe "LinuxCNC wasm interp_base link probe" ./test-linuxcnc-wasm-interp-base-link.sh
run_parallel_wasm_probe "LinuxCNC wasm interp_find link probe" ./test-linuxcnc-wasm-interp-find-link.sh
run_parallel_wasm_probe "LinuxCNC wasm python_plugin link probe" ./test-linuxcnc-wasm-python-plugin-link.sh
run_parallel_wasm_probe "LinuxCNC wasm Python C API symbol probe" ./test-linuxcnc-wasm-python-c-api-symbols.sh
run_parallel_wasm_probe "LinuxCNC wasm rs274ngc_pre object probe" ./test-linuxcnc-wasm-rs274ngc-pre-object.sh
wait_parallel_wasm_probes
echo "LinuxCNC wasm rs274ngc_pre link blocker scan"
./test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh "$manifest"
echo "LinuxCNC wasm rs274ngc_pre link probe"
./test-linuxcnc-wasm-rs274ngc-pre-link.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-rs274ngc-pre-link.sh "$manifest"
echo "LinuxCNC wasm runtime link probe"
./test-linuxcnc-wasm-runtime-link.sh "$manifest"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-runtime-link.sh "$manifest"
missing_tools=()
for required_tool in cmake emcmake emcc node; do
@@ -120,14 +152,37 @@ if ((${#missing_tools[@]} > 0)); then
exit 1
fi
wasm_build_signature=build/wasm/wasm-build.signature
wasm_build_next_signature=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_build.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'
} > "$wasm_build_next_signature"
configure_wasm=1
if [[ ! -f "$wasm_build_signature" ]] || ! cmp -s "$wasm_build_signature" "$wasm_build_next_signature"; then
mkdir -p build/wasm
elif [[ -f build/wasm/CMakeCache.txt ]]; then
configure_wasm=0
fi
if [[ "$configure_wasm" == "1" ]]; then
emcmake cmake -S core -B build/wasm \
-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[@]}"
cmake --build build/wasm --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"
cmake --build build/wasm --target cnc_sim_wasm --parallel "$build_jobs"
fi
mv "$wasm_build_next_signature" "$wasm_build_signature"
cmake --build build/wasm --target cnc_sim_wasm_runtime_probe cnc_sim_wasm --parallel "$build_jobs"
mkdir -p web/public
cp build/wasm/cnc_sim.js web/public/cnc_sim.js
cp build/wasm/cnc_sim.wasm web/public/cnc_sim.wasm

131
check-linuxcnc-inputs-cached.sh Executable file
View File

@@ -0,0 +1,131 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-}
check_args=("$@")
if [[ "${1:-}" == "--cache-dir" ]]; then
if [[ "$#" -lt 2 ]]; then
echo "missing --cache-dir value" >&2
exit 1
fi
cache_dir=$2
shift 2
check_args=("$@")
fi
manifest=${1:-}
require_complete=${2:-}
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
if [[ -z "$cache_dir" ]]; then
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "${check_args[@]}"
exit 0
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_PREFLIGHT_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_PREFLIGHT_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
exec 8>"$cache_dir/check-linuxcnc-inputs.lock"
flock 8
if [[ ! -d "$linuxcnc_root" ]]; then
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "${check_args[@]}"
exit 0
fi
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
manifest_key=ROOT_ONLY
manifest_path=
if [[ -n "$manifest" && "$manifest" != "--root-only" ]]; then
if [[ ! -f "$manifest" ]]; then
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "${check_args[@]}"
exit 0
fi
manifest_path=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
manifest_key=$(printf '%s' "$manifest_path" | sha256sum | awk '{ print $1 }')
fi
safe_require=${require_complete:-none}
safe_require=${safe_require//[^A-Za-z0-9_.-]/_}
args_key=$(
{
printf 'ARGS='
printf ' %q' "${check_args[@]}"
printf '\n'
} | sha256sum | awk '{ print $1 }'
)
cache_file="$cache_dir/check-linuxcnc-inputs.${manifest_key}.${safe_require}.${args_key}.signature"
next_signature=$(mktemp "$cache_file.next.XXXXXX")
write_source_stat_signature() {
local source_path
[[ -z "$manifest_path" ]] && return 0
while IFS=: read -r group path note extra; do
case "$group" in
""|\#*)
continue
;;
esac
[[ -z "${path:-}" ]] && continue
source_path="$linuxcnc_root/$path"
if [[ ! -f "$source_path" ]]; then
return 1
fi
stat -c 'SOURCE=%n:%s:%y' "$source_path"
done < "$manifest_path"
}
write_complete_mode_signature() {
case "$require_complete" in
--require-rs274-complete)
find "$linuxcnc_root/src/emc/rs274ngc" -maxdepth 1 -type f \
-printf 'RS274=%P:%s:%T@\n' | sort
;;
--require-kinematics-complete)
for source_dir in \
"$linuxcnc_root/src/emc/kinematics" \
"$linuxcnc_root/src/libnml/posemath" \
"$linuxcnc_root/configs/sim"; do
[[ -d "$source_dir" ]] || return 1
find "$source_dir" -type f -printf "KIN=$source_dir/%P:%s:%T@\n" | sort
done
;;
esac
}
if ! {
printf 'CHECK_SCRIPT='
sha256sum check-linuxcnc-inputs.sh
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'ARGS='
printf ' %q' "${check_args[@]}"
printf '\n'
if [[ -n "$manifest_path" ]]; then
printf 'MANIFEST_PATH=%s\n' "$manifest_path"
printf 'MANIFEST='
sha256sum "$manifest_path"
write_source_stat_signature
fi
write_complete_mode_signature
} > "$next_signature"; then
rm -f "$next_signature"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "${check_args[@]}"
exit 0
fi
if [[ -f "$cache_file" ]] && cmp -s "$cache_file" "$next_signature"; then
rm -f "$next_signature"
exit 0
fi
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "${check_args[@]}"
mv "$next_signature" "$cache_file"

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-}
check_args=("$@")
if [[ "${1:-}" == "--cache-dir" ]]; then
if [[ "$#" -lt 2 ]]; then
echo "missing --cache-dir value" >&2
exit 1
fi
cache_dir=$2
shift 2
check_args=("$@")
fi
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
manifest=${1:-linuxcnc-kinematics-source-files.txt}
if [[ -z "$cache_dir" ]]; then
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table.sh "${check_args[@]}"
exit 0
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_PREFLIGHT_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_PREFLIGHT_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
exec 8>"$cache_dir/check-linuxcnc-switchkins-remap-table.lock"
flock 8
if [[ ! -d "$linuxcnc_root" || ! -f "$manifest" ]]; then
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table.sh "${check_args[@]}"
exit 0
fi
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
manifest_path=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
manifest_key=$(printf '%s' "$manifest_path" | sha256sum | awk '{ print $1 }')
args_key=$(
{
printf 'ARGS='
printf ' %q' "${check_args[@]}"
printf '\n'
} | sha256sum | awk '{ print $1 }'
)
cache_file="$cache_dir/check-linuxcnc-switchkins-remap-table.${manifest_key}.${args_key}.signature"
next_signature=$(mktemp "$cache_file.next.XXXXXX")
write_manifest_source_stats() {
local source_path
while IFS=: read -r group path note extra; do
case "$group" in
""|\#*)
continue
;;
esac
[[ -z "${path:-}" ]] && continue
source_path="$linuxcnc_root/$path"
if [[ ! -f "$source_path" ]]; then
return 1
fi
stat -c 'SOURCE=%n:%s:%y' "$source_path"
done < "$manifest_path"
}
write_project_output_hashes() {
local project_output
for project_output in \
core/src/linuxcnc_switchkins_remap_table.inc \
core/tests/linuxcnc_switchkins_remap_config_cases.inc \
web/public/linuxcnc_switchkins_remap_config_cases.json; do
[[ -f "$project_output" ]] || return 1
sha256sum "$project_output"
done
}
if ! {
printf 'CHECK_SCRIPT='
sha256sum check-linuxcnc-switchkins-remap-table.sh
printf 'GENERATOR_SCRIPT='
sha256sum generate-linuxcnc-switchkins-remap-table.sh
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'ARGS='
printf ' %q' "${check_args[@]}"
printf '\n'
printf 'MANIFEST_PATH=%s\n' "$manifest_path"
printf 'MANIFEST='
sha256sum "$manifest_path"
write_manifest_source_stats
printf 'PROJECT_OUTPUTS:\n'
write_project_output_hashes
} > "$next_signature"; then
rm -f "$next_signature"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table.sh "${check_args[@]}"
exit 0
fi
if [[ -f "$cache_file" ]] && cmp -s "$cache_file" "$next_signature"; then
rm -f "$next_signature"
exit 0
fi
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table.sh "${check_args[@]}"
mv "$next_signature" "$cache_file"

View File

@@ -196,84 +196,6 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
target_compile_definitions(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE FMT_HEADER_ONLY=1)
endif()
set(linuxcnc_rs274_wasm_safe_probe_project_sources
${CMAKE_CURRENT_SOURCE_DIR}/src/canon_event_sink.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_canon_bridge.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rs274_backend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_tooldata_fixture.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_5axiskins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_5axiskins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_corexykins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_corexykins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_cubic_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_cubic_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_genserfuncs_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_genserfuncs_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_genhexkins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_genhexkins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_kins_util_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_kins_util_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_lineardeltakins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_lineardeltakins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_maxkins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_maxkins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_pentakins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_pentakins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_pumakins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_pumakins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rotatekins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rotatekins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rosekins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rosekins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rotarydeltakins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_rotarydeltakins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_scarakins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_scarakins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_scorbot_kins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_scorbot_kins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_tripodkins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_tripodkins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_trtfuncs_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_trtfuncs_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_userkfuncs_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_userkfuncs_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_xyzab_tdr_kins_adapter.c
${CMAKE_CURRENT_SOURCE_DIR}/src/linuxcnc_xyzab_tdr_kins_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/rtcp_kinematics.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/simulator_gcode_controls.cpp
)
add_executable(linuxcnc_rs274_wasm_safe_probe EXCLUDE_FROM_ALL
$<TARGET_OBJECTS:linuxcnc_rs274_wasm_safe_probe_objects>
${linuxcnc_rs274_wasm_safe_probe_project_sources}
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rs274ngc_pre_probe_main.cc
)
target_compile_features(linuxcnc_rs274_wasm_safe_probe PRIVATE cxx_std_20)
target_compile_definitions(linuxcnc_rs274_wasm_safe_probe
PRIVATE
CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND
CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
ULAPI
)
target_compile_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})
target_include_directories(linuxcnc_rs274_wasm_safe_probe
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims
${CNC_SIM_LINUXCNC_ROOT_ABS}/src
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion
${CNC_SIM_LINUXCNC_ROOT_ABS}/include
)
if(EMSCRIPTEN)
target_compile_definitions(linuxcnc_rs274_wasm_safe_probe PRIVATE FMT_HEADER_ONLY=1)
else()
target_link_libraries(linuxcnc_rs274_wasm_safe_probe PRIVATE fmt)
endif()
set(cnc_sim_wasm_runtime_probe_main
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc
)
@@ -371,6 +293,37 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
endif()
if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
add_executable(linuxcnc_rs274_wasm_safe_probe EXCLUDE_FROM_ALL
$<TARGET_OBJECTS:linuxcnc_rs274_wasm_safe_probe_objects>
$<TARGET_OBJECTS:cnc_sim_objects>
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rs274ngc_pre_probe_main.cc
)
target_compile_features(linuxcnc_rs274_wasm_safe_probe PRIVATE cxx_std_20)
target_compile_definitions(linuxcnc_rs274_wasm_safe_probe
PRIVATE
CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND
CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
ULAPI
)
target_compile_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})
target_include_directories(linuxcnc_rs274_wasm_safe_probe
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims
${CNC_SIM_LINUXCNC_ROOT_ABS}/src
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc
${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion
${CNC_SIM_LINUXCNC_ROOT_ABS}/include
)
if(EMSCRIPTEN)
target_compile_definitions(linuxcnc_rs274_wasm_safe_probe PRIVATE FMT_HEADER_ONLY=1)
else()
target_link_libraries(linuxcnc_rs274_wasm_safe_probe PRIVATE fmt)
endif()
add_executable(cnc_sim_wasm_runtime_probe EXCLUDE_FROM_ALL
$<TARGET_OBJECTS:linuxcnc_rs274_wasm_safe_probe_objects>
$<TARGET_OBJECTS:cnc_sim_objects>

View File

@@ -44,30 +44,170 @@ Required workflow for every functional change:
and guardrail checks: `./test-all-native.sh`,
`./test-linuxcnc-source-syntax.sh`, and
`./test-linuxcnc-wasm-cmake-safe-probe.sh`.
When `./test-native.sh` and `./test-linuxcnc-source-link.sh` have already
been run in the same pass, use
`CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY=1 ./test-all-native.sh` for the
aggregate guardrail pass instead of recompiling the same native/source-link
targets again.
8. Keep `./test-linuxcnc-wasm-cmake-safe-probe.sh` focused on the actual CMake
probe by default. Run
`CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS=1 ./test-linuxcnc-wasm-cmake-safe-probe.sh`
only when changing its meta-guardrails or the surrounding build-wasm policy.
Efficiency rules:
- Each pass should advance one reasonable, reviewable context. Do not use a
nearby failing smoke assertion, broad fixture, or convenient touched file as
permission to expand the pass into another workstream.
- Do not add a smoke-only behavior path when the LinuxCNC-backed route already
exists; add coverage to the source-backed route instead.
- Smoke tests are verification guardrails. They must not be expanded with new
functional CNC behavior unless that behavior is directly routed to, copied
from, or checked against the relevant LinuxCNC source in the same narrow
context.
- Do not mix generator/table work, manifests, OPFS/browser work, and build
policy cleanup in the same pass unless the files directly depend on each
other.
- Prefer tightening an existing probe or manifest over adding another broad
end-to-end smoke case.
- Do not run the full native aggregate after already running its expensive
native/source-link children in the same pass; use the explicit guardrails-only
aggregate mode for build-policy cleanup.
- Keep meta-guardrails out of hot build paths. The wasm-safe CMake probe may
run extended self-checks with `CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS=1`,
and the source syntax probe may run extended self-checks with
`CNC_SIM_SOURCE_SYNTAX_SELF_CHECKS=1`. The wasm blocker probe may run
analyzer failure-path self-checks with `CNC_SIM_WASM_BLOCKERS_SELF_CHECKS=1`.
The default actual CMake, syntax, and blocker probe paths remain fast.
- Keep `test-linuxcnc-wasm-source-syntax.sh` on the same persistent incremental
build pattern as the native syntax probe. It must use
`build/wasm-source-syntax-test` by default, dependency files, a signature,
`make --output-sync=target`, and `CNC_SIM_BUILD_JOBS:-8`.
- Reuse source preflight results in persistent build directories through
`check-linuxcnc-inputs-cached.sh`; its signature must include the LinuxCNC
root, manifest content, source file size and nanosecond mtime stats, the check
mode, and the checker script hash. Cache updates must be serialized with a
lock inside the cache directory and must write next signatures through unique
temporary files.
Root-only source, flag, and link helper scripts must also use this cached
preflight, defaulting to `build/linuxcnc-helper-preflight-cache` when a caller
has not supplied `CNC_SIM_PREFLIGHT_CACHE_DIR`.
`build-wasm.sh` must pass its preflight cache into nested build probes such as
`test-linuxcnc-wasm-blockers.sh` and
`test-linuxcnc-wasm-cmake-safe-probe.sh` instead of forcing a second cache
walk in the same pass.
- Cache wasm blocker analyzer output in `test-linuxcnc-wasm-blockers.sh`. Its
signature must include the analyzer script, manifest content, LinuxCNC source
size and nanosecond mtime stats, shim lister script, and shim source hashes.
The cache must be locked and may be overridden with
`CNC_SIM_WASM_BLOCKERS_CACHE_DIR`.
- Reuse switchkins/remap table check results in the same persistent cache with
`check-linuxcnc-switchkins-remap-table-cached.sh`; its signature must include
the checker and generator scripts, the kinematics manifest, referenced
LinuxCNC source size and nanosecond mtime stats, and tracked generated
table/case outputs.
- Reuse wasm probe objects across the wasm source object probe,
`rs274ngc_pre` blocker/link probes, and the runtime link probe through
`build-linuxcnc-wasm-probe-objects.sh`. Its mode-specific object caches must
be keyed by compiler, LinuxCNC root, manifest, flags, and source list, and
must include make dependency files so repeated build-wasm passes and the
paired `rs274ngc_pre` probes do not recompile unchanged LinuxCNC core files,
shims, or kinematics adapters.
- Reuse standalone wasm probe objects and binaries for the tooldata link,
tooldata_common link, `interp_base` link, python_plugin link, and
`rs274ngc_pre` object probes through
`build-linuxcnc-wasm-standalone-probe.sh`. Its mode-specific caches must keep
compiler, LinuxCNC root, flags, source list, dependency files, and a lock so
repeated build-wasm passes do not rebuild unchanged probe inputs.
- Reuse wasm final link probes for `rs274ngc_pre` and runtime link checks
through `build-linuxcnc-wasm-link-probe.sh`. It must consume
`build-linuxcnc-wasm-probe-objects.sh`, cache probe main objects and linked
executables with dependency files and a lock, and keep runtime symbol checks
in `test-linuxcnc-wasm-runtime-link.sh`.
- Cache the runtime link probe symbol table in `test-linuxcnc-wasm-runtime-link.sh`
using the probe binary size and mtime plus an explicit `SYMBOL_RULE_VERSION`,
so repeated build-wasm passes do not rerun `nm -C` on an unchanged probe.
- Cache the `rs274ngc_pre` pre-link undefined-symbol scan in
`test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh`. Its signature must
include the LinuxCNC root, manifest, object list, object size and mtime stats,
and an explicit `FILTER_RULE_VERSION`, with a lock and
`CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR` override.
- Keep `test-linuxcnc-wasm-python-c-api-symbols.sh` persistent for repeated
build-wasm passes. It must use `build/wasm-python-c-api-symbols`,
dependency files, a build signature, cached source token and object symbol
signatures, `make --output-sync=target`, and `CNC_SIM_BUILD_JOBS:-8` while
still deriving required Python C API symbols from LinuxCNC RS274 Python/remap
sources.
- Keep `test-linuxcnc-wasm-interp-find-link.sh` persistent for repeated
build-wasm passes. It must use `build/wasm-interp-find-link`, dependency
files, a signature, `make --output-sync=target`, and `CNC_SIM_BUILD_JOBS:-8`
while still linking LinuxCNC `interp_find.cc` with the wasm-safe tooldata and
RTAPI shims.
- Keep tooldata symbol probes persistent for repeated build-wasm passes.
`test-linuxcnc-wasm-tooldata-mmap-symbols.sh` must use
`build/wasm-tooldata-mmap-symbols`, and
`test-linuxcnc-wasm-tooldata-runtime-symbols.sh` must use
`build/wasm-tooldata-runtime-symbols`; both must use dependency files,
build signatures, cached `nm --defined-only` symbol export signatures,
`make --output-sync=target`, and `CNC_SIM_BUILD_JOBS:-8` while comparing wasm
shim exports against LinuxCNC tooldata sources.
- Default native, source-link, build-wasm, and wasm-safe CMake probe
parallelism to `CNC_SIM_BUILD_JOBS:-8`; raise it only by explicit
positive-integer environment override.
- When `ccache` is available and `CXX` is unset, native and wasm build paths
should enable compiler caching automatically rather than requiring a manual
wrapper.
- Persistent native, source-link, and wasm-safe CMake probe build directories
may be overridden for local workflows, but must not point at the filesystem
root.
- Persistent object/stamp signatures must not include `CNC_SIM_BUILD_JOBS`.
Parallelism affects scheduling only; changing it must not invalidate otherwise
unchanged LinuxCNC source, shim, syntax, or CMake probe build outputs.
- Persistent native, source-object, source-link, source-syntax, RS274 native,
bridge native, API native, shared bridge-object, wasm source-syntax,
wasm probe-object, wasm link-probe, wasm standalone-probe, wasm Python C API,
wasm interp_find, and wasm tooldata symbol signatures must include an explicit
`BUILD_RULE_VERSION` instead of hashing the whole probe script. Bump that
version when generated compile or link rule semantics change; ordinary
guardrail and smoke assertion edits must not invalidate unchanged LinuxCNC
source, shim, or project objects.
- The LinuxCNC canon bridge native smoke probe must use persistent
`build/bridge-native-test` objects, dependency files, a build-rule signature,
`make --output-sync=target`, and `CNC_SIM_BUILD_JOBS:-8`; it must not compile
all bridge sources in a throwaway temporary directory on every aggregate pass.
Its 41 LinuxCNC bridge/project objects must be built through the shared
`build-linuxcnc-native-bridge-objects.sh` cache so the RS274 API native smoke
probe can link the same objects instead of recompiling them.
- The LinuxCNC RS274 API native smoke probe must use persistent
`build/api-native-test` objects, dependency files, a build-rule signature,
`make --output-sync=target`, and `CNC_SIM_BUILD_JOBS:-8`; it must keep
resetting its RS274 parameter file from LinuxCNC `tests/halui/jogging/sim.var`
before running the smoke executable. It must reuse the shared bridge object
cache and compile only its extra API/backend sources locally. Its LinuxCNC
RS274 backend compile define must be applied only to source files that use
that define, currently `core/src/gcode_backend.cpp`, so unrelated bridge and
kinematics adapter objects are not rebuilt by backend-specific rule changes.
- When `ccache` is available and `CXX` is unset, native, source-link,
source-syntax, and wasm build paths should enable compiler caching
automatically rather than requiring a manual wrapper, including the
wasm-safe CMake probe.
- Persistent native, source-link, source-syntax, and wasm-safe CMake probe
build directories, plus the wasm source-syntax, Python C API, and interp_find
probe build directories, tooldata symbol probe build directories, and wasm
standalone/link probe cache directories may be overridden for local workflows,
but must not point at the filesystem root.
- Build policy knobs are intentionally narrow:
`CNC_SIM_BUILD_JOBS`, `CNC_SIM_NATIVE_BUILD_DIR`,
`CNC_SIM_SOURCE_LINK_BUILD_DIR`, `CNC_SIM_SOURCE_SYNTAX_BUILD_DIR`, and
`CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR`. Build directory overrides must
stay non-empty, whitespace-free, and outside the filesystem root.
`CNC_SIM_SOURCE_LINK_BUILD_DIR`, `CNC_SIM_SOURCE_SYNTAX_BUILD_DIR`,
`CNC_SIM_SOURCE_OBJECTS_BUILD_DIR`, `CNC_SIM_BRIDGE_NATIVE_BUILD_DIR`,
`CNC_SIM_API_NATIVE_BUILD_DIR`, `CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR`, and
`CNC_SIM_RS274_NATIVE_BUILD_DIR`, and
`CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR`. The wasm source-syntax probe also
accepts `CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR` because it owns a persistent
incremental cache. The wasm Python C API probe accepts
`CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR` for the same reason, and the
wasm interp_find probe accepts `CNC_SIM_WASM_INTERP_FIND_BUILD_DIR`.
Tooldata symbol probes accept
`CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR` and
`CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR`.
Standalone wasm probes accept `CNC_SIM_WASM_STANDALONE_PROBE_CACHE_DIR`.
Final wasm link probes accept `CNC_SIM_WASM_LINK_PROBE_CACHE_DIR`.
Build directory overrides must stay non-empty, whitespace-free, and outside
the filesystem root.
- `build-wasm.sh` keeps fixed artifact paths: CMake writes `build/wasm`, then
the script copies and byte-compares `cnc_sim.js` and `cnc_sim.wasm` under
`web/public` before running Node and browser smoke checks.
@@ -82,23 +222,61 @@ Build and source-link guardrails:
- `test-linuxcnc-source-syntax.sh` uses persistent
`build/source-syntax-test` stamps, dependency files, and
`source-syntax.signature`.
- `test-linuxcnc-source-objects.sh` uses persistent
`build/source-objects-test` objects, dependency files, and
`source-objects.signature`.
- `test-linuxcnc-rs274-native.sh` uses persistent
`build/rs274-native-test` objects, dependency files, and
`rs274-native.signature`.
- `test-linuxcnc-wasm-cmake-safe-probe.sh` uses persistent
`build/wasm-cmake-safe-probe` and `wasm-cmake-safe-probe.signature`.
`build/wasm-cmake-safe-probe` and `wasm-cmake-safe-probe.signature`; signature
changes must reconfigure in place, its signature must include an explicit
`CONFIGURE_RULE_VERSION`, and its two probe executables must be built with one
combined `cmake --build` invocation.
- `test-linuxcnc-wasm-source-syntax.sh` uses persistent
`build/wasm-source-syntax-test` stamps, dependency files, and
`wasm-source-syntax.signature`.
- `test-linuxcnc-wasm-python-c-api-symbols.sh` uses persistent
`build/wasm-python-c-api-symbols` objects, dependency files, and
`python-c-api.signature`.
- `test-linuxcnc-wasm-interp-find-link.sh` uses persistent
`build/wasm-interp-find-link` objects, dependency files, and
`interp-find.signature`.
- `test-linuxcnc-wasm-tooldata-mmap-symbols.sh` uses persistent
`build/wasm-tooldata-mmap-symbols` objects, dependency files, and
`tooldata-mmap-symbols.signature`.
- `test-linuxcnc-wasm-tooldata-runtime-symbols.sh` uses persistent
`build/wasm-tooldata-runtime-symbols` objects, dependency files, and
`tooldata-runtime-symbols.signature`.
- Native, source-link, source-syntax, wasm-safe CMake probe, and build-wasm
paths must reject empty, whitespace-containing, or filesystem-root build
directory overrides before doing destructive cleanup.
- Native, source-link, source-syntax, and build-wasm entry points must serialize
shared non-concurrency-safe paths with lock files before writing fixed
outputs.
- Source-link and syntax probes must build from generated makefiles with
`-MMD -MP` dependency tracking and `make --output-sync=target`.
- `CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY=1 ./test-all-native.sh` must run the
aggregate guardrail and failure-path assertions without invoking the expensive
child native/source-link compile and smoke scripts.
- Native, source-object, source-link, RS274 native, and syntax probes must build
from generated makefiles with `-MMD -MP` dependency tracking and
`make --output-sync=target`.
- `build-wasm.sh` must run blocker, syntax, object, CMake, tooldata,
`interp_*`, Python, `rs274ngc_pre`, and runtime link probes before copying
browser artifacts.
- Independent tooldata, `interp_*`, Python, and `rs274ngc_pre` object probes in
`build-wasm.sh` may run in parallel, but their logs must be replayed in a
deterministic order and the script must wait for all of them before
`rs274ngc_pre` link checks.
- `build-wasm.sh` must check `cmake`, `emcmake`, `emcc`, and `node` before the
Emscripten configure step.
- `build-wasm.sh` must reuse a persistent `build/wasm` configure signature
keyed by manifest, `core/CMakeLists.txt`, an explicit
`CONFIGURE_RULE_VERSION`, LinuxCNC root, and compiler launcher. The signature
must not include `CNC_SIM_BUILD_JOBS`, and signature changes must reconfigure
the existing build tree in place instead of deleting compiled objects.
- `build-wasm.sh` must build `cnc_sim_wasm_runtime_probe` before
`cnc_sim_wasm`.
`cnc_sim_wasm`, using one combined `cmake --build` invocation for both
targets.
- `build-wasm.sh` must copy `build/wasm/cnc_sim.js` and
`build/wasm/cnc_sim.wasm` exactly once each.
- `build-wasm.sh` must compare copied artifacts with `cmp -s` before running

View File

@@ -23,7 +23,8 @@ checks_duplicate_group() {
[[ "$groups" == "all" ]] || contains_group "$groups" "$group"
}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh "$manifest"
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
if [[ "$filter_group" != "all" ]] && ! contains_group "$allowed_groups" "$filter_group"; then
echo "unknown manifest source filter: $filter_group" >&2
@@ -52,9 +53,11 @@ while IFS=: read -r group path note; do
exit 1
fi
full_path=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh \
--missing-message "$missing_source_message" \
"$path")
full_path="$linuxcnc_root/$path"
if [[ ! -f "$full_path" ]]; then
echo "$missing_source_message: $path" >&2
exit 1
fi
if checks_duplicate_group "$duplicate_groups" "$group"; then
if printf '%s\n' "${seen_sources[@]}" | grep -Fx -- "$path" >/dev/null; then
echo "duplicate manifest source: $path" >&2

View File

@@ -4,8 +4,9 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
printf '%s\n' \
-L "$linuxcnc_root/lib" \

View File

@@ -4,6 +4,7 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}
include_python=0
include_core_include=0
include_core_src=0
@@ -43,7 +44,7 @@ while [[ "$#" -gt 0 ]]; do
esac
done
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
python_includes=()
if [[ "$include_python" -eq 1 ]]; then

View File

@@ -5,8 +5,9 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
missing_source_message="missing LinuxCNC source"
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
while [[ "$#" -gt 0 ]]; do
case "$1" in

View File

@@ -5,8 +5,9 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
filter=${1:-}
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
objects=(
src/objects/emc/rs274ngc/interpmodule.o

View File

@@ -4,6 +4,7 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}
std_flag=-std=c++17
include_core_include=0
include_core_src=0
@@ -96,7 +97,7 @@ case "$profile" in
;;
esac
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
printf '%s\n' \
"$std_flag" \

View File

@@ -5,7 +5,10 @@ cd "$(dirname "$0")"
filter=${1:-}
./list-cmake-set-sources.sh linuxcnc_rs274_wasm_safe_probe_project_sources | ./list-filtered-existing-paths.sh \
{
./list-cmake-set-sources.sh cnc_sim_core_sources core/
./list-cmake-set-sources.sh cnc_sim_linuxcnc_rs274_backend_sources core/
} | ./list-filtered-existing-paths.sh \
"$filter" \
"missing wasm-safe project source" \
"missing wasm-safe project source in CMake list"

View File

@@ -5,6 +5,11 @@ cd "$(dirname "$0")"
manifest=${1:-linuxcnc-rs274-source-files.txt}
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
guardrails_only=${CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY:-0}
if [[ "$guardrails_only" != "0" && "$guardrails_only" != "1" ]]; then
echo "CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY must be 0 or 1: $guardrails_only" >&2
exit 1
fi
missing_root=/tmp/does-not-exist-linuxcnc
missing_root_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_native_missing_root.XXXXXX.log")
@@ -62,6 +67,54 @@ cleanup_native_test_temps() {
trap cleanup_native_test_temps EXIT
grep -Fx 'trap cleanup_native_test_temps EXIT' test-all-native.sh >/dev/null
grep -F 'guardrails_only=${CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY:-0}' test-all-native.sh >/dev/null
grep -F 'CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY must be 0 or 1: $guardrails_only' test-all-native.sh >/dev/null
grep -F 'all native guardrail checks passed' test-all-native.sh >/dev/null
test -x check-linuxcnc-inputs-cached.sh
grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR' check-linuxcnc-inputs-cached.sh >/dev/null
grep -F 'sha256sum check-linuxcnc-inputs.sh' check-linuxcnc-inputs-cached.sh >/dev/null
grep -F 'exec 8>"$cache_dir/check-linuxcnc-inputs.lock"' check-linuxcnc-inputs-cached.sh >/dev/null
grep -F 'flock 8' check-linuxcnc-inputs-cached.sh >/dev/null
grep -F 'stat -c '\''SOURCE=%n:%s:%y'\''' check-linuxcnc-inputs-cached.sh >/dev/null
grep -F 'next_signature=$(mktemp "$cache_file.next.XXXXXX")' check-linuxcnc-inputs-cached.sh >/dev/null
test -x check-linuxcnc-switchkins-remap-table-cached.sh
grep -F 'check-linuxcnc-switchkins-remap-table.lock' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'sha256sum check-linuxcnc-switchkins-remap-table.sh' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'sha256sum generate-linuxcnc-switchkins-remap-table.sh' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'stat -c '\''SOURCE=%n:%s:%y'\''' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'core/src/linuxcnc_switchkins_remap_table.inc' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'core/tests/linuxcnc_switchkins_remap_config_cases.inc' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'web/public/linuxcnc_switchkins_remap_config_cases.json' check-linuxcnc-switchkins-remap-table-cached.sh >/dev/null
grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' test-native.sh >/dev/null
grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' test-linuxcnc-source-link.sh >/dev/null
grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' build-wasm.sh >/dev/null
grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' test-linuxcnc-source-link.sh >/dev/null
grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./test-linuxcnc-wasm-cmake-safe-probe.sh "$manifest"' build-wasm.sh >/dev/null
grep -F 'preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$build_dir/preflight-cache"}' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir"' test-native.sh >/dev/null
for helper_script in \
list-linuxcnc-source-files.sh \
list-linuxcnc-source-support-objects.sh \
list-linuxcnc-source-common-cxxflags.sh \
list-linuxcnc-native-linkflags.sh; do
grep -F 'preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/linuxcnc-helper-preflight-cache}' "$helper_script" >/dev/null
grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' "$helper_script" >/dev/null
done
grep -F 'self_checks=${CNC_SIM_SOURCE_SYNTAX_SELF_CHECKS:-0}' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_SYNTAX_SELF_CHECKS must be 0 or 1: $self_checks' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY=1 ./test-all-native.sh' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'without invoking the expensive' docs/linuxcnc-source-policy.md >/dev/null
if ! awk '
index($0, "if [[ \"$guardrails_only\" == \"1\" ]]; then") { guardrail_line = NR }
index($0, "./test-native.sh") { native_line = NR }
index($0, "./test-linuxcnc-source-link.sh \"$manifest\"") { source_link_line = NR }
END { exit !(guardrail_line && native_line && source_link_line && guardrail_line < native_line && guardrail_line < source_link_line) }
' test-all-native.sh; then
echo "native aggregate guardrails-only exit must precede expensive child tests" >&2
exit 1
fi
if ! awk '
/cleanup_native_test_temps\(\)/ { in_cleanup = 1 }
in_cleanup && index($0, "\"$missing_manifest\"") { found_missing_manifest = 1 }
@@ -128,20 +181,48 @@ grep -Fx -- "$linuxcnc_root/lib" <<<"$native_link_flags" >/dev/null
grep -Fx -- "-Wl,-rpath,$linuxcnc_root/lib" <<<"$native_link_flags" >/dev/null
grep -F 'exec 9>"${TMPDIR:-/tmp}/cnc_sim_linuxcnc_rs274_native.lock"' test-linuxcnc-rs274-native.sh >/dev/null
grep -F "flock 9" test-linuxcnc-rs274-native.sh >/dev/null
for build_dir_probe_script in \
test-linuxcnc-source-objects.sh \
test-linuxcnc-bridge-native.sh \
test-linuxcnc-rs274-native.sh \
test-linuxcnc-api-native.sh; do
if ! awk '
index($0, "trap '\''rm -rf \"$build_dir\"'\'' EXIT") { trap_line = NR }
index($0, "./check-linuxcnc-inputs.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 input validation" >&2
exit 1
fi
done
grep -F 'build_dir=${CNC_SIM_BRIDGE_NATIVE_BUILD_DIR-build/bridge-native-test}' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not be empty' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not be the filesystem root' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'exec 9>"$build_dir/bridge-native.lock"' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' test-linuxcnc-bridge-native.sh >/dev/null
test -x build-linuxcnc-native-bridge-objects.sh
grep -F 'CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR' build-linuxcnc-native-bridge-objects.sh >/dev/null
grep -F 'cache_dir=${CNC_SIM_NATIVE_BRIDGE_OBJECT_CACHE_DIR-build/native-bridge-object-cache}' build-linuxcnc-native-bridge-objects.sh >/dev/null
grep -F 'native-bridge-objects.signature' build-linuxcnc-native-bridge-objects.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" build-linuxcnc-native-bridge-objects.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null' build-linuxcnc-native-bridge-objects.sh >/dev/null
grep -F 'build-linuxcnc-native-bridge-objects.sh' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'BRIDGE_OBJECTS :=' test-linuxcnc-bridge-native.sh >/dev/null
if grep -F 'for source in "${project_sources[@]}"' test-linuxcnc-bridge-native.sh >/dev/null; then
echo "bridge native smoke still compiles shared project sources locally" >&2
exit 1
fi
grep -F 'bridge_signature="$build_dir/bridge-native.signature"' test-linuxcnc-bridge-native.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$bridge_makefile"' test-linuxcnc-bridge-native.sh >/dev/null
grep -F -- '-MMD -MP -MF %s.d' test-linuxcnc-bridge-native.sh >/dev/null
grep -F 'build_dir=${CNC_SIM_API_NATIVE_BUILD_DIR-build/api-native-test}' test-linuxcnc-api-native.sh >/dev/null
grep -F 'CNC_SIM_API_NATIVE_BUILD_DIR must not be empty' test-linuxcnc-api-native.sh >/dev/null
grep -F 'CNC_SIM_API_NATIVE_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-api-native.sh >/dev/null
grep -F 'CNC_SIM_API_NATIVE_BUILD_DIR must not be the filesystem root' test-linuxcnc-api-native.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-api-native.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-api-native.sh >/dev/null
grep -F 'exec 9>"$build_dir/api-native.lock"' test-linuxcnc-api-native.sh >/dev/null
grep -F 'check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only' test-linuxcnc-api-native.sh >/dev/null
grep -F 'build-linuxcnc-native-bridge-objects.sh' test-linuxcnc-api-native.sh >/dev/null
grep -F 'api_extra_sources=()' test-linuxcnc-api-native.sh >/dev/null
grep -F 'is_bridge_source "$source"' test-linuxcnc-api-native.sh >/dev/null
grep -F 'BRIDGE_OBJECTS :=' test-linuxcnc-api-native.sh >/dev/null
grep -F 'api_signature="$build_dir/api-native.signature"' test-linuxcnc-api-native.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-api-native.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$api_makefile"' test-linuxcnc-api-native.sh >/dev/null
grep -F 'core/src/gcode_backend.cpp)' test-linuxcnc-api-native.sh >/dev/null
grep -F 'source_flags+=(-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND)' test-linuxcnc-api-native.sh >/dev/null
grep -F "printf ' %s' \"\${source_flags[@]}\"" test-linuxcnc-api-native.sh >/dev/null
if ! awk '
/cleanup_wasm_cmake_probe_temps\(\)/ { in_cleanup = 1 }
in_cleanup && index($0, "\"$build_dir\"") { found_build_dir = 1 }
@@ -156,14 +237,29 @@ grep -F 'CNC_SIM_SOURCE_LINK_BUILD_DIR must not be empty' test-linuxcnc-source-l
grep -F 'CNC_SIM_SOURCE_LINK_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-source-link.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_LINK_BUILD_DIR must not be the filesystem root' 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
if ! awk '
index($0, "check-linuxcnc-inputs-cached.sh --cache-dir") &&
index($0, "\"$manifest\"") &&
!index($0, "--require-rs274-complete") { check_line = NR }
index($0, "./check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir \"$preflight_cache_dir\" linuxcnc-kinematics-source-files.txt") { table_line = NR }
END { exit !(check_line && table_line && check_line < table_line) }
' test-linuxcnc-source-link.sh; then
echo "source-link probe must validate its requested manifest before switchkins table checks" >&2
exit 1
fi
grep -F 'exec 9>"${TMPDIR:-/tmp}/cnc_sim_rs274_source_link.lock"' 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 'mv "$source_link_next_signature" "$source_link_signature"' 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 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-source-link.sh >/dev/null
grep -F 'printf '\''%s: %s\n'\'' "$build_dir/linuxcnc_${linuxcnc_index}.o" "$source"' test-linuxcnc-source-link.sh >/dev/null
grep -F 'printf '\''%s: %s\n'\'' "$build_dir/project_${project_index}.o" "$source"' 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 'source_link_makefile="$build_dir/source-link.mk"' 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 '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
@@ -172,9 +268,14 @@ grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-native
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 'mv "$native_next_signature" "$native_signature"' test-native.sh >/dev/null
grep -F 'printf '\''PWD=%s\n'\'' "$PWD"' test-native.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-native.sh >/dev/null
grep -F 'printf '\''%s: %s\n'\'' "${core_objects[$core_index]}" "$source"' 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 'native_makefile="$build_dir/native.mk"' 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_dir=${CNC_SIM_SOURCE_SYNTAX_BUILD_DIR-build/source-syntax-test}' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_SYNTAX_BUILD_DIR must not be empty' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_SYNTAX_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-source-syntax.sh >/dev/null
@@ -184,24 +285,166 @@ grep -F 'exec 9>"$build_dir/source-syntax.lock"' test-linuxcnc-source-syntax.sh
grep -F 'source_list="$build_dir/linuxcnc_source_syntax_sources.txt"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'source_syntax_signature="$build_dir/source-syntax.signature"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'if [[ ! -f "$source_syntax_signature" ]] || ! cmp -s "$source_syntax_signature" "$source_syntax_next_signature"; then' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'mv "$source_syntax_next_signature" "$source_syntax_signature"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'printf '\''LINUXCNC_ROOT=%s\n'\'' "$(cd "$linuxcnc_root" && pwd)"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'printf '\''MANIFEST=%s\n'\'' "$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-source-syntax.sh >/dev/null
if grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' test-linuxcnc-source-syntax.sh >/dev/null; then
echo "source syntax signature must not depend on CNC_SIM_BUILD_JOBS" >&2
exit 1
fi
grep -F 'printf '\''%s/source_%s.stamp: %s\n'\'' "$build_dir" "$source_index" "$source"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'printf '\''\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s/source_%s.d %s\n'\''' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$source_syntax_makefile"' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'build_dir=${CNC_SIM_SOURCE_OBJECTS_BUILD_DIR-build/source-objects-test}' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be empty' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be the filesystem root' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'exec 9>"$build_dir/source-objects.lock"' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'source_objects_signature="$build_dir/source-objects.signature"' test-linuxcnc-source-objects.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-source-objects.sh >/dev/null
grep -F 'source_objects_makefile="$build_dir/source-objects.mk"' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'printf '\''\n-include $(DEP_FILES)\n'\''' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$source_objects_makefile"' test-linuxcnc-source-objects.sh >/dev/null
grep -F 'build_dir=${CNC_SIM_RS274_NATIVE_BUILD_DIR-build/rs274-native-test}' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'CNC_SIM_RS274_NATIVE_BUILD_DIR must not be empty' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'CNC_SIM_RS274_NATIVE_BUILD_DIR must not contain whitespace: $build_dir' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'CNC_SIM_RS274_NATIVE_BUILD_DIR must not be the filesystem root' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'rs274_native_signature="$build_dir/rs274-native.signature"' test-linuxcnc-rs274-native.sh >/dev/null
grep -F "printf 'BUILD_RULE_VERSION=1\n'" test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'rs274_native_makefile="$build_dir/rs274-native.mk"' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'printf '\''\n-include $(DEP_FILES)\n'\''' test-linuxcnc-rs274-native.sh >/dev/null
grep -F 'make --output-sync=target -j"$build_jobs" -f "$rs274_native_makefile"' test-linuxcnc-rs274-native.sh >/dev/null
for hot_signature_script in \
build-linuxcnc-native-bridge-objects.sh \
test-linuxcnc-api-native.sh \
test-linuxcnc-bridge-native.sh \
test-linuxcnc-rs274-native.sh \
test-linuxcnc-source-link.sh \
test-linuxcnc-source-objects.sh \
test-linuxcnc-source-syntax.sh \
test-native.sh; do
if grep -F "sha256sum $hot_signature_script" "$hot_signature_script" >/dev/null; then
echo "$hot_signature_script hot object signature must use BUILD_RULE_VERSION instead of the whole script hash" >&2
exit 1
fi
done
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_args=()' build-wasm.sh >/dev/null
grep -F 'cmake_compiler_launcher_mode=ccache' build-wasm.sh >/dev/null
grep -F '"${cmake_compiler_launcher_args[@]}"' build-wasm.sh >/dev/null
grep -F 'command -v ccache >/dev/null 2>&1' build-wasm.sh >/dev/null
grep -F 'CMAKE_C_COMPILER_LAUNCHER=ccache' build-wasm.sh >/dev/null
grep -F 'CMAKE_CXX_COMPILER_LAUNCHER=ccache' build-wasm.sh >/dev/null
grep -F 'cmake --build build/wasm --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F 'cmake --build build/wasm --target cnc_sim_wasm --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F '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 -- '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 -- '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
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, "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 combined CMake build must list runtime probe before browser WASM target" >&2
exit 1
fi
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
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, "for required_tool in cmake emcmake emcc node; do") { tools_line = NR }
index($0, "emcmake cmake -S core -B build/wasm") { emcmake_line = NR }
END { exit !(tools_line && emcmake_line && tools_line < emcmake_line) }
' build-wasm.sh; then
echo "build-wasm must check required WASM tools before configuring with emcmake" >&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, "node test-web-wasm-node-smoke.cjs") { 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
grep -F 'command -v ccache >/dev/null 2>&1' test-native.sh >/dev/null
grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-source-link.sh >/dev/null
grep -F 'command -v ccache >/dev/null 2>&1' test-linuxcnc-source-syntax.sh >/dev/null
grep -F 'build_jobs=${CNC_SIM_BUILD_JOBS:-8}' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'cmake_compiler_launcher_args=()' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F '"${cmake_compiler_launcher_args[@]}"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CMAKE_C_COMPILER_LAUNCHER=ccache' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CMAKE_CXX_COMPILER_LAUNCHER=ccache' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'self_checks=${CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS:-0}' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS must be 0 or 1: $self_checks' test-linuxcnc-wasm-cmake-safe-probe.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
grep -F 'cmake_compiler_launcher_mode=none' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'cmake_compiler_launcher_mode=ccache' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'COMPILER_LAUNCHER=%s\n' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
@@ -212,17 +455,43 @@ grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR must not be the filesystem root
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 'mv "$build_next_signature" "$build_signature"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''LINUXCNC_ROOT=%s\n'\'' "$linuxcnc_root"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''MANIFEST=%s\n'\'' "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe_objects --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'cmake --build "$build_dir" --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F '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 grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null; then
echo "wasm CMake probe signature must not depend on CNC_SIM_BUILD_JOBS" >&2
exit 1
fi
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
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 'CNC_SIM_NATIVE_BUILD_DIR' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'CNC_SIM_SOURCE_LINK_BUILD_DIR' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'CNC_SIM_SOURCE_SYNTAX_BUILD_DIR' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'CNC_SIM_SOURCE_OBJECTS_BUILD_DIR' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'CNC_SIM_RS274_NATIVE_BUILD_DIR' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_BUILD_DIR' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Build directory overrides must' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'source-syntax, and wasm build paths should enable compiler caching' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'manual wrapper, including the' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Persistent object/stamp signatures must not include `CNC_SIM_BUILD_JOBS`.' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'signatures must include an explicit' docs/linuxcnc-source-policy.md >/dev/null
grep -F '`BUILD_RULE_VERSION` instead of hashing the whole probe script' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'keyed by manifest, `core/CMakeLists.txt`, an explicit' docs/linuxcnc-source-policy.md >/dev/null
grep -F '`CONFIGURE_RULE_VERSION`, LinuxCNC root, and compiler launcher' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Reuse standalone wasm probe objects and binaries for the tooldata link,' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Reuse wasm final link probes for `rs274ngc_pre` and runtime link checks' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'cached `nm --defined-only` symbol export signatures' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Cache wasm blocker analyzer output' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Persistent native, source-link, source-syntax, and wasm-safe CMake probe' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'copies and byte-compares `cnc_sim.js` and `cnc_sim.wasm` under' docs/linuxcnc-source-policy.md >/dev/null
grep -F '`CNC_SIM_BUILD_JOBS` must be a positive integer and defaults to `8`.' docs/linuxcnc-source-policy.md >/dev/null
grep -F '`test-native.sh` uses persistent `build/native-test` objects' docs/linuxcnc-source-policy.md >/dev/null
@@ -232,7 +501,8 @@ grep -F '`test-linuxcnc-wasm-cmake-safe-probe.sh` uses persistent' docs/linuxcnc
grep -F 'must reject empty, whitespace-containing, or filesystem-root build' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'entry points must serialize' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'shared non-concurrency-safe paths with lock files' docs/linuxcnc-source-policy.md >/dev/null
grep -F '`-MMD -MP` dependency tracking and `make --output-sync=target`' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Native, source-object, source-link, RS274 native, and syntax probes must build' docs/linuxcnc-source-policy.md >/dev/null
grep -F '`-MMD -MP` dependency tracking and' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'must run blocker, syntax, object, CMake, tooldata,' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'must check `cmake`, `emcmake`, `emcc`, and `node`' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'must build `cnc_sim_wasm_runtime_probe` before' docs/linuxcnc-source-policy.md >/dev/null
@@ -246,12 +516,23 @@ grep -F 'must include the built LinuxCNC `lib` path and rpath' docs/linuxcnc-sou
grep -F 'must surface helper failures instead of hiding them' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Temporary probe reports must be cleaned on failure' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'Documentation-only build policy edits should still update the guardrail' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'CNC_SIM_WASM_CMAKE_SAFE_PROBE_SELF_CHECKS=1' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'default actual CMake, syntax, and blocker probe paths remain fast' docs/linuxcnc-source-policy.md >/dev/null
grep -F 'python_include_output=$(python3.13-config --includes 2>/dev/null || python3-config --includes)' list-linuxcnc-source-common-cxxflags.sh >/dev/null
if grep -F 'read -r -a python_includes <<<"$(' list-linuxcnc-source-common-cxxflags.sh >/dev/null; then
echo "source common cxxflags still hides python-config failures behind read" >&2
exit 1
fi
for script in test-native.sh test-linuxcnc-source-syntax.sh test-linuxcnc-source-link.sh build-wasm.sh; do
for script in \
test-native.sh \
test-linuxcnc-source-syntax.sh \
test-linuxcnc-source-objects.sh \
test-linuxcnc-source-link.sh \
test-linuxcnc-rs274-native.sh \
test-linuxcnc-bridge-native.sh \
test-linuxcnc-api-native.sh \
build-wasm.sh; do
if CNC_SIM_BUILD_JOBS=0 "./$script" >"$invalid_build_jobs_log" 2>&1; then
echo "$script accepted invalid CNC_SIM_BUILD_JOBS" >&2
exit 1
@@ -334,6 +615,78 @@ if ! grep -F "CNC_SIM_NATIVE_BUILD_DIR must not contain whitespace: build/native
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
if CNC_SIM_BRIDGE_NATIVE_BUILD_DIR=/ ./test-linuxcnc-bridge-native.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-bridge-native.sh accepted filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-bridge-native.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_BRIDGE_NATIVE_BUILD_DIR=/tmp/.. ./test-linuxcnc-bridge-native.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-bridge-native.sh accepted canonical filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-bridge-native.sh did not report canonical filesystem-root build dir clearly" >&2
sed -n '1,20p' "$invalid_build_dir_log" >&2
exit 1
fi
if CNC_SIM_BRIDGE_NATIVE_BUILD_DIR= ./test-linuxcnc-bridge-native.sh >"$empty_build_dir_log" 2>&1; then
echo "test-linuxcnc-bridge-native.sh accepted empty build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not be empty" "$empty_build_dir_log" >/dev/null; then
echo "test-linuxcnc-bridge-native.sh did not report empty build dir clearly" >&2
sed -n '1,20p' "$empty_build_dir_log" >&2
exit 1
fi
if CNC_SIM_BRIDGE_NATIVE_BUILD_DIR="build/bridge native test" ./test-linuxcnc-bridge-native.sh >"$whitespace_build_dir_log" 2>&1; then
echo "test-linuxcnc-bridge-native.sh accepted whitespace in build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not contain whitespace: build/bridge native test" "$whitespace_build_dir_log" >/dev/null; then
echo "test-linuxcnc-bridge-native.sh did not report whitespace build dir clearly" >&2
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
if CNC_SIM_API_NATIVE_BUILD_DIR=/ ./test-linuxcnc-api-native.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-api-native.sh accepted filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_API_NATIVE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-api-native.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_API_NATIVE_BUILD_DIR=/tmp/.. ./test-linuxcnc-api-native.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-api-native.sh accepted canonical filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_API_NATIVE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-api-native.sh did not report canonical filesystem-root build dir clearly" >&2
sed -n '1,20p' "$invalid_build_dir_log" >&2
exit 1
fi
if CNC_SIM_API_NATIVE_BUILD_DIR= ./test-linuxcnc-api-native.sh >"$empty_build_dir_log" 2>&1; then
echo "test-linuxcnc-api-native.sh accepted empty build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_API_NATIVE_BUILD_DIR must not be empty" "$empty_build_dir_log" >/dev/null; then
echo "test-linuxcnc-api-native.sh did not report empty build dir clearly" >&2
sed -n '1,20p' "$empty_build_dir_log" >&2
exit 1
fi
if CNC_SIM_API_NATIVE_BUILD_DIR="build/api native test" ./test-linuxcnc-api-native.sh >"$whitespace_build_dir_log" 2>&1; then
echo "test-linuxcnc-api-native.sh accepted whitespace in build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_API_NATIVE_BUILD_DIR must not contain whitespace: build/api native test" "$whitespace_build_dir_log" >/dev/null; then
echo "test-linuxcnc-api-native.sh did not report whitespace build dir clearly" >&2
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
if CNC_SIM_SOURCE_SYNTAX_BUILD_DIR=/ ./test-linuxcnc-source-syntax.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-source-syntax.sh accepted filesystem root as build dir" >&2
exit 1
@@ -370,6 +723,78 @@ if ! grep -F "CNC_SIM_SOURCE_SYNTAX_BUILD_DIR must not contain whitespace: build
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
if CNC_SIM_SOURCE_OBJECTS_BUILD_DIR=/ ./test-linuxcnc-source-objects.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-source-objects.sh accepted filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-source-objects.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_SOURCE_OBJECTS_BUILD_DIR=/tmp/.. ./test-linuxcnc-source-objects.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-source-objects.sh accepted normalized filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-source-objects.sh did not report normalized filesystem-root build dir clearly" >&2
sed -n '1,20p' "$invalid_build_dir_log" >&2
exit 1
fi
if CNC_SIM_SOURCE_OBJECTS_BUILD_DIR= ./test-linuxcnc-source-objects.sh >"$empty_build_dir_log" 2>&1; then
echo "test-linuxcnc-source-objects.sh accepted empty build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be empty" "$empty_build_dir_log" >/dev/null; then
echo "test-linuxcnc-source-objects.sh did not report empty build dir clearly" >&2
sed -n '1,20p' "$empty_build_dir_log" >&2
exit 1
fi
if CNC_SIM_SOURCE_OBJECTS_BUILD_DIR="build/source objects test" ./test-linuxcnc-source-objects.sh >"$whitespace_build_dir_log" 2>&1; then
echo "test-linuxcnc-source-objects.sh accepted whitespace in build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not contain whitespace: build/source objects test" "$whitespace_build_dir_log" >/dev/null; then
echo "test-linuxcnc-source-objects.sh did not report whitespace build dir clearly" >&2
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
if CNC_SIM_RS274_NATIVE_BUILD_DIR=/ ./test-linuxcnc-rs274-native.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-rs274-native.sh accepted filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_RS274_NATIVE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-rs274-native.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_RS274_NATIVE_BUILD_DIR=/tmp/.. ./test-linuxcnc-rs274-native.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-rs274-native.sh accepted normalized filesystem root as build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_RS274_NATIVE_BUILD_DIR must not be the filesystem root" "$invalid_build_dir_log" >/dev/null; then
echo "test-linuxcnc-rs274-native.sh did not report normalized filesystem-root build dir clearly" >&2
sed -n '1,20p' "$invalid_build_dir_log" >&2
exit 1
fi
if CNC_SIM_RS274_NATIVE_BUILD_DIR= ./test-linuxcnc-rs274-native.sh >"$empty_build_dir_log" 2>&1; then
echo "test-linuxcnc-rs274-native.sh accepted empty build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_RS274_NATIVE_BUILD_DIR must not be empty" "$empty_build_dir_log" >/dev/null; then
echo "test-linuxcnc-rs274-native.sh did not report empty build dir clearly" >&2
sed -n '1,20p' "$empty_build_dir_log" >&2
exit 1
fi
if CNC_SIM_RS274_NATIVE_BUILD_DIR="build/rs274 native test" ./test-linuxcnc-rs274-native.sh >"$whitespace_build_dir_log" 2>&1; then
echo "test-linuxcnc-rs274-native.sh accepted whitespace in build dir" >&2
exit 1
fi
if ! grep -F "CNC_SIM_RS274_NATIVE_BUILD_DIR must not contain whitespace: build/rs274 native test" "$whitespace_build_dir_log" >/dev/null; then
echo "test-linuxcnc-rs274-native.sh did not report whitespace build dir clearly" >&2
sed -n '1,20p' "$whitespace_build_dir_log" >&2
exit 1
fi
if CNC_SIM_SOURCE_LINK_BUILD_DIR=/ ./test-linuxcnc-source-link.sh >"$invalid_build_dir_log" 2>&1; then
echo "test-linuxcnc-source-link.sh accepted filesystem root as build dir" >&2
exit 1
@@ -573,7 +998,8 @@ if ! grep -F "unknown manifest source output mode: bogus" "$unknown_output_log"
exit 1
fi
native_manifest_core_full=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full)
grep -Fx "$linuxcnc_root/src/emc/rs274ngc/interp_arc.cc" <<<"$native_manifest_core_full" >/dev/null
linuxcnc_root_full=$(cd "$linuxcnc_root" && pwd)
grep -Fx "$linuxcnc_root_full/src/emc/rs274ngc/interp_arc.cc" <<<"$native_manifest_core_full" >/dev/null
kinematics_manifest_config=$(./list-linuxcnc-kinematics-manifest-sources.sh linuxcnc-kinematics-source-files.txt config)
grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" <<<"$kinematics_manifest_config" >/dev/null
@@ -732,6 +1158,11 @@ if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$mis
exit 1
fi
if [[ "$guardrails_only" == "1" ]]; then
echo "all native guardrail checks passed"
exit 0
fi
./test-native.sh
./test-linuxcnc-source-syntax.sh "$manifest"
./test-linuxcnc-source-objects.sh "$manifest"

View File

@@ -5,38 +5,158 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_native.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_API_NATIVE_BUILD_DIR-build/api-native-test}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_API_NATIVE_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_API_NATIVE_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_API_NATIVE_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/api-native.lock"
flock 9
preflight_cache_dir="$build_dir/preflight-cache"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
var_file="$build_dir/rs274ngc-api.var"
cp "$linuxcnc_root/tests/halui/jogging/sim.var" "$var_file"
project_source_list="$build_dir/linuxcnc_rs274_api_project_sources.txt"
./list-linuxcnc-rs274-api-project-sources.sh > "$project_source_list"
mapfile -t project_sources < "$project_source_list"
common_flag_output=$(
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh \
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" \
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh \
--no-ulapi \
--python \
--core-include \
--core-src
)
mapfile -t common_flags <<<"$common_flag_output"
link_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-native-linkflags.sh)
link_flag_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-native-linkflags.sh)
mapfile -t link_flags <<<"$link_flag_output"
bridge_object_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./build-linuxcnc-native-bridge-objects.sh)
mapfile -t bridge_objects <<<"$bridge_object_output"
bridge_source_list="$build_dir/linuxcnc_bridge_smoke_project_sources.txt"
./list-linuxcnc-bridge-smoke-project-sources.sh > "$bridge_source_list"
mapfile -t bridge_sources < "$bridge_source_list"
project_source_list="$build_dir/linuxcnc_rs274_api_project_sources.txt"
./list-linuxcnc-rs274-api-project-sources.sh > "$project_source_list"
mapfile -t api_sources < "$project_source_list"
"$cxx" "${common_flags[@]}" \
-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND \
"${project_sources[@]}" \
core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp \
"${link_flags[@]}" \
-lrs274 \
-ltooldata \
-lpython3.13 \
-o "$build_dir/cnc_sim_api_linuxcnc_rs274_smoke"
is_bridge_source() {
local source=$1
local candidate
for candidate in "${bridge_sources[@]}"; do
if [[ "$candidate" == "$source" ]]; then
return 0
fi
done
return 1
}
CNC_SIM_RS274_VAR="$var_file" "$build_dir/cnc_sim_api_linuxcnc_rs274_smoke"
objects=()
project_index=0
api_extra_sources=()
for source in "${api_sources[@]}"; do
if is_bridge_source "$source"; then
continue
fi
api_extra_sources+=("$source")
objects+=("$build_dir/project_${project_index}.o")
project_index=$((project_index + 1))
done
main_object="$build_dir/cnc_sim_api_linuxcnc_rs274_smoke.o"
objects+=("$main_object")
target="$build_dir/cnc_sim_api_linuxcnc_rs274_smoke"
api_signature="$build_dir/api-native.signature"
api_next_signature="$build_dir/api-native.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'LINK_FLAGS='
printf ' %s' "${link_flags[@]}"
printf '\n'
printf 'BRIDGE_OBJECTS:\n'
printf '%s\n' "${bridge_objects[@]}"
printf 'API_EXTRA_SOURCES:\n'
printf '%s\n' "${api_extra_sources[@]}"
} > "$api_next_signature"
if [[ ! -f "$api_signature" ]] || ! cmp -s "$api_signature" "$api_next_signature"; then
rm -f "$build_dir"/project_*.o \
"$build_dir"/*.d \
"$main_object" \
"$target"
fi
mv "$api_next_signature" "$api_signature"
api_makefile="$build_dir/api-native.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'LINK_FLAGS :='
printf ' %s' "${link_flags[@]}"
printf '\n'
printf 'BRIDGE_OBJECTS :='
printf ' %s' "${bridge_objects[@]}"
printf '\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: %s\n\n' "$target"
project_index=0
for source in "${api_extra_sources[@]}"; do
source_flags=()
case "$source" in
core/src/gcode_backend.cpp)
source_flags+=(-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND)
;;
esac
printf '%s: %s\n' "$build_dir/project_${project_index}.o" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS)'
printf ' %s' "${source_flags[@]}"
printf ' -MMD -MP -MF %s.d -c %s -o %s\n\n' \
"$build_dir/project_${project_index}.o" "$source" "$build_dir/project_${project_index}.o"
project_index=$((project_index + 1))
done
printf '%s: core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp\n' "$main_object"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp -o %s\n\n' \
"$main_object" "$main_object"
printf '%s: $(BRIDGE_OBJECTS) $(OBJECTS)\n' "$target"
printf '\t@$(CXX) $(BRIDGE_OBJECTS) $(OBJECTS) $(LINK_FLAGS) -lrs274 -ltooldata -lpython3.13 -o %s\n\n' "$target"
printf '\n-include $(DEP_FILES)\n'
} > "$api_makefile"
make --output-sync=target -j"$build_jobs" -f "$api_makefile"
CNC_SIM_RS274_VAR="$var_file" "$target"
echo "linuxcnc rs274 API backend smoke passed"

View File

@@ -5,31 +5,110 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_native.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_BRIDGE_NATIVE_BUILD_DIR-build/bridge-native-test}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_BRIDGE_NATIVE_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_BRIDGE_NATIVE_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_BRIDGE_NATIVE_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/bridge-native.lock"
flock 9
preflight_cache_dir="$build_dir/preflight-cache"
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
project_source_list="$build_dir/linuxcnc_bridge_smoke_project_sources.txt"
./list-linuxcnc-bridge-smoke-project-sources.sh > "$project_source_list"
mapfile -t project_sources < "$project_source_list"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
common_flag_output=$(
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh \
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" \
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh \
--no-ulapi \
--core-include \
--core-src
)
mapfile -t common_flags <<<"$common_flag_output"
link_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-native-linkflags.sh)
link_flag_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-native-linkflags.sh)
mapfile -t link_flags <<<"$link_flag_output"
bridge_object_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./build-linuxcnc-native-bridge-objects.sh)
mapfile -t bridge_objects <<<"$bridge_object_output"
project_source_list="$build_dir/linuxcnc_bridge_smoke_project_sources.txt"
./list-linuxcnc-bridge-smoke-project-sources.sh > "$project_source_list"
"$cxx" "${common_flags[@]}" \
"${project_sources[@]}" \
core/tests/linuxcnc_canon_bridge_smoke.cpp \
"${link_flags[@]}" \
-ltooldata \
-o "$build_dir/linuxcnc_canon_bridge_smoke"
objects=()
main_object="$build_dir/linuxcnc_canon_bridge_smoke.o"
objects+=("$main_object")
target="$build_dir/linuxcnc_canon_bridge_smoke"
"$build_dir/linuxcnc_canon_bridge_smoke"
bridge_signature="$build_dir/bridge-native.signature"
bridge_next_signature="$build_dir/bridge-native.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'LINK_FLAGS='
printf ' %s' "${link_flags[@]}"
printf '\n'
printf 'BRIDGE_OBJECTS:\n'
printf '%s\n' "${bridge_objects[@]}"
} > "$bridge_next_signature"
if [[ ! -f "$bridge_signature" ]] || ! cmp -s "$bridge_signature" "$bridge_next_signature"; then
rm -f "$build_dir"/*.d \
"$main_object" \
"$target"
fi
mv "$bridge_next_signature" "$bridge_signature"
bridge_makefile="$build_dir/bridge-native.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'LINK_FLAGS :='
printf ' %s' "${link_flags[@]}"
printf '\n'
printf 'BRIDGE_OBJECTS :='
printf ' %s' "${bridge_objects[@]}"
printf '\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: %s\n\n' "$target"
printf '%s: core/tests/linuxcnc_canon_bridge_smoke.cpp\n' "$main_object"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c core/tests/linuxcnc_canon_bridge_smoke.cpp -o %s\n\n' \
"$main_object" "$main_object"
printf '%s: $(BRIDGE_OBJECTS) $(OBJECTS)\n' "$target"
printf '\t@$(CXX) $(BRIDGE_OBJECTS) $(OBJECTS) $(LINK_FLAGS) -ltooldata -o %s\n\n' "$target"
printf '\n-include $(DEP_FILES)\n'
} > "$bridge_makefile"
make --output-sync=target -j"$build_jobs" -f "$bridge_makefile"
"$target"
echo "linuxcnc canon bridge smoke passed"

View File

@@ -5,10 +5,33 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_native.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_RS274_NATIVE_BUILD_DIR-build/rs274-native-test}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_RS274_NATIVE_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_RS274_NATIVE_BUILD_DIR must not contain whitespace: $build_dir" >&2
exit 1
fi
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
mkdir -p "$build_dir"
build_dir=$(cd "$build_dir" && pwd)
if [[ "$build_dir" == "/" ]]; then
echo "CNC_SIM_RS274_NATIVE_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
preflight_cache_dir="$build_dir/preflight-cache"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
# The LinuxCNC rs274 backend path can bus-error when two dumps run concurrently.
exec 9>"${TMPDIR:-/tmp}/cnc_sim_linuxcnc_rs274_native.lock"
flock 9
@@ -36,13 +59,68 @@ mapfile -t common_flags <<<"$common_flag_output"
link_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-native-linkflags.sh)
mapfile -t link_flags <<<"$link_flag_output"
"$cxx" "${common_flags[@]}" \
"${project_sources[@]}" \
"${link_flags[@]}" \
-lrs274 \
-ltooldata \
-lpython3.13 \
-o "$build_dir/linuxcnc_rs274_dump"
project_objects=()
project_index=0
for source in "${project_sources[@]}"; do
project_objects+=("$build_dir/project_${project_index}.o")
project_index=$((project_index + 1))
done
rs274_native_signature="$build_dir/rs274-native.signature"
rs274_native_next_signature="$build_dir/rs274-native.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'LINK_FLAGS='
printf ' %s' "${link_flags[@]}"
printf '\n'
printf 'PROJECT_SOURCES:\n'
printf '%s\n' "${project_sources[@]}"
} > "$rs274_native_next_signature"
if [[ ! -f "$rs274_native_signature" ]] || ! cmp -s "$rs274_native_signature" "$rs274_native_next_signature"; then
rm -f "$build_dir"/project_*.o \
"$build_dir"/project_*.o.d \
"$build_dir/linuxcnc_rs274_dump"
fi
mv "$rs274_native_next_signature" "$rs274_native_signature"
rs274_native_makefile="$build_dir/rs274-native.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'LINK_FLAGS :='
printf ' %s' "${link_flags[@]}"
printf '\n\n'
printf 'PROJECT_OBJECTS :='
printf ' %s' "${project_objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${project_objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: %s\n\n' "$build_dir/linuxcnc_rs274_dump"
project_index=0
for source in "${project_sources[@]}"; do
printf '%s: %s\n' "${project_objects[$project_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' \
"${project_objects[$project_index]}" "$source" "${project_objects[$project_index]}"
project_index=$((project_index + 1))
done
printf '%s: $(PROJECT_OBJECTS)\n' "$build_dir/linuxcnc_rs274_dump"
printf '\t@$(CXX) $(PROJECT_OBJECTS) $(LINK_FLAGS) -lrs274 -ltooldata -lpython3.13 -o %s\n' "$build_dir/linuxcnc_rs274_dump"
printf '\n-include $(DEP_FILES)\n'
} > "$rs274_native_makefile"
make --output-sync=target -j"$build_jobs" -f "$rs274_native_makefile"
CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_basic_motion.ngc >"$output_dir/cnc_sim_linuxcnc_basic_motion.json"
CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/basic_mill.ngc >"$output_dir/cnc_sim_linuxcnc_basic_mill.json"

View File

@@ -30,9 +30,10 @@ if [[ "$build_dir" == "/" ]]; then
echo "CNC_SIM_SOURCE_LINK_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
preflight_cache_dir="$build_dir/preflight-cache"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table.sh linuxcnc-kinematics-source-files.txt
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt
# The LinuxCNC source-linked dump path is not concurrency-safe under parallel execution.
exec 9>"${TMPDIR:-/tmp}/cnc_sim_rs274_source_link.lock"
flock 9
@@ -47,9 +48,9 @@ mapfile -t common_flags <<<"$common_flag_output"
link_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-native-linkflags.sh)
mapfile -t link_flags <<<"$link_flag_output"
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full)
source_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full)
mapfile -t linuxcnc_sources <<<"$source_output"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest" --require-rs274-complete
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest" --require-rs274-complete
objects=()
linuxcnc_index=0
@@ -79,6 +80,7 @@ source_link_next_signature="$build_dir/source-link-build.signature.next"
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$(cd "$linuxcnc_root" && pwd)"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'

View File

@@ -5,24 +5,97 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_rs274_objects.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_SOURCE_OBJECTS_BUILD_DIR-build/source-objects-test}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not contain whitespace: $build_dir" >&2
exit 1
fi
manifest=${1:-linuxcnc-rs274-source-files.txt}
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
mkdir -p "$build_dir"
build_dir=$(cd "$build_dir" && pwd)
if [[ "$build_dir" == "/" ]]; then
echo "CNC_SIM_SOURCE_OBJECTS_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/source-objects.lock"
flock 9
preflight_cache_dir="$build_dir/preflight-cache"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh --python)
mapfile -t common_flags <<<"$common_flag_output"
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full)
source_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full)
mapfile -t sources <<<"$source_output"
objects=()
source_index=0
for source in "${sources[@]}"; do
obj="$build_dir/linuxcnc_${source_index}.o"
"$cxx" "${common_flags[@]}" -c "$source" -o "$obj"
objects+=("$build_dir/linuxcnc_${source_index}.o")
source_index=$((source_index + 1))
done
source_objects_signature="$build_dir/source-objects.signature"
source_objects_next_signature="$build_dir/source-objects.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$source_objects_next_signature"
if [[ ! -f "$source_objects_signature" ]] || ! cmp -s "$source_objects_signature" "$source_objects_next_signature"; then
rm -f "$build_dir"/linuxcnc_*.o "$build_dir"/linuxcnc_*.o.d
fi
mv "$source_objects_next_signature" "$source_objects_signature"
source_objects_makefile="$build_dir/source-objects.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: $(OBJECTS)\n\n'
source_index=0
for source in "${sources[@]}"; do
printf '%s: %s\n' "${objects[$source_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' \
"${objects[$source_index]}" "$source" "${objects[$source_index]}"
source_index=$((source_index + 1))
done
printf '\n-include $(DEP_FILES)\n'
} > "$source_objects_makefile"
make --output-sync=target -j"$build_jobs" -f "$source_objects_makefile"
echo "linuxcnc rs274 source object build passed (${#sources[@]} objects)"
echo "built objects in $build_dir"

View File

@@ -13,6 +13,11 @@ 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_SOURCE_SYNTAX_SELF_CHECKS:-0}
if [[ "$self_checks" != "0" && "$self_checks" != "1" ]]; then
echo "CNC_SIM_SOURCE_SYNTAX_SELF_CHECKS must be 0 or 1: $self_checks" >&2
exit 1
fi
build_dir=${CNC_SIM_SOURCE_SYNTAX_BUILD_DIR-build/source-syntax-test}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_SOURCE_SYNTAX_BUILD_DIR must not be empty" >&2
@@ -31,8 +36,9 @@ fi
exec 9>"$build_dir/source-syntax.lock"
flock 9
manifest=${1:-linuxcnc-rs274-source-files.txt}
preflight_cache_dir="$build_dir/preflight-cache"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"
missing_source_manifest=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_rs274_manifest_source.XXXXXX.txt")
missing_source_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_rs274_manifest_source.XXXXXX.log")
@@ -46,9 +52,11 @@ if awk '/^rm -f "\$missing_source_manifest" "\$missing_source_log"$/{ found = 1
echo "linuxcnc source syntax probe still relies on manual cleanup for missing-source temporaries" >&2
exit 1
fi
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full > "$source_list"
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" binding full >> "$source_list"
LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" tooldata full >> "$source_list"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" core full > "$source_list"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" binding full >> "$source_list"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-manifest-sources.sh "$manifest" tooldata full >> "$source_list"
if [[ "$self_checks" == "1" ]]; then
printf 'core:src/emc/rs274ngc/does_not_exist.cc:test missing source\n' >"$missing_source_manifest"
if ./test-linuxcnc-source-objects.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then
@@ -70,6 +78,8 @@ if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$mis
exit 1
fi
fi
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-common-cxxflags.sh --python --syntax-only)
mapfile -t common_flags <<<"$common_flag_output"
@@ -80,7 +90,7 @@ source_syntax_next_signature="$build_dir/source-syntax.signature.next"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$(cd "$linuxcnc_root" && pwd)"
printf 'MANIFEST=%s\n' "$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")"
printf 'BUILD_JOBS=%s\n' "$build_jobs"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'

View File

@@ -4,6 +4,32 @@ set -euo pipefail
cd "$(dirname "$0")"
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
self_checks=${CNC_SIM_WASM_BLOCKERS_SELF_CHECKS:-0}
if [[ "$self_checks" != "0" && "$self_checks" != "1" ]]; then
echo "CNC_SIM_WASM_BLOCKERS_SELF_CHECKS must be 0 or 1: $self_checks" >&2
exit 1
fi
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cache_dir=${CNC_SIM_WASM_BLOCKERS_CACHE_DIR-${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/wasm-blocker-cache}}
if [[ -z "$cache_dir" ]]; then
echo "CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not be empty" >&2
exit 1
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_WASM_BLOCKERS_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$cache_dir/preflight" "$manifest"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
if [[ "$self_checks" == "1" ]]; then
missing_manifest=${TMPDIR:-/tmp}/cnc_sim_missing_wasm_blocker_manifest.txt
missing_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_missing_wasm_blocker_manifest.XXXXXX.log")
@@ -49,8 +75,6 @@ if ! grep -F "missing LinuxCNC root: $missing_root" "$missing_root_log" >/dev/nu
exit 1
fi
output=$(./analyze-linuxcnc-wasm-blockers.sh "$manifest")
printf 'blocked:src/emc/tooldata/does_not_exist.cc:test missing blocked source\n' >"$missing_source_manifest"
if ./analyze-linuxcnc-wasm-blockers.sh "$missing_source_manifest" >"$missing_source_log" 2>&1; then
echo "wasm blocker analyzer accepted missing manifest source" >&2
@@ -91,6 +115,57 @@ if ! grep -F "missing blocked replacement mapping: src/emc/tooldata/tooldata_db.
exit 1
fi
fi
manifest_key=$(printf '%s' "$manifest" | sha256sum | awk '{ print $1 }')
exec 8>"$cache_dir/wasm-blockers.lock"
flock 8
cache_signature="$cache_dir/wasm-blockers.${manifest_key}.signature"
cache_output="$cache_dir/wasm-blockers.${manifest_key}.out"
next_signature="$cache_signature.next"
write_manifest_source_stats() {
local group path note source_path
while IFS=: read -r group path note; do
case "$group" in
""|\#*)
continue
;;
esac
[[ -z "${path:-}" ]] && continue
source_path="$linuxcnc_root/$path"
[[ -f "$source_path" ]] || return 1
stat -c 'SOURCE=%n:%s:%y' "$source_path"
done < "$manifest"
}
write_shim_source_hashes() {
local shim_source
while IFS= read -r shim_source; do
[[ -n "$shim_source" ]] || continue
[[ -f "$shim_source" ]] || return 1
sha256sum "$shim_source"
done < <(./list-linuxcnc-wasm-safe-shims.sh)
}
{
printf 'ANALYZER='
sha256sum analyze-linuxcnc-wasm-blockers.sh
printf 'SHIM_LISTER='
sha256sum list-linuxcnc-wasm-safe-shims.sh
printf 'MANIFEST_PATH=%s\n' "$manifest"
printf 'MANIFEST='
sha256sum "$manifest"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
write_manifest_source_stats
write_shim_source_hashes
} > "$next_signature"
if [[ -f "$cache_signature" && -f "$cache_output" ]] && cmp -s "$cache_signature" "$next_signature"; then
output=$(cat "$cache_output")
rm -f "$next_signature"
else
output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$cache_dir/preflight" LINUXCNC_ROOT="$linuxcnc_root" ./analyze-linuxcnc-wasm-blockers.sh "$manifest")
printf '%s\n' "$output" > "$cache_output"
mv "$next_signature" "$cache_signature"
fi
grep -F "[manifest]" <<<"$output" >/dev/null
grep -F "core=25" <<<"$(sed -n '/^\[manifest\]/,/^$/p' <<<"$output")" >/dev/null
grep -F "blocked=9" <<<"$(sed -n '/^\[manifest\]/,/^$/p' <<<"$output")" >/dev/null

View File

@@ -9,9 +9,19 @@ 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
@@ -37,6 +47,15 @@ invalid_build_jobs_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_build_wasm_invalid_jobs
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
@@ -48,6 +67,15 @@ cleanup_wasm_cmake_probe_temps() {
"$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:-}" \
@@ -92,9 +120,10 @@ cleanup_wasm_cmake_probe_temps() {
}
trap cleanup_wasm_cmake_probe_temps EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
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")
{
@@ -102,15 +131,23 @@ build_next_signature=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_cmake_safe_probe.sig
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'BUILD_JOBS=%s\n' "$build_jobs"
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
rm -rf "$build_dir"
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
@@ -171,8 +208,35 @@ 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 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
@@ -183,9 +247,284 @@ 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 -- './test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh "$manifest"' build-wasm.sh >/dev/null
grep -F -- './test-linuxcnc-wasm-rs274ngc-pre-link.sh "$manifest"' build-wasm.sh >/dev/null
grep -F -- './test-linuxcnc-wasm-runtime-link.sh "$manifest"' 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 '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 '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 '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
@@ -203,37 +542,34 @@ if ! awk '
exit 1
fi
if ! awk '
index($0, "LINUXCNC_ROOT=\"$linuxcnc_root\" ./check-linuxcnc-inputs.sh \"$manifest\"") { check_line = NR }
index($0, "report_file=$(mktemp ") { report_line = NR }
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 creates its report before input validation" >&2
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-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-link-blockers.sh \
test-linuxcnc-wasm-rs274ngc-pre-link.sh \
test-linuxcnc-wasm-runtime-link.sh \
test-linuxcnc-wasm-rs274ngc-pre-object.sh \
test-linuxcnc-wasm-source-objects.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; do
test-linuxcnc-wasm-rs274ngc-pre-link-blockers.sh; do
if ! awk '
$0 ~ /^trap .* EXIT$/ { trap_line = NR }
index($0, "./check-linuxcnc-inputs.sh") && !check_line { check_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 input validation" >&2
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
@@ -287,6 +623,8 @@ if grep -RInF "${forbidden_common_flags_process_substitution}LINUXCNC_ROOT=\"\$l
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
@@ -294,6 +632,31 @@ 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
@@ -305,7 +668,51 @@ grep -F 'build_next_signature=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_wasm_cmake_safe_
grep -F 'if [[ ! -f "$build_signature" ]] || ! cmp -s "$build_signature" "$build_next_signature"; then' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''LINUXCNC_ROOT=%s\n'\'' "$linuxcnc_root"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''MANIFEST=%s\n'\'' "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F 'printf '\''BUILD_JOBS=%s\n'\'' "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F '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
@@ -331,11 +738,8 @@ grep -F 'printf '\''\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n'
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 --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F -- 'cmake --build build/wasm --target cnc_sim_wasm --parallel "$build_jobs"' build-wasm.sh >/dev/null
grep -F -- 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe_objects --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F -- 'cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F -- 'cmake --build "$build_dir" --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
grep -F -- '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
@@ -394,6 +798,15 @@ if ! awk '
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 }
@@ -412,27 +825,28 @@ if ! awk '
exit 1
fi
if ! awk '
index($0, "cmake --build build/wasm --target cnc_sim_wasm_runtime_probe --parallel \"$build_jobs\"") { runtime_probe_line = NR }
index($0, "cmake --build build/wasm --target cnc_sim_wasm --parallel \"$build_jobs\"") &&
!index($0, "cnc_sim_wasm_runtime_probe") { wasm_line = NR }
END { exit !(runtime_probe_line && wasm_line && runtime_probe_line < wasm_line) }
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=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core)' build-wasm.sh >/dev/null
grep -F -- 'manifest_blocked_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked)' 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.sh "$manifest" --require-rs274-complete' 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 25 || "$manifest_blocked_count" -ne 9 ]]; then' build-wasm.sh >/dev/null
grep -Fx 'LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.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
@@ -746,6 +1160,7 @@ bad_default_manifest_log=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_bad_default_wasm_mani
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"
@@ -887,8 +1302,8 @@ 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"
./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core > "$manifest_core_sources"
./list-linuxcnc-wasm-manifest-sources.sh "$manifest" blocked > "$manifest_blocked_sources"
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")
@@ -988,21 +1403,24 @@ grep -F '$<TARGET_OBJECTS:cnc_sim_objects>' 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
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
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_objects --parallel "$build_jobs"
cmake --build "$build_dir" --target linuxcnc_rs274_wasm_safe_probe --parallel "$build_jobs"
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"
cmake --build "$build_dir" --target cnc_sim_wasm_runtime_probe --parallel "$build_jobs"
"$build_dir/cnc_sim_wasm_runtime_probe"
echo "linuxcnc wasm-safe CMake probe target passed"

View File

@@ -3,25 +3,8 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_interp_base_link.XXXXXX")
probe=$(./build-linuxcnc-wasm-standalone-probe.sh --mode interp-base-link)
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
dlfcn_shim=$(./list-linuxcnc-wasm-safe-shims.sh dlfcn.cc)
interp_base_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/rs274ngc/interp_base.cc)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
"$dlfcn_shim" \
"$interp_base_source" \
core/wasm_shims/interp_base_probe_main.cc \
-o "$build_dir/interp_base_probe"
"$build_dir/interp_base_probe"
"$probe"
echo "linuxcnc wasm interp_base link probe passed"

View File

@@ -5,10 +5,35 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_interp_find_link.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_WASM_INTERP_FIND_BUILD_DIR-build/wasm-interp-find-link}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_WASM_INTERP_FIND_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_INTERP_FIND_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_INTERP_FIND_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/interp-find.lock"
flock 9
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
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" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc)
tooldata_runtime_stubs_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_runtime_stubs.cc)
@@ -23,38 +48,71 @@ interp_find_source=${linuxcnc_sources[1]}
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --function-sections --data-sections)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
-c "$tooldata_common_source" \
-o "$build_dir/tooldata_common.o"
"$cxx" "${common_flags[@]}" \
-c "$tooldata_mmap_backend_shim" \
-o "$build_dir/tooldata_mmap_backend.o"
"$cxx" "${common_flags[@]}" \
-c "$tooldata_runtime_stubs_shim" \
-o "$build_dir/tooldata_runtime_stubs.o"
"$cxx" "${common_flags[@]}" \
-c "$rtapi_compat_shim" \
-o "$build_dir/rtapi_compat.o"
"$cxx" "${common_flags[@]}" \
-c core/wasm_shims/interp_find_probe_stubs.cc \
-o "$build_dir/interp_find_probe_stubs.o"
"$cxx" "${common_flags[@]}" \
-c "$interp_find_source" \
-o "$build_dir/interp_find.o"
"$cxx" "${common_flags[@]}" \
-c core/wasm_shims/interp_find_probe_main.cc \
-o "$build_dir/interp_find_probe_main.o"
sources=(
"$tooldata_common_source"
"$tooldata_mmap_backend_shim"
"$tooldata_runtime_stubs_shim"
"$rtapi_compat_shim"
core/wasm_shims/interp_find_probe_stubs.cc
"$interp_find_source"
core/wasm_shims/interp_find_probe_main.cc
)
objects=(
"$build_dir/tooldata_common.o"
"$build_dir/tooldata_mmap_backend.o"
"$build_dir/tooldata_runtime_stubs.o"
"$build_dir/rtapi_compat.o"
"$build_dir/interp_find_probe_stubs.o"
"$build_dir/interp_find.o"
"$build_dir/interp_find_probe_main.o"
)
"$cxx" \
"$build_dir/tooldata_common.o" \
"$build_dir/tooldata_mmap_backend.o" \
"$build_dir/tooldata_runtime_stubs.o" \
"$build_dir/rtapi_compat.o" \
"$build_dir/interp_find_probe_stubs.o" \
"$build_dir/interp_find.o" \
"$build_dir/interp_find_probe_main.o" \
-Wl,--gc-sections \
-o "$build_dir/interp_find_probe"
signature="$build_dir/interp-find.signature"
next_signature="$build_dir/interp-find.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$build_dir"/*.o "$build_dir"/*.d "$build_dir/interp_find_probe"
fi
mv "$next_signature" "$signature"
makefile="$build_dir/interp-find.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: %s/interp_find_probe\n\n' "$build_dir"
object_index=0
for source in "${sources[@]}"; do
printf '%s: %s\n' "${objects[$object_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
object_index=$((object_index + 1))
done
printf '%s/interp_find_probe: $(OBJECTS)\n' "$build_dir"
printf '\t@$(CXX) $(OBJECTS) -Wl,--gc-sections -o %s/interp_find_probe\n\n' "$build_dir"
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
"$build_dir/interp_find_probe"

View File

@@ -5,10 +5,35 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_python_c_api_symbols.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR-build/wasm-python-c-api-symbols}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_WASM_PYTHON_C_API_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_PYTHON_C_API_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_PYTHON_C_API_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/python-c-api.lock"
flock 9
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
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" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
python_c_api_shim=$(./list-linuxcnc-wasm-safe-shims.sh python_c_api_shim.cc)
runtime_shim=$(./list-linuxcnc-wasm-safe-shims.sh linuxcnc_runtime_shim.cc)
@@ -33,22 +58,114 @@ python_binding_sources=("${linuxcnc_sources[@]:6}")
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
-c "$python_c_api_shim" \
-o "$build_dir/python_c_api_shim.o"
"$cxx" "${common_flags[@]}" \
-c "$runtime_shim" \
-o "$build_dir/runtime_shim.o"
objects=(
"$build_dir/python_c_api_shim.o"
"$build_dir/runtime_shim.o"
)
object_sources=(
"$python_c_api_shim"
"$runtime_shim"
)
for source in "${python_binding_sources[@]}"; do
object_name=$(basename "$source" .cc)
objects+=("$build_dir/$object_name.o")
object_sources+=("$source")
done
nm --defined-only "$build_dir/python_c_api_shim.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/shim.exports"
signature="$build_dir/python-c-api.signature"
next_signature="$build_dir/python-c-api.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${object_sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$build_dir"/*.o "$build_dir"/*.d
fi
mv "$next_signature" "$signature"
rg -o 'Py[A-Za-z0-9_]+' "${linuxcnc_sources[@]}" \
| sed 's/^.*://' \
| LC_ALL=C sort -u \
> "$build_dir/linuxcnc.py-tokens"
makefile="$build_dir/python-c-api.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: $(OBJECTS)\n\n'
object_index=0
for source in "${object_sources[@]}"; do
printf '%s: %s\n' "${objects[$object_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
object_index=$((object_index + 1))
done
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
source_symbols_signature="$build_dir/python-c-api.source-symbols.signature"
source_symbols_next_signature="$build_dir/python-c-api.source-symbols.signature.next"
{
printf 'SOURCE_SYMBOL_RULE_VERSION=1\n'
printf 'LINUXCNC_SOURCES:\n'
printf '%s\n' "${linuxcnc_sources[@]}"
printf 'SOURCE_STATS:\n'
stat -c 'SOURCE=%n:%s:%y' "${linuxcnc_sources[@]}"
} > "$source_symbols_next_signature"
if [[ ! -f "$source_symbols_signature" || ! -f "$build_dir/linuxcnc.py-tokens" ]] ||
! cmp -s "$source_symbols_signature" "$source_symbols_next_signature"; then
rg -o 'Py[A-Za-z0-9_]+' "${linuxcnc_sources[@]}" \
| sed 's/^.*://' \
| LC_ALL=C sort -u \
> "$build_dir/linuxcnc.py-tokens"
mv "$source_symbols_next_signature" "$source_symbols_signature"
else
rm -f "$source_symbols_next_signature"
fi
object_symbols_signature="$build_dir/python-c-api.object-symbols.signature"
object_symbols_next_signature="$build_dir/python-c-api.object-symbols.signature.next"
{
printf 'OBJECT_SYMBOL_RULE_VERSION=1\n'
stat -c 'OBJECT=%n:%s:%y' "${objects[@]}"
} > "$object_symbols_next_signature"
if [[ ! -f "$object_symbols_signature" ||
! -f "$build_dir/shim.exports" ||
! -f "$build_dir/object.undefined" ||
! -f "$build_dir/object.defined" ]] ||
! cmp -s "$object_symbols_signature" "$object_symbols_next_signature"; then
nm --defined-only "$build_dir/python_c_api_shim.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/shim.exports"
nm -u "$build_dir"/*.o \
| awk '{print $2}' \
| sed '/^$/d' \
| LC_ALL=C sort -u \
> "$build_dir/object.undefined"
nm --defined-only "$build_dir"/*.o \
| awk '{print $3}' \
| sed '/^$/d' \
| LC_ALL=C sort -u \
> "$build_dir/object.defined"
mv "$object_symbols_next_signature" "$object_symbols_signature"
else
rm -f "$object_symbols_next_signature"
fi
awk '
$0 == "PyObject" { next }
@@ -99,23 +216,6 @@ grep -F "Py_DecRef" core/wasm_shims/boost/python/object.hpp >/dev/null
grep -F "_Py_NoneStructPtr" core/wasm_shims/boost/python/object.hpp >/dev/null
grep -F 'extern "C" PyObject *PyInit_gcode(void)' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null
for source in "${python_binding_sources[@]}"; do
object_name=$(basename "$source" .cc)
"$cxx" "${common_flags[@]}" \
-c "$source" \
-o "$build_dir/$object_name.o"
done
nm -u "$build_dir"/*.o \
| awk '{print $2}' \
| sed '/^$/d' \
| LC_ALL=C sort -u \
> "$build_dir/object.undefined"
nm --defined-only "$build_dir"/*.o \
| awk '{print $3}' \
| sed '/^$/d' \
| LC_ALL=C sort -u \
> "$build_dir/object.defined"
comm -23 "$build_dir/object.undefined" "$build_dir/object.defined" \
| awk '/^_?Py/ { print }' \
> "$build_dir/object.missing-python"

View File

@@ -3,23 +3,8 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_python_plugin_link.XXXXXX")
probe=$(./build-linuxcnc-wasm-standalone-probe.sh --mode python-plugin-link)
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
python_plugin_shim=$(./list-linuxcnc-wasm-safe-shims.sh python_plugin.cc)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
"$python_plugin_shim" \
core/wasm_shims/pythonplugin/python_plugin_probe_main.cc \
-o "$build_dir/python_plugin_probe"
"$build_dir/python_plugin_probe"
"$probe"
echo "linuxcnc wasm python_plugin link probe passed"

View File

@@ -4,13 +4,12 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_rs274ngc_pre_link_blockers.XXXXXX")
work_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_rs274ngc_pre_link_blockers.XXXXXX")
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
keep_report_file=0
cleanup_rs274ngc_pre_blocker_temps() {
rm -rf "$build_dir"
rm -rf "$work_dir"
if [[ "$keep_report_file" -eq 0 && -n "${report_file:-}" ]]; then
rm -f "$report_file"
fi
@@ -22,11 +21,11 @@ if awk '/^} > "\$report_file" \|\| true$/{ found = 1 } END { exit !found }' test
exit 1
fi
if ! awk '
index($0, "LINUXCNC_ROOT=\"$linuxcnc_root\" ./check-linuxcnc-inputs.sh \"$manifest\"") { check_line = NR }
index($0, "report_file=$(mktemp ") { report_line = NR }
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 creates its report before input validation" >&2
echo "rs274ngc_pre blocker scan prepares its report cache before input validation" >&2
exit 1
fi
if ! awk '
@@ -38,58 +37,69 @@ if ! awk '
echo "rs274ngc_pre blocker scan does not clean failed reports before preserving successful ones" >&2
exit 1
fi
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
report_file=$(mktemp "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_rs274ngc_pre_undefined.XXXXXX.txt")
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/wasm-probe-preflight-cache}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"
cache_dir=${CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR-build/wasm-rs274ngc-pre-link-blockers}
if [[ -z "$cache_dir" ]]; then
echo "CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR must not be empty" >&2
exit 1
fi
if [[ "$cache_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR must not contain whitespace: $cache_dir" >&2
exit 1
fi
mkdir -p "$cache_dir"
cache_dir=$(cd "$cache_dir" && pwd)
if [[ "$cache_dir" == "/" ]]; then
echo "CNC_SIM_WASM_RS274NGC_PRE_LINK_BLOCKERS_CACHE_DIR must not be the filesystem root" >&2
exit 1
fi
exec 8>"$cache_dir/rs274ngc-pre-link-blockers.lock"
flock 8
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile core20-sections)
mapfile -t common_flags <<<"$common_flag_output"
object_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./build-linuxcnc-wasm-probe-objects.sh --mode rs274ngc-pre "$manifest")
mapfile -t objects <<<"$object_output"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
shim_output=$(./list-linuxcnc-wasm-safe-shims.sh)
mapfile -t shim_sources <<<"$shim_output"
undefined_file="$work_dir/undefined.raw"
defined_file="$work_dir/defined.raw"
signature="$cache_dir/rs274ngc-pre-link-blockers.signature"
next_signature="$cache_dir/rs274ngc-pre-link-blockers.signature.next"
report_file="$cache_dir/rs274ngc-pre-link-blockers.txt"
next_report_file="$cache_dir/rs274ngc-pre-link-blockers.txt.next"
{
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'FILTER_RULE_VERSION=1\n'
printf 'OBJECTS:\n'
printf '%s\n' "${objects[@]}"
printf 'OBJECT_STATS:\n'
stat -c 'OBJECT=%n:%s:%y' "${objects[@]}"
} > "$next_signature"
if [[ -f "$signature" && -f "$report_file" ]] && cmp -s "$signature" "$next_signature"; then
keep_report_file=1
if [[ -s "$report_file" ]]; then
echo "unexpected cached unresolved project symbols after rs274ngc_pre shim coverage:" >&2
sed -n '1,120p' "$report_file" >&2
exit 1
fi
echo "linuxcnc wasm rs274ngc_pre link blocker scan passed"
echo "wrote $report_file"
rm -f "$next_signature"
exit 0
fi
report_file="$next_report_file"
rm -f "$next_report_file"
project_source_output=$(./list-linuxcnc-wasm-safe-project-sources.sh)
mapfile -t project_sources <<<"$project_source_output"
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full)
mapfile -t linuxcnc_sources <<<"$source_output"
shim_index=0
for source in "${shim_sources[@]}"; do
obj="$build_dir/shim_${shim_index}.o"
"$cxx" "${common_flags[@]}" -c "$source" -o "$obj"
shim_index=$((shim_index + 1))
done
project_index=0
for source in "${project_sources[@]}"; do
obj="$build_dir/project_${project_index}.o"
source_flags=()
case "$source" in
core/src/linuxcnc_corexykins_adapter.c|core/src/linuxcnc_genserfuncs_adapter.c|core/src/linuxcnc_xyzab_tdr_kins_adapter.c)
source_flags+=(-fpermissive)
;;
esac
"$cxx" "${common_flags[@]}" "${source_flags[@]}" -c "$source" -o "$obj"
project_index=$((project_index + 1))
done
linuxcnc_index=0
for source in "${linuxcnc_sources[@]}"; do
obj="$build_dir/linuxcnc_${linuxcnc_index}.o"
"$cxx" "${common_flags[@]}" -c "$source" -o "$obj"
linuxcnc_index=$((linuxcnc_index + 1))
done
undefined_file="$build_dir/undefined.raw"
defined_file="$build_dir/defined.raw"
nm -u "$build_dir"/*.o \
nm -u "${objects[@]}" \
| awk '{print $2}' \
| sed '/^$/d' \
| LC_ALL=C sort -u \
> "$undefined_file"
nm --defined-only "$build_dir"/*.o \
nm --defined-only "${objects[@]}" \
| awk '{print $3}' \
| sed '/^$/d' \
| LC_ALL=C sort -u \
@@ -151,6 +161,9 @@ if [[ -s "$report_file" ]]; then
exit 1
fi
mv "$next_signature" "$signature"
mv "$next_report_file" "$cache_dir/rs274ngc-pre-link-blockers.txt"
report_file="$cache_dir/rs274ngc-pre-link-blockers.txt"
echo "linuxcnc wasm rs274ngc_pre link blocker scan passed"
keep_report_file=1
echo "wrote $report_file"

View File

@@ -3,51 +3,11 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_rs274ngc_pre_link.XXXXXX")
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/wasm-probe-preflight-cache}
probe=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./build-linuxcnc-wasm-link-probe.sh --mode rs274ngc-pre "$manifest")
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile core20-sections)
mapfile -t common_flags <<<"$common_flag_output"
shim_output=$(./list-linuxcnc-wasm-safe-shims.sh)
mapfile -t sources <<<"$shim_output"
project_source_output=$(./list-linuxcnc-wasm-safe-project-sources.sh)
mapfile -t project_sources <<<"$project_source_output"
sources+=("${project_sources[@]}")
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full)
mapfile -t linuxcnc_sources <<<"$source_output"
for source in "${linuxcnc_sources[@]}"; do
sources+=("$source")
done
sources+=(core/wasm_shims/rs274ngc_pre_probe_main.cc)
objects=()
object_index=0
for source in "${sources[@]}"; do
obj="$build_dir/source_${object_index}.o"
source_flags=()
case "$source" in
core/src/linuxcnc_genserfuncs_adapter.c|core/src/linuxcnc_xyzab_tdr_kins_adapter.c)
source_flags+=(-fpermissive)
;;
esac
"$cxx" "${common_flags[@]}" "${source_flags[@]}" -c "$source" -o "$obj"
objects+=("$obj")
object_index=$((object_index + 1))
done
"$cxx" "${objects[@]}" \
-Wl,--gc-sections \
-lfmt \
-o "$build_dir/rs274ngc_pre_probe"
"$build_dir/rs274ngc_pre_probe"
"$probe"
echo "linuxcnc wasm rs274ngc_pre link probe passed"

View File

@@ -3,19 +3,6 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_rs274ngc_pre_object.XXXXXX")
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
rs274ngc_pre_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/rs274ngc/rs274ngc_pre.cc)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
-c "$rs274ngc_pre_source" \
-o "$build_dir/rs274ngc_pre.o"
./build-linuxcnc-wasm-standalone-probe.sh --mode rs274ngc-pre-object >/dev/null
echo "linuxcnc wasm rs274ngc_pre object probe passed"

View File

@@ -3,63 +3,33 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_runtime_link.XXXXXX")
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/wasm-probe-preflight-cache}
probe=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" ./build-linuxcnc-wasm-link-probe.sh --mode runtime "$manifest")
probe_dir=$(dirname "$probe")
symbol_file="$probe_dir/runtime.symbols"
symbol_signature="$probe_dir/runtime.symbols.signature"
symbol_next_signature="$probe_dir/runtime.symbols.signature.next"
{
printf 'PROBE=%s\n' "$probe"
printf 'SYMBOL_RULE_VERSION=1\n'
stat -c 'PROBE_STAT=%n:%s:%y' "$probe"
} > "$symbol_next_signature"
if [[ ! -f "$symbol_file" || ! -f "$symbol_signature" ]] || ! cmp -s "$symbol_signature" "$symbol_next_signature"; then
nm -C "$probe" > "$symbol_file"
mv "$symbol_next_signature" "$symbol_signature"
else
rm -f "$symbol_next_signature"
fi
grep -F "cnc_sim_parse_program" "$symbol_file" >/dev/null
grep -F "parse_linuxcnc_rs274_backend" "$symbol_file" >/dev/null
grep -F "parse_gcode_with_backend" "$symbol_file" >/dev/null
grep -F "Interp::read(char const*)" "$symbol_file" >/dev/null
grep -F "Interp::init()" "$symbol_file" >/dev/null
grep -E '(^| )wordexp($| )' "$symbol_file" >/dev/null
grep -E '(^| )wordfree($| )' "$symbol_file" >/dev/null
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile core20-sections)
mapfile -t common_flags <<<"$common_flag_output"
common_flags+=(-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND)
shim_output=$(./list-linuxcnc-wasm-safe-shims.sh)
mapfile -t sources <<<"$shim_output"
core_source_output=$(./list-cmake-set-sources.sh cnc_sim_core_sources core/)
mapfile -t core_sources <<<"$core_source_output"
sources+=("${core_sources[@]}")
backend_source_output=$(./list-cmake-set-sources.sh cnc_sim_linuxcnc_rs274_backend_sources core/)
mapfile -t backend_sources <<<"$backend_source_output"
sources+=("${backend_sources[@]}")
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full)
mapfile -t linuxcnc_sources <<<"$source_output"
sources+=("${linuxcnc_sources[@]}")
sources+=(core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc)
objects=()
object_index=0
for source in "${sources[@]}"; do
obj="$build_dir/source_${object_index}.o"
source_flags=()
case "$source" in
core/src/linuxcnc_genserfuncs_adapter.c|core/src/linuxcnc_xyzab_tdr_kins_adapter.c)
source_flags+=(-fpermissive)
;;
esac
"$cxx" "${common_flags[@]}" "${source_flags[@]}" -c "$source" -o "$obj"
objects+=("$obj")
object_index=$((object_index + 1))
done
"$cxx" "${objects[@]}" \
-Wl,--gc-sections \
-lfmt \
-o "$build_dir/cnc_sim_wasm_runtime_probe"
nm -C "$build_dir/cnc_sim_wasm_runtime_probe" > "$build_dir/runtime.symbols"
grep -F "cnc_sim_parse_program" "$build_dir/runtime.symbols" >/dev/null
grep -F "parse_linuxcnc_rs274_backend" "$build_dir/runtime.symbols" >/dev/null
grep -F "parse_gcode_with_backend" "$build_dir/runtime.symbols" >/dev/null
grep -F "Interp::read(char const*)" "$build_dir/runtime.symbols" >/dev/null
grep -F "Interp::init()" "$build_dir/runtime.symbols" >/dev/null
grep -E '(^| )wordexp($| )' "$build_dir/runtime.symbols" >/dev/null
grep -E '(^| )wordfree($| )' "$build_dir/runtime.symbols" >/dev/null
"$build_dir/cnc_sim_wasm_runtime_probe"
"$probe"
echo "linuxcnc wasm runtime link probe passed"

View File

@@ -5,33 +5,18 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_safe_probe.XXXXXX")
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-build/wasm-probe-preflight-cache}
shim_output=$(./list-linuxcnc-wasm-safe-shims.sh)
mapfile -t shim_sources <<<"$shim_output"
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile core20)
mapfile -t common_flags <<<"$common_flag_output"
object_output=$(CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./build-linuxcnc-wasm-probe-objects.sh --mode source-objects "$manifest")
mapfile -t objects <<<"$object_output"
if [[ "${#objects[@]}" -lt "${#shim_sources[@]}" ]]; then
echo "unexpected wasm-safe object cache count: got ${#objects[@]} fewer than ${#shim_sources[@]} shims" >&2
exit 1
fi
linuxcnc_object_count=$((${#objects[@]} - ${#shim_sources[@]}))
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full)
mapfile -t sources <<<"$source_output"
shim_index=0
for source in "${shim_sources[@]}"; do
obj="$build_dir/shim_${shim_index}.o"
"$cxx" "${common_flags[@]}" -c "$source" -o "$obj"
shim_index=$((shim_index + 1))
done
source_index=0
for source in "${sources[@]}"; do
obj="$build_dir/linuxcnc_${source_index}.o"
"$cxx" "${common_flags[@]}" -c "$source" -o "$obj"
source_index=$((source_index + 1))
done
echo "linuxcnc wasm-safe source object probe passed (${#sources[@]} linuxcnc objects + ${#shim_sources[@]} shims)"
echo "linuxcnc wasm-safe source object probe passed ($linuxcnc_object_count linuxcnc objects + ${#shim_sources[@]} shims)"

View File

@@ -6,17 +6,97 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
manifest=${1:-linuxcnc-rs274-wasm-source-files.txt}
cxx=${CXX:-g++}
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR-build/wasm-source-syntax-test}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_WASM_SOURCE_SYNTAX_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_SOURCE_SYNTAX_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_SOURCE_SYNTAX_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/wasm-source-syntax.lock"
flock 9
preflight_cache_dir=${CNC_SIM_PREFLIGHT_CACHE_DIR:-"$build_dir/preflight-cache"}
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh "$manifest"
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"
manifest=$(cd "$(dirname "$manifest")" && pwd)/$(basename "$manifest")
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --profile core20 --syntax-only)
mapfile -t common_flags <<<"$common_flag_output"
source_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full)
mapfile -t sources <<<"$source_output"
source_list="$build_dir/linuxcnc_wasm_source_syntax_sources.txt"
CNC_SIM_PREFLIGHT_CACHE_DIR="$preflight_cache_dir" LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-manifest-sources.sh "$manifest" core full > "$source_list"
for source in "${sources[@]}"; do
"$cxx" "${common_flags[@]}" "$source"
done
wasm_source_syntax_signature="$build_dir/wasm-source-syntax.signature"
wasm_source_syntax_next_signature="$build_dir/wasm-source-syntax.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'MANIFEST=%s\n' "$manifest"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
cat "$source_list"
} > "$wasm_source_syntax_next_signature"
if [[ ! -f "$wasm_source_syntax_signature" ]] || ! cmp -s "$wasm_source_syntax_signature" "$wasm_source_syntax_next_signature"; then
rm -f "$build_dir"/source_*.stamp "$build_dir"/source_*.d
fi
mv "$wasm_source_syntax_next_signature" "$wasm_source_syntax_signature"
echo "linuxcnc wasm-safe source syntax probe passed (${#sources[@]} files)"
wasm_source_syntax_makefile="$build_dir/wasm-source-syntax.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'STAMPS :=\n'
source_index=0
while IFS= read -r source; do
[[ -z "$source" ]] && continue
printf 'STAMPS += %s/source_%s.stamp\n' "$build_dir" "$source_index"
source_index=$((source_index + 1))
done < "$source_list"
printf '\n.PHONY: all\n'
printf 'all: $(STAMPS)\n\n'
source_index=0
while IFS= read -r source; do
[[ -z "$source" ]] && continue
printf '%s/source_%s.stamp: %s\n' "$build_dir" "$source_index" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s/source_%s.d %s\n' "$build_dir" "$source_index" "$source"
printf '\t@touch %s/source_%s.stamp\n\n' "$build_dir" "$source_index"
source_index=$((source_index + 1))
done < "$source_list"
printf '%s' '-include'
source_index=0
while IFS= read -r source; do
[[ -z "$source" ]] && continue
printf ' %s/source_%s.d' "$build_dir" "$source_index"
source_index=$((source_index + 1))
done < "$source_list"
printf '\n'
} > "$wasm_source_syntax_makefile"
make --output-sync=target -j"$build_jobs" -f "$wasm_source_syntax_makefile"
source_count=$(grep -c . "$source_list")
echo "linuxcnc wasm-safe source syntax probe passed ($source_count files)"

View File

@@ -3,27 +3,8 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_tooldata_common_link.XXXXXX")
probe=$(./build-linuxcnc-wasm-standalone-probe.sh --mode tooldata-common-link)
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc)
tooldata_runtime_stubs_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_runtime_stubs.cc)
tooldata_common_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/tooldata/tooldata_common.cc)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh --tooldata-include)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
"$tooldata_common_source" \
"$tooldata_mmap_backend_shim" \
"$tooldata_runtime_stubs_shim" \
core/wasm_shims/tooldata/tooldata_common_probe_main.cc \
-o "$build_dir/tooldata_common_probe"
"$build_dir/tooldata_common_probe"
"$probe"
echo "linuxcnc wasm tooldata_common link probe passed"

View File

@@ -3,29 +3,10 @@ set -euo pipefail
cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_tooldata_link.XXXXXX")
probe=$(./build-linuxcnc-wasm-standalone-probe.sh --mode tooldata-link)
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc)
tooldata_runtime_stubs_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_runtime_stubs.cc)
tooldata_common_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/tooldata/tooldata_common.cc)
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
"$tooldata_common_source" \
"$tooldata_mmap_backend_shim" \
"$tooldata_runtime_stubs_shim" \
core/wasm_shims/tooldata/tooldata_probe_main.cc \
-o "$build_dir/tooldata_probe"
"$build_dir/tooldata_probe" 2>"$build_dir/tooldata_probe.err"
grep -F "tool_mmap_user(): tool mmap not available" "$build_dir/tooldata_probe.err" >/dev/null
grep -F "tooldata_put() no tool_mmap_base" "$build_dir/tooldata_probe.err" >/dev/null
"$probe" 2>"$probe.err"
grep -F "tool_mmap_user(): tool mmap not available" "$probe.err" >/dev/null
grep -F "tooldata_put() no tool_mmap_base" "$probe.err" >/dev/null
echo "linuxcnc wasm tooldata shim link probe passed"

View File

@@ -5,10 +5,35 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_tooldata_mmap_symbols.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR-build/wasm-tooldata-mmap-symbols}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_TOOLDATA_MMAP_SYMBOLS_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_TOOLDATA_MMAP_SYMBOLS_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/tooldata-mmap-symbols.lock"
flock 9
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
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" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc)
tooldata_mmap_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-files.sh src/emc/tooldata/tooldata_mmap.cc)
@@ -16,23 +41,80 @@ tooldata_mmap_source=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-source-fil
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
-c "$tooldata_mmap_backend_shim" \
-o "$build_dir/tooldata_mmap_backend.o"
sources=(
"$tooldata_mmap_backend_shim"
"$tooldata_mmap_source"
)
objects=(
"$build_dir/tooldata_mmap_backend.o"
"$build_dir/linuxcnc_tooldata_mmap.o"
)
"$cxx" "${common_flags[@]}" \
-c "$tooldata_mmap_source" \
-o "$build_dir/linuxcnc_tooldata_mmap.o"
signature="$build_dir/tooldata-mmap-symbols.signature"
next_signature="$build_dir/tooldata-mmap-symbols.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$build_dir"/*.o "$build_dir"/*.d
fi
mv "$next_signature" "$signature"
nm --defined-only "$build_dir/tooldata_mmap_backend.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/backend.exports"
makefile="$build_dir/tooldata-mmap-symbols.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: $(OBJECTS)\n\n'
nm --defined-only "$build_dir/linuxcnc_tooldata_mmap.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/linuxcnc.exports"
object_index=0
for source in "${sources[@]}"; do
printf '%s: %s\n' "${objects[$object_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
object_index=$((object_index + 1))
done
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
symbols_signature="$build_dir/tooldata-mmap-symbols.nm.signature"
symbols_next_signature="$build_dir/tooldata-mmap-symbols.nm.signature.next"
{
printf 'SYMBOL_RULE_VERSION=1\n'
stat -c 'OBJECT=%n:%s:%y' "${objects[@]}"
} > "$symbols_next_signature"
if [[ ! -f "$symbols_signature" || ! -f "$build_dir/backend.exports" || ! -f "$build_dir/linuxcnc.exports" ]] ||
! cmp -s "$symbols_signature" "$symbols_next_signature"; then
nm --defined-only "$build_dir/tooldata_mmap_backend.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/backend.exports"
nm --defined-only "$build_dir/linuxcnc_tooldata_mmap.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/linuxcnc.exports"
mv "$symbols_next_signature" "$symbols_signature"
else
rm -f "$symbols_next_signature"
fi
if ! comm -23 "$build_dir/linuxcnc.exports" "$build_dir/backend.exports" > "$build_dir/missing.exports"; then
exit 1

View File

@@ -5,10 +5,35 @@ cd "$(dirname "$0")"
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
cxx=${CXX:-g++}
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/cnc_sim_linuxcnc_wasm_tooldata_runtime_symbols.XXXXXX")
if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then
cxx="ccache $cxx"
fi
build_jobs=${CNC_SIM_BUILD_JOBS:-8}
if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then
echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2
exit 1
fi
build_dir=${CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR-build/wasm-tooldata-runtime-symbols}
if [[ -z "$build_dir" ]]; then
echo "CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not be empty" >&2
exit 1
fi
if [[ "$build_dir" =~ [[:space:]] ]]; then
echo "CNC_SIM_WASM_TOOLDATA_RUNTIME_SYMBOLS_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_TOOLDATA_RUNTIME_SYMBOLS_BUILD_DIR must not be the filesystem root" >&2
exit 1
fi
exec 9>"$build_dir/tooldata-runtime-symbols.lock"
flock 9
trap 'rm -rf "$build_dir"' EXIT
LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs.sh --root-only
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" --root-only
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
tooldata_mmap_backend_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_mmap_backend.cc)
tooldata_runtime_stubs_shim=$(./list-linuxcnc-wasm-safe-shims.sh tooldata_runtime_stubs.cc)
@@ -22,36 +47,92 @@ tooldata_nml_source=${linuxcnc_sources[1]}
common_flag_output=$(LINUXCNC_ROOT="$linuxcnc_root" ./list-linuxcnc-wasm-common-cxxflags.sh)
mapfile -t common_flags <<<"$common_flag_output"
"$cxx" "${common_flags[@]}" \
-c "$tooldata_runtime_stubs_shim" \
-o "$build_dir/tooldata_runtime_stubs.o"
sources=(
"$tooldata_runtime_stubs_shim"
"$tooldata_mmap_backend_shim"
"$tooldata_db_source"
"$tooldata_nml_source"
)
objects=(
"$build_dir/tooldata_runtime_stubs.o"
"$build_dir/tooldata_mmap_backend.o"
"$build_dir/linuxcnc_tooldata_db.o"
"$build_dir/linuxcnc_tooldata_nml.o"
)
"$cxx" "${common_flags[@]}" \
-c "$tooldata_mmap_backend_shim" \
-o "$build_dir/tooldata_mmap_backend.o"
signature="$build_dir/tooldata-runtime-symbols.signature"
next_signature="$build_dir/tooldata-runtime-symbols.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'LINUXCNC_ROOT=%s\n' "$linuxcnc_root"
printf 'BUILD_RULE_VERSION=1\n'
printf 'COMMON_FLAGS='
printf ' %s' "${common_flags[@]}"
printf '\n'
printf 'SOURCES:\n'
printf '%s\n' "${sources[@]}"
} > "$next_signature"
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
rm -f "$build_dir"/*.o "$build_dir"/*.d
fi
mv "$next_signature" "$signature"
"$cxx" "${common_flags[@]}" \
-c "$tooldata_db_source" \
-o "$build_dir/linuxcnc_tooldata_db.o"
makefile="$build_dir/tooldata-runtime-symbols.mk"
{
printf 'CXX := %s\n' "$cxx"
printf 'COMMON_FLAGS :='
printf ' %s' "${common_flags[@]}"
printf '\n\n'
printf 'OBJECTS :='
printf ' %s' "${objects[@]}"
printf '\n\n'
printf 'DEP_FILES :=\n'
for object in "${objects[@]}"; do
printf 'DEP_FILES += %s.d\n' "$object"
done
printf '\n.PHONY: all\n'
printf 'all: $(OBJECTS)\n\n'
"$cxx" "${common_flags[@]}" \
-c "$tooldata_nml_source" \
-o "$build_dir/linuxcnc_tooldata_nml.o"
object_index=0
for source in "${sources[@]}"; do
printf '%s: %s\n' "${objects[$object_index]}" "$source"
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
object_index=$((object_index + 1))
done
printf '\n-include $(DEP_FILES)\n'
} > "$makefile"
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
nm --defined-only "$build_dir/tooldata_runtime_stubs.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/runtime.exports"
symbols_signature="$build_dir/tooldata-runtime-symbols.nm.signature"
symbols_next_signature="$build_dir/tooldata-runtime-symbols.nm.signature.next"
{
printf 'SYMBOL_RULE_VERSION=1\n'
stat -c 'OBJECT=%n:%s:%y' "${objects[@]}"
} > "$symbols_next_signature"
if [[ ! -f "$symbols_signature" ||
! -f "$build_dir/runtime.exports" ||
! -f "$build_dir/backend.exports" ||
! -f "$build_dir/linuxcnc-runtime.exports" ]] ||
! cmp -s "$symbols_signature" "$symbols_next_signature"; then
nm --defined-only "$build_dir/tooldata_runtime_stubs.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/runtime.exports"
nm --defined-only "$build_dir/tooldata_mmap_backend.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/backend.exports"
nm --defined-only "$build_dir/tooldata_mmap_backend.o" \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/backend.exports"
nm --defined-only "$build_dir"/linuxcnc_tooldata_*.o \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/linuxcnc-runtime.exports"
nm --defined-only "$build_dir"/linuxcnc_tooldata_*.o \
| awk '$2 ~ /^[A-Z]$/ {print $3}' \
| LC_ALL=C sort -u \
> "$build_dir/linuxcnc-runtime.exports"
mv "$symbols_next_signature" "$symbols_signature"
else
rm -f "$symbols_next_signature"
fi
comm -23 "$build_dir/linuxcnc-runtime.exports" "$build_dir/backend.exports" \
> "$build_dir/expected.exports"

View File

@@ -29,11 +29,12 @@ if [[ "$build_dir" == "/" ]]; then
fi
exec 9>"$build_dir/native-test.lock"
flock 9
preflight_cache_dir="$build_dir/preflight-cache"
./check-linuxcnc-inputs.sh linuxcnc-rs274-source-files.txt --require-rs274-complete
./check-linuxcnc-inputs.sh linuxcnc-rs274-wasm-source-files.txt --require-rs274-complete
./check-linuxcnc-inputs.sh linuxcnc-kinematics-source-files.txt --require-kinematics-complete
./check-linuxcnc-switchkins-remap-table.sh linuxcnc-kinematics-source-files.txt
./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-rs274-source-files.txt --require-rs274-complete
./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-rs274-wasm-source-files.txt --require-rs274-complete
./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt --require-kinematics-complete
./check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt
grep -F '#include "linuxcnc_switchkins_remap_table.inc"' core/src/cnc_sim_api.cpp >/dev/null
grep -F 'switchkins: options.switchkins' web/src/wasm-core.js >/dev/null
grep -F 'remap: options.remap' web/src/wasm-core.js >/dev/null
@@ -341,6 +342,7 @@ native_next_signature="$build_dir/native-build.signature.next"
{
printf 'CXX=%s\n' "$cxx"
printf 'PWD=%s\n' "$PWD"
printf 'BUILD_RULE_VERSION=1\n'
printf 'SMOKE_CXXFLAGS='
printf ' %s' "${smoke_cxxflags[@]}"
printf '\n'