diff --git a/.gitea/workflows/build-and-test.yml b/.gitea/workflows/build-and-test.yml index 8d1f8c2..5350cd3 100644 --- a/.gitea/workflows/build-and-test.yml +++ b/.gitea/workflows/build-and-test.yml @@ -272,12 +272,30 @@ jobs: exit 1 fi echo "checking $SO" - file "$SO" - API=$(file "$SO" | sed -n 's/.*for Android \([0-9]*\).*/\1/p') - if [ -z "$API" ] || [ "$API" != "$MIN_API" ]; then - echo "FAIL: linked for Android '${API:-unknown}', expected $MIN_API" + # `file` is kept for the log — it names the NDK that built this — but + # the check no longer depends on it. + file "$SO" || true + # The API level is the first word of the `.note.android.ident` ELF + # note, little-endian. Read the note rather than asking `file` for it: + # `file` only prints "for Android 28" when its magic database is new + # enough to decode that note, and this image's is not. The parse then + # produced nothing, `${API:-unknown}` reported "unknown", and every + # push failed here for weeks on a .so that was linked perfectly + # correctly. A note read straight out of the ELF cannot go stale that + # way. + readelf -n "$SO" | sed -n '/android.ident/,+3p' + HEX=$(readelf -n "$SO" 2>/dev/null \ + | awk '/description data:/ { print $6 $5 $4 $3; exit }') + if [ -z "$HEX" ]; then + echo "FAIL: no .note.android.ident in $SO — nothing states an API level" exit 1 fi + API=$(( 0x$HEX )) + if [ "$API" != "$MIN_API" ]; then + echo "FAIL: linked for Android $API, expected $MIN_API" + exit 1 + fi + echo "OK: linked for Android $API" # The APK itself, so a run leaves something installable behind rather # than only the knowledge that it would have linked. The assembly is