#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
VENDOR_DIR="$ROOT_DIR/vendor/linuxcnc"
BUILD_DIR="$ROOT_DIR/build/native"
WRAP_DIR="$ROOT_DIR/runtime/core/linuxcnc_wrap"
SHIM_DIR="$ROOT_DIR/runtime/core/shims"
INCLUDE_DIR="$ROOT_DIR/runtime/core/include"
SOURCE_PROBE_MAP="$BUILD_DIR/source-probes.tsv"
NATIVE_SOURCE_PROOF_SUMMARY="$BUILD_DIR/native-source-proof-summary.tsv"
NATIVE_RUNTIME_PROBE_SUMMARY="$BUILD_DIR/native-runtime-probe-summary.tsv"
MILLTURN_USER_M_RUNTIME_PROBE="$ROOT_DIR/tests/native/probe_millturn_user_m_runtime.sh"
TOOL_DB_RUNTIME_PROBE="$ROOT_DIR/tests/native/probe_tool_db_runtime.sh"
PYTHON_REMAP_RUNTIME_PROBE="$ROOT_DIR/tests/native/probe_python_remap_runtime.sh"
MINIMAL_GCODE_FIXTURE="$ROOT_DIR/tests/fixtures/gcode/minimal_linear.ngc"
DO_WHILE_BREAK_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/do-while-break/test.ngc"
OWORD_BUG315_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/oword-bug315/test.ngc"
OWORD_BUG315_P2_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/oword-bug315-p2/test.ngc"
EXISTS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/exists/test.ngc"
RETURN_VALUE_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/return-value/test.ngc"
SUBS_FOLLOW_MAIN_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/subs-follow-main/test.ngc"
FRACTIONAL_LINENUMBERS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/fractional-linenumbers/test.ngc"
CAM_NISLEY_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/cam-nisley/cam.ngc"
CAM_NISLEY_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/interp/cam-nisley/test.tbl"
CAM_NISLEY_INI="$BUILD_DIR/cam-nisley.ini"
CRAZY_PATHS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/crazy-paths/test.ngc"
NAMEDPARAM_BUG424_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/namedparam-bug424/test.ngc"
FLOWSNAKE_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/flowsnake/flowsnake.ngc"
INSIDE_CORNERS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/inside-corners/test.ngc"
INVERSE_TIME_WITH_COMP_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/inverse-time-with-comp/inverse.ngc"
CCOMP_LATHE_COMP_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/lathe-comp/test.ngc"
CCOMP_LATHE_COMP_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/lathe-comp/test.tbl"
CCOMP_LATHE_COMP_INI="$BUILD_DIR/ccomp-lathe-comp.ini"
CCOMP_MILL_G90G91G92_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/mill-g90g91g92/test.ngc"
CCOMP_MILL_G90G91G92_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/mill-g90g91g92/test.tbl"
CCOMP_MILL_G90G91G92_INI="$BUILD_DIR/ccomp-mill-g90g91g92.ini"
CCOMP_MILL_LINE_ARC_ENTRY_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/mill-line-arc-entry/test.ngc"
CCOMP_MILL_LINE_ARC_ENTRY_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/mill-line-arc-entry/test.tbl"
CCOMP_MILL_LINE_ARC_ENTRY_INI="$BUILD_DIR/ccomp-mill-line-arc-entry.ini"
CCOMP_MILL_ZCHANGES_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/mill-zchanges/test.ngc"
CCOMP_MILL_ZCHANGES_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/ccomp/mill-zchanges/test.tbl"
CCOMP_MILL_ZCHANGES_INI="$BUILD_DIR/ccomp-mill-zchanges.ini"
BAD_A_IN_CANNED_CYCLE_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/a-in-canned-cycle.ngc"
BAD_A_IN_CANNED_CYCLE2_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/a-in-canned-cycle2.ngc"
BAD_ARC_BIG_IMPERIAL_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/bad-arc.big.imperial.center-format.ngc"
BAD_ARC_BIG_METRIC_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/bad-arc.big.metric.center-format.ngc"
BAD_ARC_MEDIUM_IMPERIAL_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/bad-arc.medium.imperial.center-format.ngc"
BAD_ARC_MEDIUM_METRIC_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/bad-arc.medium.metric.center-format.ngc"
BAD_ARC_SMALL_IMPERIAL_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/bad-arc.small.imperial.center-format.ngc"
BAD_ARC_SMALL_METRIC_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/bad-arc.small.metric.center-format.ngc"
BAD_CCOMP_ARCEXIT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/ccomp-arcexit.ngc"
BAD_CCOMP_GOUGING_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/ccomp-gouging.ngc"
BAD_EXISTS_1_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-1.ngc"
BAD_EXISTS_2_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-2.ngc"
BAD_EXISTS_3_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-3.ngc"
BAD_EXISTS_4_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-4.ngc"
BAD_EXISTS_5_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-5.ngc"
BAD_EXISTS_6_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-6.ngc"
BAD_EXISTS_7_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/exists-7.ngc"
BAD_NESTED_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/nested.ngc"
BAD_NO_FEED_RATE_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/no-feed-rate.ngc"
BAD_NO_IJR_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/no-ijr.ngc"
BAD_PROBE_NO_AXES_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/bad/probe-no-axes.ngc"
G33_1_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g33.1/g33.1.ngc"
G6164_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g6164/test.ngc"
GOOD_ARC_BIG_IMPERIAL_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/good/good-arc.big.imperial.center-format.ngc"
GOOD_ARC_BIG_METRIC_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/good/good-arc.big.metric.center-format.ngc"
GOOD_ARC_MEDIUM_IMPERIAL_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/good/good-arc.medium.imperial.center-format.ngc"
GOOD_ARC_MEDIUM_METRIC_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/good/good-arc.medium.metric.center-format.ngc"
GOOD_ARC_SMALL_IMPERIAL_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/good/good-arc.small.imperial.center-format.ngc"
GOOD_ARC_SMALL_METRIC_CENTER_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/good/good-arc.small.metric.center-format.ngc"
G72_FACING_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g72-facing/g72-iterations-present.ngc"
G72_MISSING_ITERATION_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g72-missing-iteration/g72-iterations-missing.ngc"
G71_ENDLESS_LOOP_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g71-endless-loop/g71-endless-loop.ngc"
G71_ENDLESS_LOOP2_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g71-endless-loop2/g71-endless-loop2.ngc"
G71_ENDLESS_LOOP_2_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g71-endless-loop_2/g71-endless-loop_2.ngc"
G71_WITH_G70_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g71-with-g70/g71-with-g70.ngc"
G76_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g76/g76only.ngc"
G76_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g76/test.tbl"
G76_INI="$BUILD_DIR/g76.ini"
ROTATION_ABS_PTS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/rotation/abs-pts/test.ngc"
ROTATION_G28_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/rotation/g28/g28.ngc"
ROTATION_G53_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/rotation/g53/g53.ngc"
INIPARAM_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/iniparam/test.ngc"
INIPARAM_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/iniparam/test.ini"
INIPARAM_FAILASSIGN_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/iniparam-failassign/test.ngc"
INIPARAM_FAILASSIGN_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/iniparam-failassign/test.ini"
SUB_CALL_FROM_SUB_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/sub-call-from-sub/test.ngc"
SUB_CALL_FROM_SUB_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/sub-call-from-sub/test.ini"
SEQUENCE_NUMBER_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/sequence-number/test.ngc"
SEQUENCE_NUMBER_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/sequence-number/test.ini"
NESTED_SUB_ERROR_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/nested-sub-error/test.ngc"
NESTED_SUB_ERROR_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/nested-sub-error/test.ini"
NESTED_SUB_IN_FILE_ERROR_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/nested-sub-in-file-error/test.ngc"
NESTED_SUB_IN_FILE_ERROR_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/nested-sub-in-file-error/test.ini"
OWORD_UNWIND_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/oword-unwind/test.ngc"
OWORD_UNWIND_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/oword-unwind/test.ini"
ABORT_HOT_COMMENT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/abort-hot-comment/test.ngc"
ABORT_HOT_COMMENT_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/abort-hot-comment/test.ini"
M19_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m19/test.ngc"
M19_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/m19/test.ini"
MAGIC_COMMENTS_PARAM_FORMAT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/magic_comments/param_format_printing/test.ngc"
M98M99_01_BASICS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/01-basics/test.ngc"
M98M99_02_VARIABLES_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/02-variables/test.ngc"
M98M99_03_ERROR_M98_NO_P_WORD_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/03-error-M98-no-P-word/test.ngc"
M98M99_04_M98_BUT_NO_SUB_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/04-M98-but-no-sub/test.ngc"
M98M99_05_M98_LOOPS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/05-M98-loops/test.ngc"
M98M99_06_CALLED_WITH_O_CALL_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/06-error-mixed-sub-styles/O...-called-with-O..._call.ngc"
M98M99_06_ENDED_WITH_O_ENDSUB_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/06-error-mixed-sub-styles/O...-ended-with-O..._endsub.ngc"
M98M99_06_SUB_CALLED_WITH_M98_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/06-error-mixed-sub-styles/O...-sub-called-with-M98.ngc"
M98M99_06_SUB_ENDED_WITH_M99_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/06-error-mixed-sub-styles/O...-sub-ended-with-M99.ngc"
M98M99_07_NESTED_SUBS_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/07-nested-subs/test.ngc"
M98M99_08_SUB_FOLLOWS_MAIN_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/08-sub-follows-main/test.ngc"
M98M99_09_FANUC_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/09-disable-fanuc-subs/test-fanuc.ngc"
M98M99_09_RS274NGC_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/09-disable-fanuc-subs/test-rs274ngc.ngc"
M98M99_09_FANUC_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/09-disable-fanuc-subs/test-fanuc.ini"
M98M99_09_NO_FANUC_INI="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/09-disable-fanuc-subs/test-no-fanuc.ini"
M98M99_10_M98_P001_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/10-M98-P001/test.ngc"
M98M99_11_LEGAL_M2_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-legal-end-main-with-m2.ngc"
M98M99_11_LEGAL_M02_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-legal-end-main-with-m02.ngc"
M98M99_11_LEGAL_M30_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-legal-end-main-with-m30.ngc"
M98M99_11_LEGAL_PERCENT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-legal-end-main-with-percent.ngc"
M98M99_11_ILLEGAL_EOF_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-illegal-end-main-with-eof.ngc"
M98M99_11_ILLEGAL_NO_M30_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-illegal-no-m30-before-osub.ngc"
M98M99_11_ILLEGAL_SUB_AFTER_PERCENT_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/11-main-program-oword/test-illegal-sub-after-percent.ngc"
M98M99_13_NAMED_PROGRAM_NAMED_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/13-named-program/test-named.ngc"
M98M99_13_NAMED_PROGRAM_NUMBERED_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/13-named-program/test-numbered.ngc"
M98M99_14_O_EXPRESSION_CALL_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/m98m99/14-o-expression-call/test.ngc"
G10_L1_L10_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-l1-l10/test.ngc"
G10_L1_L10_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-l1-l10/test.tbl"
G10_L1_L10_INI="$BUILD_DIR/g10-l1-l10.ini"
G10_L11_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-l11/test.ngc"
G10_L11_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-l11/test.tbl"
G10_L11_INI="$BUILD_DIR/g10-l11.ini"
G10_L2_WHILE_ACTIVE_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-l2-while-active/test.ngc"
G10_L20_WHILE_ACTIVE_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-l20-while-active/test.ngc"
G10_WITH_G92_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-with-g92/test.ngc"
G10_WITH_G92_TOOL_TABLE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g10/g10-with-g92/test.tbl"
G10_WITH_G92_INI="$BUILD_DIR/g10-with-g92.ini"
G52_G92_INTERACTION_FIXTURE="$ROOT_DIR/vendor/linuxcnc/tests/interp/g52/g52-g92-interaction/g52-g92-interaction.ngc"
G92_PERSISTENCE_FIXTURE="$BUILD_DIR/g92-persistence.ngc"
G92_PERSISTENCE_PARAMETER_FILE="$BUILD_DIR/g92-persistence.var"
G92_PERSISTENCE_INI="$BUILD_DIR/g92-persistence.ini"
G92_PERSISTENCE_DISABLED_INI="$BUILD_DIR/g92-persistence-disabled.ini"
SIM_AXIS_FOAM_FIXTURE="$ROOT_DIR/../linuxcnc/configs/sim/axis/foam/foam.ngc"
SIM_AXIS_FOAM_INI="$ROOT_DIR/../linuxcnc/configs/sim/axis/foam/axis_foam.ini"
SIM_BRIDGEMILL_FIXTURE="$ROOT_DIR/../linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axisgui.ngc"
SIM_BRIDGEMILL_INI="$ROOT_DIR/../linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini"
SIM_GEOMETRY_XYZC_FIXTURE="$ROOT_DIR/../linuxcnc/configs/sim/axis/geometry/xyzc.ngc"
SIM_GEOMETRY_XYZC_INI="$ROOT_DIR/../linuxcnc/configs/sim/axis/geometry/xyzc.ini"
SIM_EXTERNAL_OFFSETS_DYN_FIXTURE="$ROOT_DIR/../linuxcnc/configs/sim/axis/external_offsets/dyn_demo.ngc"
SIM_EXTERNAL_OFFSETS_DYN_INI="$ROOT_DIR/../linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.ini"
NAMEDPARAM_INI_FIXTURE="$ROOT_DIR/tests/fixtures/ini/namedparams.ini"
CXX="${CXX:-g++}"
CC="${CC:-gcc}"
CACHE_KEY_FILE="$BUILD_DIR/native-probes.input.sha256"
CACHE_OK_FILE="$BUILD_DIR/native-probes.ok"
CACHE_OUTPUT_MANIFEST="$BUILD_DIR/native-probes.outputs"
NATIVE_PROBE_RUN_TIMEOUT_SECONDS="${NATIVE_PROBE_RUN_TIMEOUT_SECONDS:-60}"

