Files
Odin/tests/abi/run.sh
2026-08-13 22:11:53 -07:00

54 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -eu
# The ABI comparator.
#
# Every check is "Odin agrees with the platform C compiler"
#
# ./run.sh
# ./run.sh linux_riscv64 riscv64-linux-gnu \
# "-extra-linker-flags:-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
#
# For a target with no cross libc -- i386, arm32 -- see `cross.sh`, which builds
# the same corpus freestanding.
TARGET=${1:-}
TRIPLE=${2:-}
if [ $# -gt 2 ]; then shift 2; else shift $#; fi # anything else goes to `odin test`
here=$(cd "$(dirname "$0")" && pwd)
: "${ODIN:=$here/../../odin}"
: "${CLANG:=clang}"
# The C side's optimisation level. An ABI is a link-time contract, so the two
# sides are built independently and either may be optimised: `ABI_CFLAGS=-O2`.
: "${ABI_CFLAGS:=}"
COMMON="-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused-defineables"
CC_TARGET=""; [ -n "$TRIPLE" ] && CC_TARGET="--target=$TRIPLE"
ODIN_TARGET=""; [ -n "$TARGET" ] && ODIN_TARGET="-target:$TARGET"
# Cleaned BEFORE, not after: the generated corpus is left in place so it can be
# read after a failure. CI throws the tree away anyway.
rm -rf "$here/build"
mkdir -p "$here/build"
pushd "$here/build" > /dev/null
set -x
$ODIN run ../gen.odin -file -- .
# Ask the C compiler which tiers it has, by preprocessing the generated `build-cross/tiers.c`.
# The Odin side must use the same tiers or it references symbols C never emitted.
have() { $CLANG $CC_TARGET -E tiers.c 2>/dev/null | grep -q "ABI_YES_$1" && echo true || echo false; }
TIERS="-define:ABI_TIER_GNU=$(have GNU) -define:ABI_TIER_F16=$(have F16) -define:ABI_TIER_I128=$(have I128)"
# `-w` because the corpus deliberately uses zero-length arrays and empty
# structs; both are the extensions under test.
$CLANG $CC_TARGET $ABI_CFLAGS -c abi_corpus.c -o abi_corpus_c.o -w
$ODIN test abi_corpus.odin $COMMON $ODIN_TARGET $TIERS "$@"
set +x
popd > /dev/null