androidandroid-ndkspeex

Compiling Speex and SpeexDSP for Android 64bit architectures results in "error: impossible constraint in 'asm'"


Google recently announced policy requiring support libraries be recompiled for 64bit support so I'm hoping someone else has also been down this road recently.

I'm trying to compile Speex 1.2 for Android 64bit ARM. I was able to build speex but speexdsp fails.

Here are the steps I took, followed by the failure:

  1. Created a standalone toolchain:

    ~/android-ndk-r17/build/tools/make-standalone-toolchain.sh --platform=android-21 --install-dir=~/speex-toolchain --arch=arm64
    
  2. Set my PATH to look first in the toolchain's bin directory

    export PATH=~/speex-toolchain/bin:$PATH
    
  3. Set the CC and RANLIB env vars (maybe not necessary?)

    export CC=aarch64-linux-android-gcc
    export RANLIB=aarch64-linux-android-ranlib
    
  4. ./configure --host=arm
  5. make

Make fails with:

make  all-recursive
make[1]: Entering directory `/Users/spartygw/Downloads/speexdsp-1.2rc3'
Making all in libspeexdsp
make[2]: Entering directory `/Users/spartygw/Downloads/speexdsp-1.2rc3/libspeexdsp'
  CC       preprocess.lo
  CC       jitter.lo
  CC       mdf.lo
  CC       fftwrap.lo
  CC       filterbank.lo
  CC       resample.lo
In file included from resample.c:104:0:
resample.c: In function 'resampler_basic_direct_single':
resample_neon.h:148:5: error: impossible constraint in 'asm'
     asm volatile ("  cmp %[len], #0\n"
     ^
make[2]: *** [resample.lo] Error 1
make[2]: Leaving directory `/Users/spartygw/Downloads/speexdsp-1.2rc3/libspeexdsp'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/Users/spartygw/Downloads/speexdsp-1.2rc3'
make: *** [all] Error 2

Solution

  • Instead of steps 3 and 4, I would suggest just doing ./configure --host=aarch64-linux-android, which takes care of picking up the right tools, and which gets the target architecture right.

    As for the main issue, the compilation error, the issue seems to be that speexdsp does support NEON (ARM's SIMD instruction set), but it detects it in configure in one way (by testing if #include <arm_neon.h> works and if NEON compiler intrinsics work, which work the same for both ARM and AArch64). Once it concluded that NEON is supported, it goes on to use it via inline assembly (which is different for ARM and AArch64).

    So the conclusion is that speexdsp only supports NEON on ARM (32 bit), not on 64 bit, but speexdsp's configure script enables it incorrectly for AArch64 as well. Add --disable-neon to the configure call, and compilation should succeed.