Friday, June 2, 2017

IT++ and FFTW integration with Android NDK

IT++ and FFTW libraries need to be compiled specific to Application Binary Interface (ABI) for Android NDK.

These are the following ABIs:
  1. X86
  2. X86_64
  3. armeabi
  4. mips
  5. mips64
etc....
Further details can be found over here-> https://developer.android.com/ndk/guides/abis.html

IMPORTANT: Compile FFTW before IT++ as IT++ incorporates FFTW's archived library inside its own shared library.


FFTW compilation for NDK:
  1. Download the latest package from http://www.fftw.org/
  2. Unzip and go inside the folder: cd ~/Downloads/fftw-3.3.5
  3. Set the compilation parameters specific to an ABI. The example is for 'armeabi'.
    1. export NDK_ROOT="/Users/rajanya/Library/Android/sdk/ndk-bundle"
    2. export PATH="$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/:$PATH"
    3. export SYS_ROOT="$NDK_ROOT/platforms/android-21/arch-arm/"
    4. export CC="arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"
    5. export LD="arm-linux-androideabi-ld"
    6. export AR="arm-linux-androideabi-ar"
    7. export RANLIB="arm-linux-androideabi-ranlib"
    8. export STRIP="arm-linux-androideabi-strip"
    9. export DEST_DIR="$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/user"
  4. Generate Makefile: ./configure --host=arm-eabi --build=i386-apple-darwin10.8.0 --prefix=$DEST_DIR LIBS="-lc -lgcc" --disable-fortran
  5. make && make install

IT++ compilation with FFTW for NDK:
  1. Download the latest package from http://itpp.sourceforge.net/4.3.1/installation.html
  2. Unzip and go inside the folder: cd ~/Downloads/itpp-4.3.1
  3. mkdir build && cd build/
  4. Download https://github.com/taka-no-me/android-cmake to obtain cmake toolchain file.
  5. Open cmake GUI. If cmake not present , visit https://cmake.org/download/
  6. In cmake, add the following entries:
    1. Where is the source code: ~/Downloads/itpp-4.3.1
    2. Where to build the binaries:~/Downloads/itpp-4.3.1/build
  7. Then click '+Add Entry' button to add the following key-value pair:
    1. ANDROID_NDK -> PATH -> ~/Library/Android/sdk/ndk-bundle
    2. ANDROID_NATIVE_API_LEVEL -> STRING -> 17
    3. ANDROID_TOOLCHAIN_NAME -> STRING -> arm-linux-androideabi-4.9
  8. Click Configure -> Specify toolchain file for cross-compiling -> ~/Downloads/android-cmake-master/android.toolchain.cmake
  9. Click Generate.
  10. Return back to terminal. Run make && make install to build & install the shared library at /usr/local/lib/
NOTE: Repeat the above steps for each and every ABI

How to make IT++ functions available to the C++ code in Android?

  1. Copy /usr/local/lib/libitpp.so to <app_path>/app/libs/
  2. Enter the following lines in the CMake file:
    1. set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../libs)
    2. add_library(lib_itpp SHARED IMPORTED)
    3. set_target_properties(lib_itpp PROPERTIES IMPORTED_LOCATION

          ${distribution_DIR}/lib/${ANDROID_ABI}/libitpp.so)
    4. target_link_libraries(native-lib
                            android
                            lib_itpp)
  3. #include<itpp/itbase.h> in your native-lib.cpp file.






9 comments:

  1. Hello,

    I followed the instruction for ITPP and make && make install were successful. I now struggle with having itpp header files available in my android NDK project in which I use CMake.

    My CMake entry for itpp is:

    set(itpp_DIR /usr/local/lib)
    find_library(itpp REQUIRED)
    include_directories(${itpp_INCLUDE_DIR})

    I still have e.g.
    #include
    not available.

    Can anyone give me a hint what I am doing wrong? Than you.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Sorry there is a mistake. I wanted to say that after all I still have e.g.

      # include < itpp / itbase . h >

      not available for my cpp files

      Delete
    3. Hi Michal,
      I am happy to know that you referred to my blog :) I have appended a new section. Please refer to it and let me know if that solves your problem.

      Delete
  2. Hello,

    Thank you for adding some more insights about Android Studio and CMake.

    Unfortunately I still have issues with making it work.

    1) What do you mean exactly by:
    "NOTE: Repeat the above steps for each and every ABI" ?

    Do you mean repeating the steps only for "IT++ compilation with FFTW for NDK:" or also for FFTW? I have errors when I run `make && make install` for abis other than `arm-linux-androideabi-4.9`.

    2) Also after I successfuly complete all steps for `arm-linux-androideabi-4.9` I cannot find libittp.so at usr/local/lib but I find it at `~/Downloads/itpp-4.3.1/build/itpp/` instead. When I grab the .so file and link it in Android Studio project CMake i can successfuly sync gradle but when I try to build project I get:

    Error:error: linker command failed with exit code 1 (use -v to see invocation)
    Error:error: ../../../../libs/libitpp.so: incompatible target

    Can you give any hints? Thanks a lot.

    ReplyDelete
    Replies
    1. Ok, I do not have errors when building for other ABIs, I have not been cleaning cmake cash before compiling for other ABI. Now it works.

      I organise the output libittp.so files in separate folders and then will try to plug one of them into Android Studio project CMakeLists.txt . So far I tried 3 of them and result is always :

      "Error:error: linker command failed with exit code 1 (use -v to see invocation)
      Error:error: ../../../../libs/libitpp.so: incompatible target"

      Delete
    2. Ok I have repeated steps for ITPP for all ABIs and my android studio project compiles well when I use the following CMakeLists entries:

      set(distribution_DIR ${CMAKE_SOURCE_DIR}/libs)
      add_library(lib_itpp SHARED IMPORTED)
      set_target_properties(lib_itpp PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/${ANDROID_ABI}/libitpp.so)

      I also added `lib_itpp` to my `target_link_libraries` cmake command at the end of the CMakeLists.txt file.
      I feel like I am close. The last remaining issue is that besides everything should be compiled Android Studio does not recognize:

      #include

      throwing: Error:fatal error: 'itpp/base.h' file not found

      Any hints what may be wrong? I suspect i have a bug in the CMakeLists.txt

      Delete
    3. You need to put the headers in the 'include' folder.

      Delete
    4. Everything works now :) Thank you a lot for this blog article and for your support.

      Delete