Files
gen1recomp/scripts/luajit/verify_luajit.sh
T
Shane McGovern ca90a89d68 Ship pinned modern LuaJIT in the aarch64 Linux builds
The linux-arm64 AppImage, the SBC PortMaster zip and the RG34XXSP zip
shipped LuaJIT 2.1.0-beta3 (2017): Debian bullseye's libluajit-5.1-dev for
the AppImage, PortMaster's love_11.5 runtime library for the zips. With
the JIT enabled, beta3 segfaulted 3/3 runs on a TrimUI Brick; LuaJIT v2.1
commit c6ffc141 ran a 26-minute JIT-on soak without a crash.

- Build LuaJIT c6ffc141 from a sha256-pinned tarball in a digest-pinned
  debian:bullseye (glibc 2.31) with the same apt sources as the AppImage
  builder; compile with PREFIX=/usr so no build path is baked into
  package.path, stage-install, and verify before use.
- AppImage: compile it inside the builder instead of libluajit-5.1-dev,
  bundle it with jit/*.lua and its license; cache keys include the LuaJIT
  commit, recipe hash and Dockerfile hash.
- PortMaster zips: replace libs.aarch64/libluajit-5.1.so.2 with the pinned
  build, pin the PortMaster runtime to commit 715f50fd with sha256 checks
  (rg34xxsp followed main), ship LuaJIT-COPYRIGHT, verify the finished zip.
- verify_luajit.sh gates every package: version string, not beta, aarch64
  ELF, /usr module path, max GLIBC <= 2.31; offline selftests cover it and
  the PortMaster helpers.
- CI/release build LuaJIT once on an arm64 runner and pass it to the zip
  jobs via GEN1RECOMP_LUAJIT_LIB.

The JIT stays off by default (LÖVE's jitsetup disables it on arm/arm64).
POKEPORT_JIT=1 needs stability testing on H700, RK3566 and A133P devices
before it can be enabled by default.
2026-10-10 19:37:08 +01:00

61 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Host-side check of a built libluajit-5.1.so.2 (works on macOS and Linux, no
# readelf needed). Fails if the library is not the pinned LuaJIT, is the old
# 2.1.0-beta3, or needs a glibc newer than the pin allows.
#
# Usage: scripts/luajit/verify_luajit.sh <libluajit-5.1.so.2>
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=pins.sh
. "$HERE/pins.sh"
fail() { printf 'error: %s\n' "$*" >&2; exit 1; }
[ $# -eq 1 ] || fail "usage: verify_luajit.sh <libluajit-5.1.so.2>"
LIB="$1"
[ -f "$LIB" ] || fail "not a file: $LIB"
# 64-bit (byte 4 = 02), little-endian (byte 5 = 01), e_machine 0xb7 = aarch64.
hdr="$(od -An -tx1 -N20 "$LIB" | tr -d ' \n')"
[ "${hdr:0:8}" = "7f454c46" ] && [ "${hdr:8:2}" = "02" ] && [ "${hdr:10:2}" = "01" ] \
&& [ "${hdr:36:4}" = "b700" ] \
|| fail "$LIB is not a 64-bit little-endian aarch64 ELF"
grep -aqF "$LUAJIT_VERSION_STRING" "$LIB" \
|| fail "$LIB does not contain '$LUAJIT_VERSION_STRING'"
if grep -aq '2\.1\.0-beta' "$LIB"; then
fail "$LIB contains '2.1.0-beta' (old LuaJIT)"
fi
# Built with PREFIX=/usr; a build-prefix path here means a stale or wrong build.
grep -aqF '/usr/share/luajit-2.1/?.lua' "$LIB" \
|| fail "$LIB does not contain the default module path /usr/share/luajit-2.1/?.lua"
# Compare dotted versions numerically without relying on sort -V.
ver_gt() {
awk -v a="$1" -v b="$2" 'BEGIN {
na = split(a, x, "."); nb = split(b, y, ".")
n = na > nb ? na : nb
for (i = 1; i <= n; i++) {
if ((x[i] + 0) > (y[i] + 0)) exit 0
if ((x[i] + 0) < (y[i] + 0)) exit 1
}
exit 1
}'
}
maxg=""
while IFS= read -r v; do
v="${v#GLIBC_}"
[ -n "$v" ] || continue
if [ -z "$maxg" ] || ver_gt "$v" "$maxg"; then maxg="$v"; fi
done < <(grep -ao 'GLIBC_[0-9][0-9.]*' "$LIB" | sort -u)
[ -n "$maxg" ] || fail "$LIB has no GLIBC_ version strings"
if ver_gt "$maxg" "$LUAJIT_MAX_GLIBC"; then
fail "$LIB requires GLIBC_$maxg > $LUAJIT_MAX_GLIBC"
fi
echo "verify_luajit ok: '$LUAJIT_VERSION_STRING', max GLIBC=$maxg (limit $LUAJIT_MAX_GLIBC)" >&2