|
| 1 | +#!/usr/bin/env bash |
| 2 | +# check_freestanding.sh |
| 3 | +# |
| 4 | +# Compiles .github/freestanding/smoketest.cpp in both configurations this fork |
| 5 | +# has to support, and fails if the compiler says anything at all. |
| 6 | +# |
| 7 | +# Why "anything at all" rather than just a non-zero exit: the defects this check |
| 8 | +# exists to catch are not errors. When the freestanding guards were added, |
| 9 | +# GeneralBlockPanelKernel.h's four #undef PACKET_DECL_COND* lines ended up inside |
| 10 | +# an #ifndef EIGEN_FREESTANDING block, so in freestanding builds the macros |
| 11 | +# leaked out of Eigen/Core and one of them was redefined in |
| 12 | +# GeneralMatrixVector.h. Every downstream translation unit warned; nothing |
| 13 | +# failed. Same for the unconditional #pragma message in all_freestanding.hpp. |
| 14 | +# Both are invisible to a check that only looks at the exit status. |
| 15 | +# |
| 16 | +# Both configurations are checked because the two can break independently: the |
| 17 | +# macro leak appeared only with EIGEN_FREESTANDING defined, and a careless fix |
| 18 | +# could break the hosted path instead. |
| 19 | +# |
| 20 | +# Usage: check_freestanding.sh |
| 21 | +# Environment: |
| 22 | +# EIGEN3_DIR Root of the Eigen checkout (the directory containing 'Eigen/'). |
| 23 | +# Defaults to the repository root, so it normally needs no setting. |
| 24 | +# CXX Compiler to use. Defaults to g++-13, the version the downstream |
| 25 | +# flight software builds with. |
| 26 | + |
| 27 | +set -euo pipefail |
| 28 | + |
| 29 | +CXX="${CXX:-g++-13}" |
| 30 | + |
| 31 | +if ! REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"; then |
| 32 | + REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" |
| 33 | +fi |
| 34 | +EIGEN3_DIR="${EIGEN3_DIR:-$REPO_ROOT}" |
| 35 | + |
| 36 | +if [[ ! -d "${EIGEN3_DIR}/Eigen" ]]; then |
| 37 | + echo "Eigen not found under ${EIGEN3_DIR}" >&2 |
| 38 | + exit 2 |
| 39 | +fi |
| 40 | +if ! command -v "${CXX}" >/dev/null 2>&1; then |
| 41 | + echo "Compiler '${CXX}' not found; set CXX to an available compiler." >&2 |
| 42 | + exit 2 |
| 43 | +fi |
| 44 | + |
| 45 | +TU="${REPO_ROOT}/.github/freestanding/smoketest.cpp" |
| 46 | +if [[ ! -f "$TU" ]]; then |
| 47 | + echo "Translation unit not found: $TU" >&2 |
| 48 | + exit 2 |
| 49 | +fi |
| 50 | + |
| 51 | +FORCE_INCLUDE="${EIGEN3_DIR}/Eigen/src/Freestanding/all_freestanding.hpp" |
| 52 | +# -Wundef matters specifically: Eigen's own test suite compiles with it, and the |
| 53 | +# freestanding guards are the kind of thing that gets written as `!EIGEN_FREESTANDING` |
| 54 | +# instead of `!defined(EIGEN_FREESTANDING)`, which silently evaluates to 0 in every |
| 55 | +# hosted translation unit. Not -Wall/-Wextra yet: the freestanding stubs in |
| 56 | +# Memory.h have pre-existing unused-parameter warnings that need fixing first. |
| 57 | +COMMON=(-std=gnu++23 -fsyntax-only -Wundef -I"${EIGEN3_DIR}") |
| 58 | + |
| 59 | +FAILURES=0 |
| 60 | + |
| 61 | +# $1 = human-readable configuration name, remaining args = extra compiler flags |
| 62 | +check_config() { |
| 63 | + local name="$1" |
| 64 | + shift |
| 65 | + |
| 66 | + local output |
| 67 | + if ! output="$("${CXX}" "${COMMON[@]}" "$@" "$TU" 2>&1)" || [[ -n "$output" ]]; then |
| 68 | + echo "::error::${name} configuration is not clean" |
| 69 | + echo "$output" | sed 's/^/ /' |
| 70 | + FAILURES=$((FAILURES + 1)) |
| 71 | + else |
| 72 | + echo " ${name}: clean" |
| 73 | + fi |
| 74 | +} |
| 75 | + |
| 76 | +echo "Checking ${TU#"$REPO_ROOT"/} with ${CXX}" |
| 77 | +check_config "freestanding" -DEIGEN_FREESTANDING=1 -include "${FORCE_INCLUDE}" |
| 78 | +check_config "hosted" |
| 79 | + |
| 80 | +# Approximates a non-x86 target on an x86 runner. EIGEN_HAS_CXX11_MATH is 1 on |
| 81 | +# x86 (Macros.h requires EIGEN_ARCH_i386_OR_x86_64), which short-circuits |
| 82 | +# MathFunctions.h:503 and hides anything the branch below it depends on. Forcing |
| 83 | +# it to 0 exercises that path without a cross toolchain -- it is how the |
| 84 | +# EIGEN_HAS_C99_MATH block was found to be trapped inside a freestanding guard. |
| 85 | +check_config "freestanding, non-x86 math path" \ |
| 86 | + -DEIGEN_FREESTANDING=1 -DEIGEN_HAS_CXX11_MATH=0 -include "${FORCE_INCLUDE}" |
| 87 | + |
| 88 | +if [[ $FAILURES -gt 0 ]]; then |
| 89 | + echo "" |
| 90 | + echo "${FAILURES} configuration(s) produced compiler output." |
| 91 | + exit 1 |
| 92 | +fi |
| 93 | + |
| 94 | +echo "All configurations compile silently." |
0 commit comments