On aarch64, set the target architecture to a base architecture (arm8.5-a, in this case) and use attribute((target)) to enable instruction set extensions as needed on a per function basis.
There's a speculative fix for #2.
test_static fails sve2 aes prefix popcounting but at least it's successfully arch-detecting (first output is under qemu-aarch64 with advanced CPU support, second is directly on pi5, cortex-A76):
$ qemu-aarch64 ./build/test/test_static
AMD64 tests: SKIPAARCH64 tests:
Portable/aarch64 sve2 aes prefix popcounting): ERROR, no match for 8 bit on iter 0, index 0
mask: ec
portable: e2
aes: 0
Portable/aarch64 neon prefix popcounting: PASS
portable/bitperm pext: PASS
portable/bitperm pdep: PASS
portable/aes pext: PASS
portable/aes pdep: PASS
portable/neon pext: PASS
portable/neon pdep: PASS
portable/bitperm pexts: PASS
portable/bitperm pdeps: PASS
portable/aes pexts: PASS
portable/aes pdeps: PASS
portable/neon pexts: PASS
portable/neon pdeps: PASS
support: 3e
$ $ ./build/test/test_static | grep -v SKIP
Portable/aarch64 neon prefix popcounting: PASS
portable/neon pext: PASS
support: 2
This is in contrast to an earlier version just crashing out because instruction set extensions were enabled across all source files & functions, which led to them being used in general test code. (something I reported on mastodon, not codeberg) (though I'm not reproducing that at the tip of your main so this needs a grain of salt)