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

1

6

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

Parmesan answered 7/4, 2018 at 20:6 Comment(2)
developer.android.com/studio/projects/add-native-code.htmlEasterner
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.Parmesan
H
3

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.

Hydrophyte answered 8/4, 2018 at 7:53 Comment(9)
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?Parmesan
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.Hydrophyte
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?Parmesan
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.Hydrophyte
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 wrongFurlong
@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.Hydrophyte
@AlexCohn hi i have asked the question here #51784201 , 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)Furlong
Instead of a huge command-line, see step-1 of how to set Android tool-chain in cmake-script (tested with latest Android-Studio and v3.1, but the ANDROID_ABI option is unavoidable)Cerda
I got this error: ld: error: cannot open output file cmTC_7407b: Input/outputPete

© 2022 - 2024 — McMap. All rights reserved.