Saturday, October 16, 2010

cross compiling for android

The NDK, last time I looked, did an OK job of building small jni modules, but what if you needed to use third party libraries? Then you were in for a rough ride. But I managed to get something working together. First go get crystax's NDK so you have a real C++ environment. Not strictly necessary but let's keep surprises to a minimum shall we?

After installation I set the following variables, which you'll probably want to stuff into a file you can source from time to time:
export NDK_HOME=/opt/android/ndk
export TOOLCHAIN_ROOT=$NDK_HOME/build/prebuilt/linux-x86/arm-eabi-4.4.0/
export PLATFORM_ROOT=$NDK_HOME/build/platforms/android-8/arch-arm
export PATH=$PATH:${TOOLCHAIN_ROOT}/bin
You'll also need the following files:
and if you use CMake or it's needed for other libraries (ie OpenCV), here's a toolchain file:

A note on the cmake toolchain file: It is setup mostly to be standalone but there are some complex things going on that agcc/ag++ take care of internally that would be difficult to add to the toolchain file to modify cmake's behavior appropriately. If you have improvements, please be vocal about them!

Anywho, place agcc/ag++ in your path and mark them executable. Then just set CC/CXX appropriately. Source the ndk variables set above and everything should takecare of itself with autoconf/automake projects. For cmake projects, use the cmake file above and the first line lists an example calling. Keep in mind that bionic, the c library used in android, is pretty small though so don't be surprised if you have to patch out some c functions you've never heard of.

Here's an example for installing libtiff to your ndk:
./configure --host=arm-eabi CC=agcc CXX=ag++ \
CC=agcc CXX=ag++ \
CPPFLAGS="-D__i386__ -DANDROID -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -D__ANDROID__ -I/opt/android/ndk/build/platforms/android-8/arch-arm/usr/include" \
CFLAGS="-nostdlib -march=armv7-a -mtune=xscale -mfloat-abi=softfp -mfpu=vfp -mthumb-interwork -ffunction-sections -fstack-protector -fno-short-enums -Wno-psabi" \
LDFLAGS="-Wl,-rpath-link=/opt/android/ndk/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/ndk/build/platforms/android-8/arch-arm/usr/lib -Wl,-rpath-link=/opt/android/ndk/build/platforms/android-8/arch-arm/lib/gcc/arm-eabi/4.4.0 -L/opt/android/ndk/build/platforms/android-8/arch-arm/lib/gcc/arm-eabi/4.4.0 -Wl,-rpath-link=/opt/android/ndk/build/platforms/android-8/arch-arm/arm-eabi/lib -L/opt/android/ndk/build/platforms/android-8/arch-arm/arm-eabi/lib -WWl,--fix-cortex-a8 -lgcc -lstdc++ -lsupc++ -lm -lc" \
--prefix=/opt/android/ndk/build/platforms/android-8/arch-arm/usr --disable-cxx
make install DESTDIR=/opt/android/ndk/build/platforms/android-8/arch-arm/
Note that this compiles and installs to the android 2.2 platform.

Kudos to Andrew Ross for the original agcc script, which I've modified above.

1 comment:

  1. will this generate shared object or static library? I am trying to build the same procedure mentioned above. But I am getting static library. How do I get shared object?

    ReplyDelete