5

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

Chris R
  • 63
  • 1
  • 5
  • https://developer.android.com/studio/projects/add-native-code.html – Michael Apr 07 '18 at 21:37
  • 1
    But that describes how to add c++ source code to android studio and use cmake to compile it right? My C++ project is a quite big system by itself. So I want to compile it separately for Android using command line and then add that library to Android Studio. – Chris R Apr 07 '18 at 22:03

1 Answers1

2

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.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • Thank you @Alex. Using the existing cmake I got this error CMAKE_SYSTEM_NAME is 'Android' but 'NVIDIA Nsight Tegra Visual Studio Edition' is not installed. Do you know why this could be? – Chris R Apr 08 '18 at 19:38
  • Probably you have this package from NVIDIA installed on your PC, and it's cmake is on the system path. Try to provide full path to cmake executable which is part of Android SDK. – Alex Cohn Apr 08 '18 at 20:40
  • I have one of the libraries built and I added it to Android Studio project and setup an Android.mk. Now the problem is that the include files from the library which I included to my jni file is looking for Boost headers. Is there a way to specify the Boost root path(C:Boost) in Android.mk? How can I tell Android Studio where to look for Boost headers? – Chris R Apr 10 '18 at 15:59
  • Android.mk knows nothing about boost, unlike cmake. If you must provide path to boost, you must either pass it as argument to ndk-build, or fetch it from the OS environment string, or in the worst case, you can hardcode it. – Alex Cohn Apr 10 '18 at 16:45
  • I am also doing like this, i want to create a shared lib which has libssl.a and libcrypto.a but getting ld: warning: ld: warning: ignoring file openssl-armeabi-v7a/lib/libcrypto.a, file was built for archive which is not the architecture being linked (x86_64): openssl-armeabi-v7a/lib/libcrypto.aignoring file openssl-armeabi-v7a/lib/libssl.a, file was built for archive which is not the architecture being linked (x86_64): openssl-armeabi-v7a/lib/libssl.a don't understand what i am doing wrong – Amit Hooda Aug 10 '18 at 09:17
  • @AmitHooda, you need libssl for your Android device. You can find prebuilt libraries on the internet, but it's strongly recommended to build this security-related library from official sources. – Alex Cohn Aug 10 '18 at 09:45
  • @AlexCohn hi i have asked the question here https://stackoverflow.com/questions/51783701/cmake-creating-a-shared-arm-library-which-can-be-used-in-android , since this was not the right way to ask question :) , i have already build libssl and libcrypto and using those but since i want a shared lib of my own code along with these two libs so i have mentioned things in the question (link shared in this comment) – Amit Hooda Aug 10 '18 at 09:50
  • **Instead of a huge command-line, see** step-1 of [how to set Android tool-chain in cmake-script](https://stackoverflow.com/a/67729248/8740349) (tested with latest Android-Studio and v3.1, but the `ANDROID_ABI` option is unavoidable) – Top-Master Jun 09 '21 at 14:56
  • I got this error: ld: error: cannot open output file cmTC_7407b: Input/output – Mesut Jan 05 '23 at 17:36