mkdir -p "$BUILD_DIR"

hash_tree() {
  find "$@" -type f -print0 | sort -z | xargs -0 -r sha256sum
}

native_input_fingerprint() {
  {
    printf 'CXX=%s\n' "$CXX"
    "$CXX" --version 2>/dev/null | sed -n '1p' || true
    printf 'CC=%s\n' "$CC"
    "$CC" --version 2>/dev/null | sed -n '1p' || true
    sha256sum \
      "$ROOT_DIR/tools/build_native_probes.sh" \
      "$ROOT_DIR/tools/source-manifest.txt"
    hash_tree \
      "$VENDOR_DIR" \
      "$WRAP_DIR" \
      "$SHIM_DIR" \
      "$INCLUDE_DIR" \
      "$ROOT_DIR/tests/fixtures"
    hash_tree \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/vismach/millturn/mcodes" \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/vismach/millturn/remap_subs"
    sha256sum \
      "$MILLTURN_USER_M_RUNTIME_PROBE" \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini"
    hash_tree \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/db_demo"
    sha256sum \
      "$TOOL_DB_RUNTIME_PROBE" \
      "$ROOT_DIR/../linuxcnc/src/emc/task/taskclass.cc" \
      "$ROOT_DIR/../linuxcnc/src/emc/tooldata/tooldata_db.cc" \
      "$ROOT_DIR/../linuxcnc/src/emc/tooldata/tooldata_common.cc"
    hash_tree \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/laser" \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/remap/cycle" \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/nc_files/remap_lib/python-stdglue" \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating" \
      "$ROOT_DIR/../linuxcnc/configs/sim/gmoccapy/python"
    sha256sum \
      "$ROOT_DIR/../linuxcnc/src/emc/rs274ngc/interp_python.cc" \
      "$ROOT_DIR/../linuxcnc/src/emc/pythonplugin/python_plugin.cc" \
      "$PYTHON_REMAP_RUNTIME_PROBE"
    hash_tree \
      "$ROOT_DIR/../linuxcnc/configs/sim/axis/remap/stop-lookahead"
  } | sha256sum | awk '{ print $1 }'
}

cached_native_outputs_exist() {
  [[ -f "$CACHE_OUTPUT_MANIFEST" ]] || return 1
  [[ -s "$SOURCE_PROBE_MAP" ]] || return 1

  local file
  while IFS= read -r file; do
    [[ -z "$file" ]] && continue
    [[ -f "$file" ]] || return 1
  done < "$CACHE_OUTPUT_MANIFEST"
}

write_native_cache_stamp() {
  local key="$1"
  printf '%s\n' "$key" > "$CACHE_KEY_FILE"
  find "$BUILD_DIR" -maxdepth 1 -type f \
    ! -name 'native-probes.input.sha256' \
    ! -name 'native-probes.ok' \
    ! -name 'native-probes.outputs' \
    -print | sort > "$CACHE_OUTPUT_MANIFEST"
  printf '%s\n' "$key" > "$CACHE_OK_FILE"
}

NATIVE_INPUT_FINGERPRINT="$(native_input_fingerprint)"
if [[ -f "$CACHE_KEY_FILE" && -f "$CACHE_OK_FILE" ]] &&
   [[ "$(tr -d '[:space:]' < "$CACHE_KEY_FILE")" == "$NATIVE_INPUT_FINGERPRINT" ]] &&
   [[ "$(tr -d '[:space:]' < "$CACHE_OK_FILE")" == "$NATIVE_INPUT_FINGERPRINT" ]] &&
   cached_native_outputs_exist; then
  echo "native probes up to date"
  exit 0
fi

: > "$SOURCE_PROBE_MAP"

COMMON_FLAGS=(
  -std=c++20
  -O2
  -D_GNU_SOURCE
  -DM_PI=3.14159265358979323846
  -DOBJECT_FWD_DWA2002724_HPP
  -I"$WRAP_DIR"
  -I"$SHIM_DIR"
  -I"$INCLUDE_DIR"
  -I"$VENDOR_DIR/src"
  -I"$VENDOR_DIR/src/rtapi"
  -I"$VENDOR_DIR/src/emc"
  -I"$VENDOR_DIR/src/emc/nml_intf"
  -I"$VENDOR_DIR/src/emc/motion"
  -I"$VENDOR_DIR/src/emc/tp"
  -I"$VENDOR_DIR/src/emc/kinematics"
  -I"$VENDOR_DIR/src/libnml/posemath"
)

COMMON_INI_FLAGS=(
  "${COMMON_FLAGS[@]}"
  -I"$VENDOR_DIR/src/emc/ini"
)

REMAP_SOURCE_FLAGS=(
  "${COMMON_INI_FLAGS[@]}"
  -include "$SHIM_DIR/linuxcnc_remap_compile_compat.hh"
)

VENDOR_ASSET_FLAGS=(
  "${COMMON_INI_FLAGS[@]}"
  -DLINUXCNC_VENDOR_DIR=\"$VENDOR_DIR\"
)

SOURCE_CONFIG_ASSET_FLAGS=(
  "${COMMON_INI_FLAGS[@]}"
  -DLINUXCNC_SOURCE_DIR=\"$ROOT_DIR/../linuxcnc\"
  -DLINUXCNC_SOURCE_CONFIG_DIR=\"$ROOT_DIR/../linuxcnc/configs/sim\"
)

MINIMAL_FLAGS=(
  "${COMMON_INI_FLAGS[@]}"
  -ffunction-sections
  -fdata-sections
  -DUNIT_TEST
  -DLINUXCNC_STANDALONE_USE_RS274_PRE_STATE
)

REMAP_RUNTIME_FLAGS=(
  "${MINIMAL_FLAGS[@]}"
  -DLINUXCNC_VENDOR_DIR=\"$VENDOR_DIR\"
  -include "$SHIM_DIR/linuxcnc_remap_compile_compat.hh"
)

INTERP_BASE_FLAGS=(
  "${MINIMAL_FLAGS[@]}"
  -DEMC2_HOME=\"/standalone\"
)

MINIMAL_LINK_FLAGS=(
  -Wl,--gc-sections
)

TP_FLAGS=(
  "${COMMON_FLAGS[@]}"
  -fpermissive
)

C_FLAGS=(
  -std=gnu11
  -O2
  -D_GNU_SOURCE
  -DM_PI=3.14159265358979323846
  -I"$WRAP_DIR"
  -I"$SHIM_DIR"
  -I"$INCLUDE_DIR"
  -I"$VENDOR_DIR/src"
  -I"$VENDOR_DIR/src/rtapi"
  -I"$VENDOR_DIR/src/emc"
  -I"$VENDOR_DIR/src/emc/nml_intf"
  -I"$VENDOR_DIR/src/emc/motion"
  -I"$VENDOR_DIR/src/emc/tp"
  -I"$VENDOR_DIR/src/emc/kinematics"
  -I"$VENDOR_DIR/src/libnml/posemath"
)

write_command_file() {
  local file="$1"
  shift
  printf '%q\n' "$@" > "$file"
}

write_file_if_changed() {
  local file="$1"
  local tmp
  tmp="$(mktemp)"
  cat > "$tmp"
  if [[ -f "$file" ]] && cmp -s "$tmp" "$file"; then
    rm -f "$tmp"
    return 0
  fi
  mv "$tmp" "$file"
}

stdout_value() {
  local file="$1"
  local key="$2"

  awk -F= -v key="$key" '$1 == key { value = substr($0, length(key) + 2) } END { print value }' "$file"
}

