Search code examples
androidcmakeandroid-ndkandroid.mk

Building c++ projects which have cmake build files for Android using NDK


I have to build 2 separate C++ projects which have Cmake build files setup for different platforms. I want to build them both for Android using NDK so that I can use them as prebuilt libs in Android Studio.

  1. How do I build them for Android using NDK to generate a .a/.so for Arm architectures? Can I do it using cmake itself? Please provide detailed steps

  2. Finally when I have 2 libraries, how do I integrate to Android Studio? I kind of learnt how to create Android.mks for prebuilt libraries from this link Using Pre-built Shared Library in Android Studio But my lib2 depends on lib1 for both compilation and running. Jni code will depend on the combined library of both lib2 and lib1

I am new to NDK. So please provide detailed answers


Solution

  • Most likely, the CMake scripts that work for other platforms will require some changes for Android. Also, we often need special treatment for external dependencies, e.g. if we want CMake to find the correct version of boost.

    But the main skeleton of CMakeLists.txt should be a good start. You can run CMake 'manually' for your libraries:

    cmake                                                           \
        -DCMAKE_TOOLCHAIN_FILE=${NDK_ROOT}/build/cmake/android.toolchain.cmake \
        -DANDROID_NDK=${NDK_ROOT}                               \
        -DANDROID_ABI=armeabi-v7a                               \
        -DANDROID_PLATFORM=android-19                           \
        -DANDROID_STL=c++_shared                                \
        -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${LIB1_DIRECTORY}/libs/armeabi-v7a       \
        ${LIB1_DIRECTORY}
    

    In the main CMakeLists.txt that builds your JNI wrapper, you can add

    add_library(lib1 SHARED IMPORTED)
    set_target_properties(lib1 PROPERTIES IMPORTED_LOCATION ${LIB1_DIRECTORY}/libs/armeabi-v7a/lib1.so )
    target_link_libraries(jni_wrapper lib1 … log)
    

    Android Studio will not build lib1.so for you, but it will pick it from the correct location and pack it into the APK.

    Same trick with IMPORTED will provide lib1 for build of lib2 if the CMake script does not already handle this dependency.