append_native_source_proof_summary_row() {
  local tmp="$1"
  local boundary="$2"
  local proof_key="$3"
  local execution_key="$4"
  local promotion_key="$5"
  local stdout_log="$6"

  local proof_value
  local execution_enabled
  local promotion_allowed
  proof_value="$(stdout_value "$stdout_log" "$proof_key")"
  execution_enabled="$(stdout_value "$stdout_log" "$execution_key")"
  promotion_allowed="$(stdout_value "$stdout_log" "$promotion_key")"

  printf '%s\t%s\t%s\t%s\t%s\t%s\n' \
    "$boundary" \
    "$proof_key" \
    "$proof_value" \
    "$execution_enabled" \
    "$promotion_allowed" \
    "${stdout_log#"$BUILD_DIR"/}" >> "$tmp"
}

write_native_source_proof_summary() {
  local tmp
  tmp="$(mktemp)"
  printf '%s\t%s\t%s\t%s\t%s\t%s\n' \
    boundary_class \
    proof_key \
    proof_value \
    execution_enabled \
    promotion_allowed \
    stdout_log > "$tmp"

  append_native_source_proof_summary_row \
    "$tmp" \
    L4-USER-M-PROCESS \
    millturn_user_m_native_source_state_proof \
    millturn_user_m_execution_enabled \
    millturn_user_m_promotion_allowed \
    "$BUILD_DIR/linuxcnc_millturn_user_m_boundary_probe.run.stdout.log"

  append_native_source_proof_summary_row \
    "$tmp" \
    L4-TOOL-DB \
    tool_db_native_source_protocol_proof \
    tool_db_execution_enabled \
    tool_db_promotion_allowed \
    "$BUILD_DIR/linuxcnc_tool_db_boundary_probe.run.stdout.log"

  append_native_source_proof_summary_row \
    "$tmp" \
    L4-PYTHON-REMAP \
    python_remap_native_source_inventory_proof \
    python_remap_execution_enabled \
    python_remap_promotion_allowed \
    "$BUILD_DIR/linuxcnc_python_remap_boundary_probe.run.stdout.log"

  if [[ -f "$NATIVE_SOURCE_PROOF_SUMMARY" ]] && cmp -s "$tmp" "$NATIVE_SOURCE_PROOF_SUMMARY"; then
    rm -f "$tmp"
    return 0
  fi
  mv "$tmp" "$NATIVE_SOURCE_PROOF_SUMMARY"
}

append_native_runtime_probe_summary_row() {
  local tmp="$1"
  local boundary_class="$2"
  local boundary_kind="$3"
  local target="$4"
  local runtime_probe="$5"
  local required_native_proof="$6"
  local opt_in_env="$7"
  local prefix="$8"
  local stdout_log="$9"

  local runtime_ready
  local source_proof_ready
  local probe_status
  local execution_enabled
  local promotion_allowed
  local missing_requirements
  local probe_note
  runtime_ready="$(stdout_value "$stdout_log" "${prefix}_runtime_ready")"
  source_proof_ready="$(stdout_value "$stdout_log" "${prefix}_source_proof_ready")"
  probe_status="$(stdout_value "$stdout_log" "${prefix}_runtime_probe_status")"
  execution_enabled="$(stdout_value "$stdout_log" "${prefix}_execution_enabled")"
  promotion_allowed="$(stdout_value "$stdout_log" "${prefix}_promotion_allowed")"
  missing_requirements="$(stdout_value "$stdout_log" "${prefix}_missing_requirements")"
  probe_note="$(stdout_value "$stdout_log" "${prefix}_runtime_probe_note")"

  printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
    "$boundary_class" \
    "$boundary_kind" \
    "$target" \
    "$runtime_probe" \
    "$required_native_proof" \
    "$opt_in_env" \
    "$runtime_ready" \
    "$source_proof_ready" \
    "$probe_status" \
    "$execution_enabled" \
    "$promotion_allowed" \
    "${missing_requirements:-"-"}" \
    "${probe_note:-"-"}" \
    "${stdout_log#"$BUILD_DIR"/}" >> "$tmp"
}

write_native_runtime_probe_summary() {
  local tmp
  tmp="$(mktemp)"
  printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
    boundary_class \
    boundary_kind \
    target \
    runtime_probe \
    required_native_proof \
    opt_in_env \
    runtime_ready \
    source_proof_ready \
    probe_status \
    execution_enabled \
    promotion_allowed \
    missing_requirements \
    probe_note \
    stdout_log > "$tmp"

  append_native_runtime_probe_summary_row \
    "$tmp" \
    L4-USER-M-PROCESS \
    external_user_m_process \
    axis/vismach/millturn/example.ngc \
    linuxcnc_millturn_user_m_runtime_probe \
    native_runtime_state_probe_required \
    ENABLE_MILLTURN_USER_M_RUNTIME_PROBE=1 \
    millturn_user_m \
    "$BUILD_DIR/linuxcnc_millturn_user_m_runtime_probe.run.stdout.log"

  append_native_runtime_probe_summary_row \
    "$tmp" \
    L4-TOOL-DB \
    tool_database_process \
    axis/db_demo/base.ngc \
    linuxcnc_tool_db_runtime_probe \
    native_db_process_protocol_probe_required \
    ENABLE_TOOL_DB_RUNTIME_PROBE=1 \
    tool_db \
    "$BUILD_DIR/linuxcnc_tool_db_runtime_probe.run.stdout.log"

  append_native_runtime_probe_summary_row \
    "$tmp" \
    L4-PYTHON-REMAP \
    python_runtime \
    axis/remap/stop-lookahead/nc_files \
    linuxcnc_python_remap_runtime_probe \
    linuxcnc_python_runtime_lifecycle_probe_required \
    ENABLE_PYTHON_REMAP_RUNTIME_PROBE=1 \
    python_remap \
    "$BUILD_DIR/linuxcnc_python_remap_runtime_probe.run.stdout.log"

  if [[ -f "$NATIVE_RUNTIME_PROBE_SUMMARY" ]] && cmp -s "$tmp" "$NATIVE_RUNTIME_PROBE_SUMMARY"; then
    rm -f "$tmp"
    return 0
  fi
  mv "$tmp" "$NATIVE_RUNTIME_PROBE_SUMMARY"
}

write_ccomp_ini() {
  local file="$1"
  local tool_table="$2"

  write_file_if_changed "$file" <<EOF
[EMCIO]
TOOL_TABLE = $tool_table
[TRAJ]
COORDINATES = X Y Z A B C U V W
EOF
}

write_tool_table_ini() {
  local file="$1"
  local tool_table="$2"

  write_file_if_changed "$file" <<EOF
[EMCIO]
TOOL_TABLE = $tool_table
[TRAJ]
COORDINATES = X Y Z A B C U V W
EOF
}

write_g92_persistence_files() {
  write_file_if_changed "$G92_PERSISTENCE_FIXTURE" <<EOF
(PRINT,Startup G92 params: #5210 #5211 #5212 #5213)
M30
EOF

  write_file_if_changed "$G92_PERSISTENCE_PARAMETER_FILE" <<EOF
5210 1
5211 1.25
5212 2.5
5213 3.75
5220 1
EOF

  write_file_if_changed "$G92_PERSISTENCE_INI" <<EOF
[RS274NGC]
PARAMETER_FILE = $(basename "$G92_PERSISTENCE_PARAMETER_FILE")
[TRAJ]
COORDINATES = X Y Z
EOF

  write_file_if_changed "$G92_PERSISTENCE_DISABLED_INI" <<EOF
[RS274NGC]
PARAMETER_FILE = $(basename "$G92_PERSISTENCE_PARAMETER_FILE")
DISABLE_G92_PERSISTENCE = 1
[TRAJ]
COORDINATES = X Y Z
EOF
}

command_matches() {
  local file="$1"
  shift

  local tmp
  tmp="$(mktemp)"
  write_command_file "$tmp" "$@"
  if [[ -f "$file" ]] && cmp -s "$tmp" "$file"; then
    rm -f "$tmp"
    return 0
  fi
  rm -f "$tmp"
  return 1
}

depfile_newer_than() {
  local depfile="$1"
  local output="$2"

  [[ -f "$depfile" ]] || return 0
  local deps
  deps="$(tr '\\\n' '  ' < "$depfile" | sed -e 's/^[^:]*://')"
  local dep
  for dep in $deps; do
    if [[ -f "$dep" && "$dep" -nt "$output" ]]; then
      return 0
    fi
  done
  return 1
}

object_needs_rebuild() {
  local obj="$1"
  local depfile="$2"
  local cmdfile="$3"
  shift 3

  [[ -f "$obj" ]] || return 0
  command_matches "$cmdfile" "$@" || return 0
  depfile_newer_than "$depfile" "$obj" && return 0
  return 1
}

shared_object_path() {
  local source="$1"
  shift

  local base key
  base="$(basename "$source")"
  key="$(
    {
      printf 'source=%q\n' "$source"
      printf 'arg=%q\n' "$@"
    } | sha256sum | awk '{ print $1 }'
  )"
  printf '%s/obj/shared/%s-%s.o\n' "$BUILD_DIR" "${base%.*}" "$key"
}

compile_object() {
  local target="$1"
  local source="$2"
  local obj="$3"
  shift 3

  local stdout_log="$BUILD_DIR/$target.stdout.log"
  local stderr_log="$BUILD_DIR/$target.stderr.log"
  local depfile="$obj.d"
  local cmdfile="$obj.cmd"
  local cmd=("$CXX" "$@" -MMD -MP -MF "$depfile" -c "$source" -o "$obj")

  mkdir -p "$(dirname "$obj")"
  if ! object_needs_rebuild "$obj" "$depfile" "$cmdfile" "${cmd[@]}"; then
    printf 'up to date: %s\n' "$source" >> "$stdout_log"
    return 0
  fi

  printf 'compile: %s\n' "$source" >> "$stdout_log"
  if "${cmd[@]}" >> "$stdout_log" 2>> "$stderr_log"; then
    write_command_file "$cmdfile" "${cmd[@]}"
    return 0
  fi
  return 1
}

compile_c_object() {
  local target="$1"
  local source="$2"
  local obj="$3"
  shift 3

  local stdout_log="$BUILD_DIR/$target.stdout.log"
  local stderr_log="$BUILD_DIR/$target.stderr.log"
  local depfile="$obj.d"
  local cmdfile="$obj.cmd"
  local cmd=("$CC" "$@" -MMD -MP -MF "$depfile" -c "$source" -o "$obj")

  mkdir -p "$(dirname "$obj")"
  if ! object_needs_rebuild "$obj" "$depfile" "$cmdfile" "${cmd[@]}"; then
    printf 'up to date: %s\n' "$source" >> "$stdout_log"
    return 0
  fi

  printf 'compile-c: %s\n' "$source" >> "$stdout_log"
  if "${cmd[@]}" >> "$stdout_log" 2>> "$stderr_log"; then
    write_command_file "$cmdfile" "${cmd[@]}"
    return 0
  fi
  return 1
}

record_source_probe() {
  local target="$1"
  local source="$2"

  [[ "$target" == *_source_probe ]] || return 0
  [[ "$source" == "$VENDOR_DIR/"* ]] || return 0
  printf '%s\t%s\n' "${source#"$VENDOR_DIR"/}" "$target" >> "$SOURCE_PROBE_MAP"
}

link_needs_rebuild() {
  local output="$1"
  local cmdfile="$2"
  shift 2

  [[ -f "$output" ]] || return 0
  command_matches "$cmdfile" "$@" || return 0

  local arg
  for arg in "$@"; do
    if [[ -f "$arg" && "$arg" -nt "$output" ]]; then
      return 0
    fi
  done
  return 1
}

link_binary() {
  local target="$1"
  local output="$2"
  shift 2

  local stdout_log="$BUILD_DIR/$target.stdout.log"
  local stderr_log="$BUILD_DIR/$target.stderr.log"
  local cmdfile="$output.cmd"
  local cmd=("$CXX" "$@" -o "$output")

  if ! link_needs_rebuild "$output" "$cmdfile" "${cmd[@]}"; then
    printf 'up to date: %s\n' "$output" >> "$stdout_log"
    return 0
  fi

  printf 'link: %s\n' "$output" >> "$stdout_log"
  if "${cmd[@]}" >> "$stdout_log" 2>> "$stderr_log"; then
    write_command_file "$cmdfile" "${cmd[@]}"
    return 0
  fi
  return 1
}

compile_target_objects() {
  local target="$1"
  local flags_name="$2"
  local sources_name="$3"
  local objs_name="$4"

  local -n flags="$flags_name"
  local -n sources="$sources_name"
  local -n objs="$objs_name"
  local status=0

  objs=()
  local source
  for source in "${sources[@]}"; do
    local obj
    obj="$(shared_object_path "$source" "${flags[@]}")"
    objs+=("$obj")
    if ! compile_object "$target" "$source" "$obj" "${flags[@]}"; then
      status=1
    fi
  done

  return "$status"
}

build_binary_target() {
  local target="$1"
  local output="$2"
  local flags_name="$3"
  local sources_name="$4"
  local link_flags_name="$5"
  shift 5

  local stdout_log="$BUILD_DIR/$target.stdout.log"
  local stderr_log="$BUILD_DIR/$target.stderr.log"
  : > "$stdout_log"
  : > "$stderr_log"

  local target_objs=()
  local status=0
  if ! compile_target_objects "$target" "$flags_name" "$sources_name" target_objs; then
    status=1
  fi

  if [[ "$status" -eq 0 ]]; then
    local -n link_flags="$link_flags_name"
    if ! link_binary "$target" "$output" "${link_flags[@]}" "${target_objs[@]}" "$@"; then
      status=1
    fi
  fi

  echo "$status" > "$BUILD_DIR/$target.exitcode"
  return "$status"
}

build_object_target() {
  local target="$1"
  local output="$2"
  local source="$3"
  local flags_name="$4"

  local stdout_log="$BUILD_DIR/$target.stdout.log"
  local stderr_log="$BUILD_DIR/$target.stderr.log"
  : > "$stdout_log"
  : > "$stderr_log"

  local -n flags="$flags_name"
  local status=0
  if ! compile_object "$target" "$source" "$output" "${flags[@]}"; then
    status=1
  fi

  record_source_probe "$target" "$source"
  echo "$status" > "$BUILD_DIR/$target.exitcode"
  return "$status"
}

build_c_object_target() {
  local target="$1"
  local output="$2"
  local source="$3"
  local flags_name="$4"

  local stdout_log="$BUILD_DIR/$target.stdout.log"
  local stderr_log="$BUILD_DIR/$target.stderr.log"
  : > "$stdout_log"
  : > "$stderr_log"

  local -n flags="$flags_name"
  local status=0
  if ! compile_c_object "$target" "$source" "$output" "${flags[@]}"; then
    status=1
  fi

  record_source_probe "$target" "$source"
  echo "$status" > "$BUILD_DIR/$target.exitcode"
  return "$status"
}

run_command_needs_update() {
  local exitfile="$1"
  local stdout_log="$2"
  local stderr_log="$3"
  local cmdfile="$4"
  shift 4

  [[ -f "$exitfile" && -f "$stdout_log" && -f "$stderr_log" ]] || return 0
  command_matches "$cmdfile" "$@" || return 0

  local arg
  for arg in "$@"; do
    if [[ -f "$arg" && "$arg" -nt "$exitfile" ]]; then
      return 0
    fi
  done

  return 1
}

run_logged_command() {
  local label="$1"
  shift

  local exitfile="$BUILD_DIR/$label.run.exitcode"
  local stdout_log="$BUILD_DIR/$label.run.stdout.log"
  local stderr_log="$BUILD_DIR/$label.run.stderr.log"
  local cmdfile="$BUILD_DIR/$label.run.cmd"

  if ! run_command_needs_update "$exitfile" "$stdout_log" "$stderr_log" "$cmdfile" "$@"; then
    return 0
  fi

  set +e
  if command -v timeout >/dev/null 2>&1; then
    timeout "$NATIVE_PROBE_RUN_TIMEOUT_SECONDS" "$@" >"$stdout_log" 2>"$stderr_log"
  else
    "$@" >"$stdout_log" 2>"$stderr_log"
  fi
  local run_rc=$?
  set -e

  if [[ "$run_rc" == "124" ]]; then
    printf 'run timed out after %s seconds\n' "$NATIVE_PROBE_RUN_TIMEOUT_SECONDS" >>"$stderr_log"
  fi

  write_command_file "$cmdfile" "$@"
  echo "$run_rc" > "$exitfile"
}

clear_logged_command() {
  local label="$1"
  rm -f \
    "$BUILD_DIR/$label.run.exitcode" \
    "$BUILD_DIR/$label.run.stdout.log" \
    "$BUILD_DIR/$label.run.stderr.log" \
    "$BUILD_DIR/$label.run.cmd"
}

NO_LINK_FLAGS=()

INI_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/ini/inifile.cc"
  "$WRAP_DIR/linuxcnc_ini_probe.cpp"
)

FIVEAXIS_REMAP_ASSET_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/ini/inifile.cc"
  "$WRAP_DIR/linuxcnc_5axis_remap_asset_probe.cpp"
)

MILLTURN_USER_M_BOUNDARY_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/ini/inifile.cc"
  "$WRAP_DIR/linuxcnc_millturn_user_m_boundary_probe.cpp"
)

TOOL_DB_BOUNDARY_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/ini/inifile.cc"
  "$WRAP_DIR/linuxcnc_tool_db_boundary_probe.cpp"
)

PYTHON_REMAP_BOUNDARY_PROBE_SOURCES=(
  "$WRAP_DIR/linuxcnc_python_remap_boundary_probe.cpp"
)

STATE_PROBE_SOURCES=(
  "$WRAP_DIR/linuxcnc_interp_state_probe.cpp"
)

EMC_STATUS_PROBE_SOURCES=(
  "$WRAP_DIR/linuxcnc_emc_status_runtime.cpp"
  "$WRAP_DIR/linuxcnc_emc_status_probe.cpp"
)

TP_API_PROBE_SOURCES=(
  "$WRAP_DIR/linuxcnc_tp_api_probe.cpp"
)

KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/trivkins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_kinematics_probe.cpp"
)

FIVEAXIS_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/5axiskins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_5axis_kinematics_probe.cpp"
)

XYZAC_TRT_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/trtfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/xyzac-trt-kins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_xyzac_trt_kinematics_probe.cpp"
)

XYZBC_TRT_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/trtfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/xyzbc-trt-kins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_xyzbc_trt_kinematics_probe.cpp"
)

COREXY_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/corexykins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_corexy_kinematics_probe.cpp"
)

ROTATE_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/rotatekins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_rotate_kinematics_probe.cpp"
)

ROSE_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/rosekins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_rose_kinematics_probe.cpp"
)

MAX_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/maxkins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_max_kinematics_probe.cpp"
)

LINEARDELTA_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/lineardeltakins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_lineardelta_kinematics_probe.cpp"
)

ROTARYDELTA_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/rotarydeltakins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_rotarydelta_kinematics_probe.cpp"
)

SCORBOT_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/scorbot-kins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_scorbot_kinematics_probe.cpp"
)

TRIPOD_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/tripodkins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_tripod_kinematics_probe.cpp"
)

SCARA_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/scarakins.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_scara_kinematics_probe.cpp"
)

PUMA_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/pumakins.c"
  "$VENDOR_DIR/src/libnml/posemath/posemath.cc"
  "$VENDOR_DIR/src/libnml/posemath/_posemath.c"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_puma_kinematics_probe.cpp"
)

GENSER_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/genserfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/genserkins.c"
  "$WRAP_DIR/linuxcnc_gomath_cxx.cpp"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_genser_kinematics_probe.cpp"
)

GENHEX_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c"
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c"
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c"
  "$VENDOR_DIR/src/emc/kinematics/genhexkins.c"
  "$VENDOR_DIR/src/libnml/posemath/posemath.cc"
  "$VENDOR_DIR/src/libnml/posemath/_posemath.c"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_genhex_kinematics_probe.cpp"
)

PENTAKINS_KINEMATICS_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/kinematics/pentakins.c"
  "$VENDOR_DIR/src/libnml/posemath/posemath.cc"
  "$VENDOR_DIR/src/libnml/posemath/_posemath.c"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_pentakins_kinematics_probe.cpp"
)

TP_CORE_SOURCES=(
  "$VENDOR_DIR/src/emc/tp/tp.c"
  "$VENDOR_DIR/src/emc/tp/tc.c"
  "$VENDOR_DIR/src/emc/tp/tcq.c"
  "$VENDOR_DIR/src/emc/tp/spherical_arc.c"
  "$VENDOR_DIR/src/emc/tp/blendmath.c"
  "$VENDOR_DIR/src/emc/tp/sp_scurve.c"
  "$VENDOR_DIR/src/emc/tp/ruckig_wrapper.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/block.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/brake.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/calculator.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/cruckig.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/input_parameter.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/output_parameter.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/profile.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/roots.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/trajectory.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_first_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_first_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_second_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_second_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_third_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_third_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_second_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_second_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_third_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_third_step2.c"
  "$VENDOR_DIR/src/emc/nml_intf/emcpose.c"
  "$VENDOR_DIR/src/libnml/posemath/posemath.cc"
  "$VENDOR_DIR/src/libnml/posemath/_posemath.c"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
)

TP_RUNTIME_PROBE_SOURCES=(
  "${TP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_tp_api_probe.cpp"
)

TP_SOURCE_PROBE_NAMES=(
  linuxcnc_tp_tp_source_probe
  linuxcnc_tp_tc_source_probe
  linuxcnc_tp_tcq_source_probe
  linuxcnc_tp_spherical_arc_source_probe
  linuxcnc_tp_blendmath_source_probe
  linuxcnc_tp_sp_scurve_source_probe
  linuxcnc_tp_ruckig_wrapper_source_probe
  linuxcnc_cruckig_block_source_probe
  linuxcnc_cruckig_brake_source_probe
  linuxcnc_cruckig_calculator_source_probe
  linuxcnc_cruckig_cruckig_source_probe
  linuxcnc_cruckig_input_parameter_source_probe
  linuxcnc_cruckig_output_parameter_source_probe
  linuxcnc_cruckig_profile_source_probe
  linuxcnc_cruckig_roots_source_probe
  linuxcnc_cruckig_trajectory_source_probe
  linuxcnc_cruckig_position_first_step1_source_probe
  linuxcnc_cruckig_position_first_step2_source_probe
  linuxcnc_cruckig_position_second_step1_source_probe
  linuxcnc_cruckig_position_second_step2_source_probe
  linuxcnc_cruckig_position_third_step1_source_probe
  linuxcnc_cruckig_position_third_step2_source_probe
  linuxcnc_cruckig_velocity_second_step1_source_probe
  linuxcnc_cruckig_velocity_second_step2_source_probe
  linuxcnc_cruckig_velocity_third_step1_source_probe
  linuxcnc_cruckig_velocity_third_step2_source_probe
  linuxcnc_emcpose_source_probe
  linuxcnc_posemath_source_probe
  linuxcnc_posemath_c_source_probe
  linuxcnc_sincos_source_probe
)

TP_SOURCE_PROBE_SOURCES=(
  "$VENDOR_DIR/src/emc/tp/tp.c"
  "$VENDOR_DIR/src/emc/tp/tc.c"
  "$VENDOR_DIR/src/emc/tp/tcq.c"
  "$VENDOR_DIR/src/emc/tp/spherical_arc.c"
  "$VENDOR_DIR/src/emc/tp/blendmath.c"
  "$VENDOR_DIR/src/emc/tp/sp_scurve.c"
  "$VENDOR_DIR/src/emc/tp/ruckig_wrapper.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/block.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/brake.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/calculator.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/cruckig.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/input_parameter.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/output_parameter.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/profile.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/roots.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/trajectory.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_first_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_first_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_second_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_second_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_third_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_third_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_second_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_second_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_third_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_third_step2.c"
  "$VENDOR_DIR/src/emc/nml_intf/emcpose.c"
  "$VENDOR_DIR/src/libnml/posemath/posemath.cc"
  "$VENDOR_DIR/src/libnml/posemath/_posemath.c"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
)

INTERP_CORE_SOURCES=(
  "$VENDOR_DIR/src/emc/rs274ngc/modal_state.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_array.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_internal.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_read.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_check.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_arc.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_inverse.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_execute.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_convert.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_cycles.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_g7x.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_queue.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_find.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_namedparams.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_write.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_o_word.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/rs274ngc_pre.cc"
  "$VENDOR_DIR/src/emc/tooldata/tooldata_common.cc"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_emc_status_runtime.cpp"
  "$WRAP_DIR/linuxcnc_interp_edge_stubs.cpp"
  "$WRAP_DIR/linuxcnc_machine_config.cpp"
  "$WRAP_DIR/linuxcnc_runtime_state_stubs.cpp"
  "$WRAP_DIR/linuxcnc_tool_adapter.cpp"
  "$WRAP_DIR/linuxcnc_interp_minimal_runtime.cpp"
  "$VENDOR_DIR/src/emc/ini/inifile.cc"
)

NAMEDPARAM_SOURCES=(
  "${INTERP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_namedparam_harness.cpp"
)

MINIMAL_SOURCES=(
  "${INTERP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_interp_minimal_harness.cpp"
)

PARAMETER_FILE_SOURCES=(
  "${INTERP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_parameter_file_harness.cpp"
)

INIT_HARNESS_SOURCES=(
  "${INTERP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_interp_init_harness.cpp"
)

INDEXER_HARNESS_SOURCES=(
  "${INTERP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_indexer_harness.cpp"
)

REMAP_RUNTIME_CORE_SOURCES=(
  "$VENDOR_DIR/src/emc/rs274ngc/modal_state.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_array.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_internal.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_read.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_check.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_arc.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_inverse.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_execute.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_convert.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_cycles.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_g7x.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_queue.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_find.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_namedparams.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_write.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_o_word.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/interp_remap.cc"
  "$VENDOR_DIR/src/emc/rs274ngc/rs274ngc_pre.cc"
  "$VENDOR_DIR/src/emc/tooldata/tooldata_common.cc"
  "$WRAP_DIR/linuxcnc_hal_adapter.cpp"
  "$WRAP_DIR/linuxcnc_emc_status_runtime.cpp"
  "$WRAP_DIR/linuxcnc_interp_python_edge_stubs.cpp"
  "$WRAP_DIR/linuxcnc_machine_config.cpp"
  "$WRAP_DIR/linuxcnc_runtime_state_stubs.cpp"
  "$WRAP_DIR/linuxcnc_tool_adapter.cpp"
  "$WRAP_DIR/linuxcnc_interp_minimal_runtime.cpp"
  "$VENDOR_DIR/src/emc/ini/inifile.cc"
)

REMAP_PARSE_SOURCES=(
  "${REMAP_RUNTIME_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_remap_parse_harness.cpp"
)

REMAP_HAL_SYNC_SOURCES=(
  "${INTERP_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_remap_hal_sync_harness.cpp"
)

FIVEAXIS_REMAP_EXECUTE_SOURCES=(
  "${REMAP_RUNTIME_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_5axis_remap_execute_harness.cpp"
)

DUPLICATE_OWORD_REMAP_SOURCES=(
  "${REMAP_RUNTIME_CORE_SOURCES[@]}"
  "$WRAP_DIR/linuxcnc_duplicate_oword_remap_harness.cpp"
)

if [[ "${NATIVE_PROBE_ONLY:-}" == "linuxcnc_duplicate_oword_remap_harness" ]]; then
  build_binary_target \
    linuxcnc_duplicate_oword_remap_harness \
    "$BUILD_DIR/linuxcnc_duplicate_oword_remap_harness" \
    REMAP_RUNTIME_FLAGS \
    DUPLICATE_OWORD_REMAP_SOURCES \
    MINIMAL_LINK_FLAGS

  if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_duplicate_oword_remap_harness.exitcode")" == "0" ]]; then
    run_logged_command \
      linuxcnc_duplicate_oword_remap_harness \
      "$BUILD_DIR/linuxcnc_duplicate_oword_remap_harness"
  else
    clear_logged_command linuxcnc_duplicate_oword_remap_harness
  fi

  echo "native probe target complete: linuxcnc_duplicate_oword_remap_harness"
  exit 0
fi

build_binary_target \
  linuxcnc_ini_probe \
  "$BUILD_DIR/linuxcnc_ini_probe" \
  COMMON_FLAGS \
  INI_PROBE_SOURCES \
  NO_LINK_FLAGS \
  -lfmt

build_binary_target \
  linuxcnc_5axis_remap_asset_probe \
  "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe" \
  VENDOR_ASSET_FLAGS \
  FIVEAXIS_REMAP_ASSET_PROBE_SOURCES \
  NO_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe" \
    >"$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.run.stderr.log"
  FIVEAXIS_REMAP_ASSET_RUN_RC=$?
  set -e
  echo "$FIVEAXIS_REMAP_ASSET_RUN_RC" > "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_5axis_remap_asset_probe.run.stderr.log"
fi

build_binary_target \
  linuxcnc_millturn_user_m_boundary_probe \
  "$BUILD_DIR/linuxcnc_millturn_user_m_boundary_probe" \
  SOURCE_CONFIG_ASSET_FLAGS \
  MILLTURN_USER_M_BOUNDARY_PROBE_SOURCES \
  NO_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_millturn_user_m_boundary_probe.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_millturn_user_m_boundary_probe \
    "$BUILD_DIR/linuxcnc_millturn_user_m_boundary_probe"
  run_logged_command \
    linuxcnc_millturn_user_m_runtime_probe \
    bash \
    "$MILLTURN_USER_M_RUNTIME_PROBE"
else
  clear_logged_command linuxcnc_millturn_user_m_boundary_probe
  clear_logged_command linuxcnc_millturn_user_m_runtime_probe
fi

build_binary_target \
  linuxcnc_tool_db_boundary_probe \
  "$BUILD_DIR/linuxcnc_tool_db_boundary_probe" \
  SOURCE_CONFIG_ASSET_FLAGS \
  TOOL_DB_BOUNDARY_PROBE_SOURCES \
  NO_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_tool_db_boundary_probe.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_tool_db_boundary_probe \
    "$BUILD_DIR/linuxcnc_tool_db_boundary_probe"
  run_logged_command \
    linuxcnc_tool_db_runtime_probe \
    bash \
    "$TOOL_DB_RUNTIME_PROBE"
else
  clear_logged_command linuxcnc_tool_db_boundary_probe
  clear_logged_command linuxcnc_tool_db_runtime_probe
fi

build_binary_target \
  linuxcnc_python_remap_boundary_probe \
  "$BUILD_DIR/linuxcnc_python_remap_boundary_probe" \
  SOURCE_CONFIG_ASSET_FLAGS \
  PYTHON_REMAP_BOUNDARY_PROBE_SOURCES \
  NO_LINK_FLAGS

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_python_remap_boundary_probe.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_python_remap_boundary_probe \
    "$BUILD_DIR/linuxcnc_python_remap_boundary_probe"
  run_logged_command \
    linuxcnc_python_remap_runtime_probe \
    bash \
    "$PYTHON_REMAP_RUNTIME_PROBE"
else
  clear_logged_command linuxcnc_python_remap_boundary_probe
  clear_logged_command linuxcnc_python_remap_runtime_probe
fi

write_native_source_proof_summary
write_native_runtime_probe_summary

build_object_target \
  linuxcnc_inifile_source_probe \
  "$BUILD_DIR/linuxcnc_inifile_source_probe.o" \
  "$VENDOR_DIR/src/emc/ini/inifile.cc" \
  COMMON_INI_FLAGS

build_binary_target \
  linuxcnc_interp_state_probe \
  "$BUILD_DIR/linuxcnc_interp_state_probe" \
  COMMON_FLAGS \
  STATE_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_emc_status_probe \
  "$BUILD_DIR/linuxcnc_emc_status_probe" \
  COMMON_FLAGS \
  EMC_STATUS_PROBE_SOURCES \
  NO_LINK_FLAGS

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_emc_status_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_emc_status_probe" \
    >"$BUILD_DIR/linuxcnc_emc_status_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_emc_status_probe.run.stderr.log"
  EMC_STATUS_RUN_RC=$?
  set -e
  echo "$EMC_STATUS_RUN_RC" > "$BUILD_DIR/linuxcnc_emc_status_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_emc_status_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_emc_status_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_emc_status_probe.run.stderr.log"
fi

build_binary_target \
  linuxcnc_tp_api_probe \
  "$BUILD_DIR/linuxcnc_tp_api_probe" \
  TP_FLAGS \
  TP_RUNTIME_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_kinematics_probe \
  "$BUILD_DIR/linuxcnc_kinematics_probe" \
  TP_FLAGS \
  KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_5axis_kinematics_probe \
  "$BUILD_DIR/linuxcnc_5axis_kinematics_probe" \
  TP_FLAGS \
  FIVEAXIS_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_xyzac_trt_kinematics_probe \
  "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe" \
  TP_FLAGS \
  XYZAC_TRT_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_xyzbc_trt_kinematics_probe \
  "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe" \
  TP_FLAGS \
  XYZBC_TRT_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_corexy_kinematics_probe \
  "$BUILD_DIR/linuxcnc_corexy_kinematics_probe" \
  TP_FLAGS \
  COREXY_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_rotate_kinematics_probe \
  "$BUILD_DIR/linuxcnc_rotate_kinematics_probe" \
  TP_FLAGS \
  ROTATE_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_rose_kinematics_probe \
  "$BUILD_DIR/linuxcnc_rose_kinematics_probe" \
  TP_FLAGS \
  ROSE_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_max_kinematics_probe \
  "$BUILD_DIR/linuxcnc_max_kinematics_probe" \
  TP_FLAGS \
  MAX_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_lineardelta_kinematics_probe \
  "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe" \
  TP_FLAGS \
  LINEARDELTA_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_rotarydelta_kinematics_probe \
  "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe" \
  TP_FLAGS \
  ROTARYDELTA_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_scorbot_kinematics_probe \
  "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe" \
  TP_FLAGS \
  SCORBOT_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_tripod_kinematics_probe \
  "$BUILD_DIR/linuxcnc_tripod_kinematics_probe" \
  TP_FLAGS \
  TRIPOD_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_scara_kinematics_probe \
  "$BUILD_DIR/linuxcnc_scara_kinematics_probe" \
  TP_FLAGS \
  SCARA_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_puma_kinematics_probe \
  "$BUILD_DIR/linuxcnc_puma_kinematics_probe" \
  TP_FLAGS \
  PUMA_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_genser_kinematics_probe \
  "$BUILD_DIR/linuxcnc_genser_kinematics_probe" \
  TP_FLAGS \
  GENSER_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_genhex_kinematics_probe \
  "$BUILD_DIR/linuxcnc_genhex_kinematics_probe" \
  TP_FLAGS \
  GENHEX_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

build_binary_target \
  linuxcnc_pentakins_kinematics_probe \
  "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe" \
  TP_FLAGS \
  PENTAKINS_KINEMATICS_PROBE_SOURCES \
  NO_LINK_FLAGS

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_kinematics_probe.run.stderr.log"
  KINEMATICS_RUN_RC=$?
  set -e
  echo "$KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_5axis_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_5axis_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.stderr.log"
  FIVEAXIS_KINEMATICS_RUN_RC=$?
  set -e
  echo "$FIVEAXIS_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.stderr.log"
  XYZAC_TRT_KINEMATICS_RUN_RC=$?
  set -e
  echo "$XYZAC_TRT_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.stderr.log"
  XYZBC_TRT_KINEMATICS_RUN_RC=$?
  set -e
  echo "$XYZBC_TRT_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_corexy_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stderr.log"
  COREXY_KINEMATICS_RUN_RC=$?
  set -e
  echo "$COREXY_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_rotate_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stderr.log"
  ROTATE_KINEMATICS_RUN_RC=$?
  set -e
  echo "$ROTATE_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_rose_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_rose_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stderr.log"
  ROSE_KINEMATICS_RUN_RC=$?
  set -e
  echo "$ROSE_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_max_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_max_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stderr.log"
  MAX_KINEMATICS_RUN_RC=$?
  set -e
  echo "$MAX_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.stderr.log"
  LINEARDELTA_KINEMATICS_RUN_RC=$?
  set -e
  echo "$LINEARDELTA_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.stderr.log"
  ROTARYDELTA_KINEMATICS_RUN_RC=$?
  set -e
  echo "$ROTARYDELTA_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.stderr.log"
  SCORBOT_KINEMATICS_RUN_RC=$?
  set -e
  echo "$SCORBOT_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_tripod_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_tripod_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.stderr.log"
  TRIPOD_KINEMATICS_RUN_RC=$?
  set -e
  echo "$TRIPOD_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_scara_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_scara_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.stderr.log"
  SCARA_KINEMATICS_RUN_RC=$?
  set -e
  echo "$SCARA_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_puma_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_puma_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.stderr.log"
  PUMA_KINEMATICS_RUN_RC=$?
  set -e
  echo "$PUMA_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_genser_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_genser_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.stderr.log"
  GENSER_KINEMATICS_RUN_RC=$?
  set -e
  echo "$GENSER_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_genhex_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_genhex_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.stderr.log"
  GENHEX_KINEMATICS_RUN_RC=$?
  set -e
  echo "$GENHEX_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe" \
    >"$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.stderr.log"
  PENTAKINS_KINEMATICS_RUN_RC=$?
  set -e
  echo "$PENTAKINS_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.stderr.log"
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_tp_api_probe.exitcode")" == "0" ]]; then
  set +e
  "$BUILD_DIR/linuxcnc_tp_api_probe" \
    >"$BUILD_DIR/linuxcnc_tp_api_probe.run.stdout.log" \
    2>"$BUILD_DIR/linuxcnc_tp_api_probe.run.stderr.log"
  TP_API_RUN_RC=$?
  set -e
  echo "$TP_API_RUN_RC" > "$BUILD_DIR/linuxcnc_tp_api_probe.run.exitcode"
else
  rm -f \
    "$BUILD_DIR/linuxcnc_tp_api_probe.run.exitcode" \
    "$BUILD_DIR/linuxcnc_tp_api_probe.run.stdout.log" \
    "$BUILD_DIR/linuxcnc_tp_api_probe.run.stderr.log"
fi

for index in "${!TP_SOURCE_PROBE_NAMES[@]}"; do
  build_object_target \
    "${TP_SOURCE_PROBE_NAMES[$index]}" \
    "$BUILD_DIR/${TP_SOURCE_PROBE_NAMES[$index]}.o" \
    "${TP_SOURCE_PROBE_SOURCES[$index]}" \
    TP_FLAGS
done

build_binary_target \
  linuxcnc_namedparam_harness \
  "$BUILD_DIR/linuxcnc_namedparam_harness" \
  MINIMAL_FLAGS \
  NAMEDPARAM_SOURCES \
  MINIMAL_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_namedparam_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_namedparam_harness \
    "$BUILD_DIR/linuxcnc_namedparam_harness" "$NAMEDPARAM_INI_FIXTURE"
else
  clear_logged_command linuxcnc_namedparam_harness
fi

build_binary_target \
  linuxcnc_interp_minimal_harness \
  "$BUILD_DIR/linuxcnc_interp_minimal_harness" \
  MINIMAL_FLAGS \
  MINIMAL_SOURCES \
  MINIMAL_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_interp_minimal_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_interp_minimal_harness \
    "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$MINIMAL_GCODE_FIXTURE"
else
  clear_logged_command linuxcnc_interp_minimal_harness
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_interp_minimal_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_interp_minimal_harness.do_while_break \
    "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$DO_WHILE_BREAK_FIXTURE"
else
  clear_logged_command linuxcnc_interp_minimal_harness.do_while_break
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_interp_minimal_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_interp_minimal_harness.oword_bug315 \
    "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$OWORD_BUG315_FIXTURE"
else
  clear_logged_command linuxcnc_interp_minimal_harness.oword_bug315
fi

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_interp_minimal_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_interp_minimal_harness.oword_bug315_p2 \
    "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$OWORD_BUG315_P2_FIXTURE"
else
  clear_logged_command linuxcnc_interp_minimal_harness.oword_bug315_p2
fi

run_interp_minimal_fixture() {
  local label="$1"
  local fixture="$2"
  local ini="${3:-}"
  local mode="${4:-}"

  if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_interp_minimal_harness.exitcode")" == "0" ]]; then
    if [[ "$mode" == "continue_on_error" ]]; then
      run_logged_command \
        "linuxcnc_interp_minimal_harness.$label" \
        "$BUILD_DIR/linuxcnc_interp_minimal_harness" --continue-on-error "$fixture" "$ini"
    else
      run_logged_command \
        "linuxcnc_interp_minimal_harness.$label" \
        "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$fixture" "$ini"
    fi
  else
    clear_logged_command "linuxcnc_interp_minimal_harness.$label"
  fi
}

run_interp_minimal_fixture interp_exists "$EXISTS_FIXTURE"
run_interp_minimal_fixture return_value "$RETURN_VALUE_FIXTURE"
run_interp_minimal_fixture subs_follow_main "$SUBS_FOLLOW_MAIN_FIXTURE"
run_interp_minimal_fixture fractional_linenumbers "$FRACTIONAL_LINENUMBERS_FIXTURE"
run_interp_minimal_fixture cam_nisley_bare "$CAM_NISLEY_FIXTURE"
write_tool_table_ini "$CAM_NISLEY_INI" "$CAM_NISLEY_TOOL_TABLE"
run_interp_minimal_fixture cam_nisley "$CAM_NISLEY_FIXTURE" "$CAM_NISLEY_INI"
run_interp_minimal_fixture crazy_paths "$CRAZY_PATHS_FIXTURE"
run_interp_minimal_fixture namedparam_bug424 "$NAMEDPARAM_BUG424_FIXTURE"
run_interp_minimal_fixture flowsnake "$FLOWSNAKE_FIXTURE"
run_interp_minimal_fixture inside_corners "$INSIDE_CORNERS_FIXTURE"
run_interp_minimal_fixture inverse_time_with_comp "$INVERSE_TIME_WITH_COMP_FIXTURE"
write_ccomp_ini "$CCOMP_LATHE_COMP_INI" "$CCOMP_LATHE_COMP_TOOL_TABLE"
write_ccomp_ini "$CCOMP_MILL_G90G91G92_INI" "$CCOMP_MILL_G90G91G92_TOOL_TABLE"
write_ccomp_ini "$CCOMP_MILL_LINE_ARC_ENTRY_INI" "$CCOMP_MILL_LINE_ARC_ENTRY_TOOL_TABLE"
write_ccomp_ini "$CCOMP_MILL_ZCHANGES_INI" "$CCOMP_MILL_ZCHANGES_TOOL_TABLE"
run_interp_minimal_fixture ccomp_lathe_comp "$CCOMP_LATHE_COMP_FIXTURE" "$CCOMP_LATHE_COMP_INI"
run_interp_minimal_fixture ccomp_mill_g90g91g92 "$CCOMP_MILL_G90G91G92_FIXTURE" "$CCOMP_MILL_G90G91G92_INI"
run_interp_minimal_fixture ccomp_mill_line_arc_entry "$CCOMP_MILL_LINE_ARC_ENTRY_FIXTURE" "$CCOMP_MILL_LINE_ARC_ENTRY_INI"
run_interp_minimal_fixture ccomp_mill_zchanges "$CCOMP_MILL_ZCHANGES_FIXTURE" "$CCOMP_MILL_ZCHANGES_INI"
run_interp_minimal_fixture bad_a_in_canned_cycle "$BAD_A_IN_CANNED_CYCLE_FIXTURE"
run_interp_minimal_fixture bad_a_in_canned_cycle2 "$BAD_A_IN_CANNED_CYCLE2_FIXTURE"
run_interp_minimal_fixture bad_arc_big_imperial_center_format "$BAD_ARC_BIG_IMPERIAL_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture bad_arc_big_metric_center_format "$BAD_ARC_BIG_METRIC_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture bad_arc_medium_imperial_center_format "$BAD_ARC_MEDIUM_IMPERIAL_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture bad_arc_medium_metric_center_format "$BAD_ARC_MEDIUM_METRIC_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture bad_arc_small_imperial_center_format "$BAD_ARC_SMALL_IMPERIAL_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture bad_arc_small_metric_center_format "$BAD_ARC_SMALL_METRIC_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture bad_ccomp_arcexit "$BAD_CCOMP_ARCEXIT_FIXTURE"
run_interp_minimal_fixture bad_ccomp_gouging "$BAD_CCOMP_GOUGING_FIXTURE"
run_interp_minimal_fixture bad_exists_1 "$BAD_EXISTS_1_FIXTURE"
run_interp_minimal_fixture bad_exists_2 "$BAD_EXISTS_2_FIXTURE"
run_interp_minimal_fixture bad_exists_3 "$BAD_EXISTS_3_FIXTURE"
run_interp_minimal_fixture bad_exists_4 "$BAD_EXISTS_4_FIXTURE"
run_interp_minimal_fixture bad_exists_5 "$BAD_EXISTS_5_FIXTURE"
run_interp_minimal_fixture bad_exists_6 "$BAD_EXISTS_6_FIXTURE"
run_interp_minimal_fixture bad_exists_7 "$BAD_EXISTS_7_FIXTURE"
run_interp_minimal_fixture bad_nested "$BAD_NESTED_FIXTURE"
run_interp_minimal_fixture bad_no_feed_rate "$BAD_NO_FEED_RATE_FIXTURE"
run_interp_minimal_fixture bad_no_ijr "$BAD_NO_IJR_FIXTURE"
run_interp_minimal_fixture bad_probe_no_axes "$BAD_PROBE_NO_AXES_FIXTURE"
run_interp_minimal_fixture g33_1 "$G33_1_FIXTURE"
run_interp_minimal_fixture g6164 "$G6164_FIXTURE"
run_interp_minimal_fixture g72_facing "$G72_FACING_FIXTURE"
run_interp_minimal_fixture g72_missing_iteration "$G72_MISSING_ITERATION_FIXTURE"
run_interp_minimal_fixture g71_endless_loop "$G71_ENDLESS_LOOP_FIXTURE"
run_interp_minimal_fixture g71_endless_loop2 "$G71_ENDLESS_LOOP2_FIXTURE"
run_interp_minimal_fixture g71_endless_loop_2 "$G71_ENDLESS_LOOP_2_FIXTURE"
run_interp_minimal_fixture g71_with_g70 "$G71_WITH_G70_FIXTURE"
write_tool_table_ini "$G76_INI" "$G76_TOOL_TABLE"
run_interp_minimal_fixture g76 "$G76_FIXTURE" "$G76_INI"
run_interp_minimal_fixture good_arc_big_imperial_center_format "$GOOD_ARC_BIG_IMPERIAL_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture good_arc_big_metric_center_format "$GOOD_ARC_BIG_METRIC_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture good_arc_medium_imperial_center_format "$GOOD_ARC_MEDIUM_IMPERIAL_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture good_arc_medium_metric_center_format "$GOOD_ARC_MEDIUM_METRIC_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture good_arc_small_imperial_center_format "$GOOD_ARC_SMALL_IMPERIAL_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture good_arc_small_metric_center_format "$GOOD_ARC_SMALL_METRIC_CENTER_FORMAT_FIXTURE"
run_interp_minimal_fixture rotation_abs_pts "$ROTATION_ABS_PTS_FIXTURE"
run_interp_minimal_fixture rotation_g28 "$ROTATION_G28_FIXTURE"
run_interp_minimal_fixture rotation_g53 "$ROTATION_G53_FIXTURE"
run_interp_minimal_fixture iniparam "$INIPARAM_FIXTURE" "$INIPARAM_INI" continue_on_error
run_interp_minimal_fixture iniparam_failassign "$INIPARAM_FAILASSIGN_FIXTURE" "$INIPARAM_FAILASSIGN_INI"
run_interp_minimal_fixture sub_call_from_sub "$SUB_CALL_FROM_SUB_FIXTURE" "$SUB_CALL_FROM_SUB_INI"
run_interp_minimal_fixture sequence_number "$SEQUENCE_NUMBER_FIXTURE" "$SEQUENCE_NUMBER_INI"
run_interp_minimal_fixture nested_sub_error "$NESTED_SUB_ERROR_FIXTURE" "$NESTED_SUB_ERROR_INI"
run_interp_minimal_fixture nested_sub_in_file_error "$NESTED_SUB_IN_FILE_ERROR_FIXTURE" "$NESTED_SUB_IN_FILE_ERROR_INI"
run_interp_minimal_fixture oword_unwind "$OWORD_UNWIND_FIXTURE" "$OWORD_UNWIND_INI" continue_on_error
run_interp_minimal_fixture abort_hot_comment "$ABORT_HOT_COMMENT_FIXTURE" "$ABORT_HOT_COMMENT_INI" continue_on_error
run_interp_minimal_fixture m19 "$M19_FIXTURE" "$M19_INI"
run_interp_minimal_fixture magic_comments_param_format "$MAGIC_COMMENTS_PARAM_FORMAT_FIXTURE"
run_interp_minimal_fixture m98m99_01_basics "$M98M99_01_BASICS_FIXTURE"
run_interp_minimal_fixture m98m99_02_variables "$M98M99_02_VARIABLES_FIXTURE"
run_interp_minimal_fixture m98m99_03_error_m98_no_p_word "$M98M99_03_ERROR_M98_NO_P_WORD_FIXTURE"
run_interp_minimal_fixture m98m99_04_m98_but_no_sub "$M98M99_04_M98_BUT_NO_SUB_FIXTURE"
run_interp_minimal_fixture m98m99_05_m98_loops "$M98M99_05_M98_LOOPS_FIXTURE"
run_interp_minimal_fixture m98m99_06_called_with_o_call "$M98M99_06_CALLED_WITH_O_CALL_FIXTURE"
run_interp_minimal_fixture m98m99_06_ended_with_o_endsub "$M98M99_06_ENDED_WITH_O_ENDSUB_FIXTURE"
run_interp_minimal_fixture m98m99_06_sub_called_with_m98 "$M98M99_06_SUB_CALLED_WITH_M98_FIXTURE"
run_interp_minimal_fixture m98m99_06_sub_ended_with_m99 "$M98M99_06_SUB_ENDED_WITH_M99_FIXTURE"
run_interp_minimal_fixture m98m99_07_nested_subs "$M98M99_07_NESTED_SUBS_FIXTURE"
run_interp_minimal_fixture m98m99_08_sub_follows_main "$M98M99_08_SUB_FOLLOWS_MAIN_FIXTURE"
run_interp_minimal_fixture m98m99_09_fanuc_ini "$M98M99_09_FANUC_FIXTURE" "$M98M99_09_FANUC_INI"
run_interp_minimal_fixture m98m99_09_rs274ngc_ini "$M98M99_09_RS274NGC_FIXTURE" "$M98M99_09_FANUC_INI"
run_interp_minimal_fixture m98m99_09_fanuc_no_fanuc "$M98M99_09_FANUC_FIXTURE" "$M98M99_09_NO_FANUC_INI"
run_interp_minimal_fixture m98m99_09_rs274ngc_no_fanuc "$M98M99_09_RS274NGC_FIXTURE" "$M98M99_09_NO_FANUC_INI"
run_interp_minimal_fixture m98m99_09_fanuc_default "$M98M99_09_FANUC_FIXTURE"
run_interp_minimal_fixture m98m99_09_rs274ngc_default "$M98M99_09_RS274NGC_FIXTURE"
run_interp_minimal_fixture m98m99_10_m98_p001 "$M98M99_10_M98_P001_FIXTURE"
run_interp_minimal_fixture m98m99_11_legal_m2 "$M98M99_11_LEGAL_M2_FIXTURE"
run_interp_minimal_fixture m98m99_11_legal_m02 "$M98M99_11_LEGAL_M02_FIXTURE"
run_interp_minimal_fixture m98m99_11_legal_m30 "$M98M99_11_LEGAL_M30_FIXTURE"
run_interp_minimal_fixture m98m99_11_legal_percent "$M98M99_11_LEGAL_PERCENT_FIXTURE"
run_interp_minimal_fixture m98m99_11_illegal_eof "$M98M99_11_ILLEGAL_EOF_FIXTURE"
run_interp_minimal_fixture m98m99_11_illegal_no_m30 "$M98M99_11_ILLEGAL_NO_M30_FIXTURE"
run_interp_minimal_fixture m98m99_11_illegal_sub_after_percent "$M98M99_11_ILLEGAL_SUB_AFTER_PERCENT_FIXTURE"
run_interp_minimal_fixture m98m99_13_named_program_named "$M98M99_13_NAMED_PROGRAM_NAMED_FIXTURE"
run_interp_minimal_fixture m98m99_13_named_program_numbered "$M98M99_13_NAMED_PROGRAM_NUMBERED_FIXTURE"
run_interp_minimal_fixture m98m99_14_o_expression_call "$M98M99_14_O_EXPRESSION_CALL_FIXTURE"
write_tool_table_ini "$G10_L1_L10_INI" "$G10_L1_L10_TOOL_TABLE"
write_tool_table_ini "$G10_L11_INI" "$G10_L11_TOOL_TABLE"
write_tool_table_ini "$G10_WITH_G92_INI" "$G10_WITH_G92_TOOL_TABLE"
run_interp_minimal_fixture g10_l1_l10 "$G10_L1_L10_FIXTURE" "$G10_L1_L10_INI"
run_interp_minimal_fixture g10_l11 "$G10_L11_FIXTURE" "$G10_L11_INI"
run_interp_minimal_fixture g10_l2_while_active "$G10_L2_WHILE_ACTIVE_FIXTURE"
run_interp_minimal_fixture g10_l20_while_active "$G10_L20_WHILE_ACTIVE_FIXTURE"
run_interp_minimal_fixture g10_with_g92 "$G10_WITH_G92_FIXTURE" "$G10_WITH_G92_INI"
run_interp_minimal_fixture g52_g92_interaction "$G52_G92_INTERACTION_FIXTURE"
write_g92_persistence_files
run_interp_minimal_fixture g92_persistence_enabled "$G92_PERSISTENCE_FIXTURE" "$G92_PERSISTENCE_INI"
run_interp_minimal_fixture g92_persistence_disabled "$G92_PERSISTENCE_FIXTURE" "$G92_PERSISTENCE_DISABLED_INI"
run_interp_minimal_fixture sim_axis_foam "$SIM_AXIS_FOAM_FIXTURE" "$SIM_AXIS_FOAM_INI" continue_on_error
run_interp_minimal_fixture sim_bridgemill "$SIM_BRIDGEMILL_FIXTURE" "$SIM_BRIDGEMILL_INI" continue_on_error
run_interp_minimal_fixture sim_geometry_xyzc "$SIM_GEOMETRY_XYZC_FIXTURE" "$SIM_GEOMETRY_XYZC_INI" continue_on_error
run_interp_minimal_fixture sim_external_offsets_dyn "$SIM_EXTERNAL_OFFSETS_DYN_FIXTURE" "$SIM_EXTERNAL_OFFSETS_DYN_INI" continue_on_error

build_binary_target \
  linuxcnc_parameter_file_harness \
  "$BUILD_DIR/linuxcnc_parameter_file_harness" \
  MINIMAL_FLAGS \
  PARAMETER_FILE_SOURCES \
  MINIMAL_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_parameter_file_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_parameter_file_harness \
    "$BUILD_DIR/linuxcnc_parameter_file_harness"
else
  clear_logged_command linuxcnc_parameter_file_harness
fi

build_binary_target \
  linuxcnc_interp_init_harness \
  "$BUILD_DIR/linuxcnc_interp_init_harness" \
  MINIMAL_FLAGS \
  INIT_HARNESS_SOURCES \
  MINIMAL_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_interp_init_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_interp_init_harness \
    "$BUILD_DIR/linuxcnc_interp_init_harness"
else
  clear_logged_command linuxcnc_interp_init_harness
fi

build_binary_target \
  linuxcnc_remap_parse_harness \
  "$BUILD_DIR/linuxcnc_remap_parse_harness" \
  REMAP_RUNTIME_FLAGS \
  REMAP_PARSE_SOURCES \
  MINIMAL_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_remap_parse_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_remap_parse_harness \
    "$BUILD_DIR/linuxcnc_remap_parse_harness"
else
  clear_logged_command linuxcnc_remap_parse_harness
fi

build_binary_target \
  linuxcnc_remap_hal_sync_harness \
  "$BUILD_DIR/linuxcnc_remap_hal_sync_harness" \
  REMAP_RUNTIME_FLAGS \
  REMAP_HAL_SYNC_SOURCES \
  MINIMAL_LINK_FLAGS

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_remap_hal_sync_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_remap_hal_sync_harness \
    "$BUILD_DIR/linuxcnc_remap_hal_sync_harness"
else
  clear_logged_command linuxcnc_remap_hal_sync_harness
fi

build_binary_target \
  linuxcnc_5axis_remap_execute_harness \
  "$BUILD_DIR/linuxcnc_5axis_remap_execute_harness" \
  REMAP_RUNTIME_FLAGS \
  FIVEAXIS_REMAP_EXECUTE_SOURCES \
  MINIMAL_LINK_FLAGS

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_5axis_remap_execute_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_5axis_remap_execute_harness \
    "$BUILD_DIR/linuxcnc_5axis_remap_execute_harness"
else
  clear_logged_command linuxcnc_5axis_remap_execute_harness
fi

build_binary_target \
  linuxcnc_duplicate_oword_remap_harness \
  "$BUILD_DIR/linuxcnc_duplicate_oword_remap_harness" \
  REMAP_RUNTIME_FLAGS \
  DUPLICATE_OWORD_REMAP_SOURCES \
  MINIMAL_LINK_FLAGS

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_duplicate_oword_remap_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_duplicate_oword_remap_harness \
    "$BUILD_DIR/linuxcnc_duplicate_oword_remap_harness"
else
  clear_logged_command linuxcnc_duplicate_oword_remap_harness
fi

build_binary_target \
  linuxcnc_indexer_harness \
  "$BUILD_DIR/linuxcnc_indexer_harness" \
  MINIMAL_FLAGS \
  INDEXER_HARNESS_SOURCES \
  MINIMAL_LINK_FLAGS \
  -lfmt

if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_indexer_harness.exitcode")" == "0" ]]; then
  run_logged_command \
    linuxcnc_indexer_harness \
    "$BUILD_DIR/linuxcnc_indexer_harness"
else
  clear_logged_command linuxcnc_indexer_harness
fi

build_object_target \
  linuxcnc_rs274_compile_probe \
  "$BUILD_DIR/linuxcnc_rs274_compile_probe.o" \
  "$WRAP_DIR/linuxcnc_rs274_compile_probe.cpp" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_kins_util_source_probe \
  "$BUILD_DIR/linuxcnc_kins_util_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/kins_util.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_cubic_source_probe \
  "$BUILD_DIR/linuxcnc_cubic_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/cubic.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_trivkins_source_probe \
  "$BUILD_DIR/linuxcnc_trivkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/trivkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_switchkins_source_probe \
  "$BUILD_DIR/linuxcnc_switchkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/switchkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_userkfuncs_source_probe \
  "$BUILD_DIR/linuxcnc_userkfuncs_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/userkfuncs.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_5axiskins_source_probe \
  "$BUILD_DIR/linuxcnc_5axiskins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/5axiskins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_trtfuncs_source_probe \
  "$BUILD_DIR/linuxcnc_trtfuncs_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/trtfuncs.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_xyzac_trt_kins_source_probe \
  "$BUILD_DIR/linuxcnc_xyzac_trt_kins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/xyzac-trt-kins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_xyzbc_trt_kins_source_probe \
  "$BUILD_DIR/linuxcnc_xyzbc_trt_kins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/xyzbc-trt-kins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_corexykins_source_probe \
  "$BUILD_DIR/linuxcnc_corexykins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/corexykins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_rotatekins_source_probe \
  "$BUILD_DIR/linuxcnc_rotatekins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/rotatekins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_rosekins_source_probe \
  "$BUILD_DIR/linuxcnc_rosekins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/rosekins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_maxkins_source_probe \
  "$BUILD_DIR/linuxcnc_maxkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/maxkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_lineardeltakins_source_probe \
  "$BUILD_DIR/linuxcnc_lineardeltakins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/lineardeltakins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_rotarydeltakins_source_probe \
  "$BUILD_DIR/linuxcnc_rotarydeltakins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/rotarydeltakins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_scorbot_kins_source_probe \
  "$BUILD_DIR/linuxcnc_scorbot_kins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/scorbot-kins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_tripodkins_source_probe \
  "$BUILD_DIR/linuxcnc_tripodkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/tripodkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_scarakins_source_probe \
  "$BUILD_DIR/linuxcnc_scarakins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/scarakins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_pumakins_source_probe \
  "$BUILD_DIR/linuxcnc_pumakins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/pumakins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_genhexkins_source_probe \
  "$BUILD_DIR/linuxcnc_genhexkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/genhexkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_genserfuncs_source_probe \
  "$BUILD_DIR/linuxcnc_genserfuncs_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/genserfuncs.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_genserkins_source_probe \
  "$BUILD_DIR/linuxcnc_genserkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/genserkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_ugenserkins_source_probe \
  "$BUILD_DIR/linuxcnc_ugenserkins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/ugenserkins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_pentakins_source_probe \
  "$BUILD_DIR/linuxcnc_pentakins_source_probe.o" \
  "$VENDOR_DIR/src/emc/kinematics/pentakins.c" \
  TP_FLAGS

build_object_target \
  linuxcnc_interp_convert_source_probe \
  "$BUILD_DIR/linuxcnc_interp_convert_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_convert.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_read_source_probe \
  "$BUILD_DIR/linuxcnc_interp_read_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_read.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_check_source_probe \
  "$BUILD_DIR/linuxcnc_interp_check_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_check.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_execute_source_probe \
  "$BUILD_DIR/linuxcnc_interp_execute_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_execute.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_modal_state_source_probe \
  "$BUILD_DIR/linuxcnc_modal_state_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/modal_state.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_array_source_probe \
  "$BUILD_DIR/linuxcnc_interp_array_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_array.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_internal_source_probe \
  "$BUILD_DIR/linuxcnc_interp_internal_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_internal.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_arc_source_probe \
  "$BUILD_DIR/linuxcnc_interp_arc_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_arc.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_inverse_source_probe \
  "$BUILD_DIR/linuxcnc_interp_inverse_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_inverse.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_cycles_source_probe \
  "$BUILD_DIR/linuxcnc_interp_cycles_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_cycles.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_g7x_source_probe \
  "$BUILD_DIR/linuxcnc_interp_g7x_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_g7x.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_queue_source_probe \
  "$BUILD_DIR/linuxcnc_interp_queue_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_queue.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_find_source_probe \
  "$BUILD_DIR/linuxcnc_interp_find_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_find.cc" \
  COMMON_FLAGS

build_object_target \
  linuxcnc_interp_namedparams_source_probe \
  "$BUILD_DIR/linuxcnc_interp_namedparams_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_namedparams.cc" \
  COMMON_INI_FLAGS

build_object_target \
  linuxcnc_interp_write_source_probe \
  "$BUILD_DIR/linuxcnc_interp_write_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_write.cc" \
  COMMON_INI_FLAGS

build_object_target \
  linuxcnc_interp_o_word_source_probe \
  "$BUILD_DIR/linuxcnc_interp_o_word_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_o_word.cc" \
  COMMON_INI_FLAGS

build_object_target \
  linuxcnc_interp_remap_source_probe \
  "$BUILD_DIR/linuxcnc_interp_remap_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_remap.cc" \
  REMAP_SOURCE_FLAGS

build_object_target \
  linuxcnc_rs274ngc_pre_source_probe \
  "$BUILD_DIR/linuxcnc_rs274ngc_pre_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/rs274ngc_pre.cc" \
  MINIMAL_FLAGS

build_object_target \
  linuxcnc_interp_base_source_probe \
  "$BUILD_DIR/linuxcnc_interp_base_source_probe.o" \
  "$VENDOR_DIR/src/emc/rs274ngc/interp_base.cc" \
  INTERP_BASE_FLAGS

build_c_object_target \
  linuxcnc_gomath_source_probe \
  "$BUILD_DIR/linuxcnc_gomath_source_probe.o" \
  "$VENDOR_DIR/src/libnml/posemath/gomath.c" \
  C_FLAGS

build_object_target \
  linuxcnc_tooldata_common_source_probe \
  "$BUILD_DIR/linuxcnc_tooldata_common_source_probe.o" \
  "$VENDOR_DIR/src/emc/tooldata/tooldata_common.cc" \
  MINIMAL_FLAGS

write_native_cache_stamp "$NATIVE_INPUT_FINGERPRINT"
echo "native probes complete"
