Search code examples
c++android-studiogradleandroid-ndkgoogletest

Android NDK with Google Test


I'm trying to use GoogleTest on Android Studio.

According to what I understood, the latest version of NDK has the gtest included.

I did not find a clear guide how to do it.

I followed this document:

So, I opened a new project, created jni folder and the following files (inside the files I wrote exactly what the document):

enter image description here

But it does not recognize the #include gtest/gtest.h

In addition,

  • how to run the adb at the end?
  • I created an android.mk file but where should I call it?

Solution

  • If you choose cmake to drive your externalNativeBuild (and this is the preferred option, according to Android Developers NDK guide), then you can simply add the following lines to your CMakeLists.txt:

    set(GOOGLETEST_ROOT ${ANDROID_NDK}/sources/third_party/googletest/googletest)
    add_library(gtest STATIC ${GOOGLETEST_ROOT}/src/gtest_main.cc ${GOOGLETEST_ROOT}/src/gtest-all.cc)
    target_include_directories(gtest PRIVATE ${GOOGLETEST_ROOT})
    target_include_directories(gtest PUBLIC ${GOOGLETEST_ROOT}/include)
    
    add_executable(footest src/main/jni/foo_unittest.cc)
    target_link_libraries(footest gtest)
    

    If your build succeeds, you will find app/.externalNativeBuild/cmake/debug/x86/footest. From here, you can follow the instructions in README.NDK to run it on emulator or device.


    Notes:

    • make sure that the ABI matches the target you use (the guide is not very clear about this).
    • the list of ABI's that are built is controlled by abiFilters in build.gradle. In Android Studio, even ndk-build ignores APP_ABI set in Application.mk.
    • the files Android.mk and Application.mk are ignored when you use cmake.
    • for gradle-3.3, and classpath 'com.android.tools.build:gradle:2.3.3', as in the current Android Studio release 2.3.3, you may need to explicitly specify the unittest target in build.gradle:

      android { defaultConfig { externalNativeBuild { cmake { targets "foo_unittest" }}}}
      
    • with Android Studio 3.0, gradle-4.1, and classpath 'com.android.tools.build:gradle:3.0.0-beta6' the executable is easier to find under app/build/intermediates/cmake/debug/obj.


    To test the foo(int x, int y) function from foo.cpp in a shared library (to make is as close as possible to the NDK instructions), you need some more lines in your CMakeLists.txt script:

    # build libfoo.so
    add_library(foo SHARED src/main/jni/foo.cpp)
    target_link_libraries(footest foo) 
    

    You will find libfoo.so to copy manually to your device under app/build/intermediates/cmake/debug/obj.

    To reduce the hassle, you can use STATIC instead of SHARED, or simply add foo.cpp to footest executable:

    add_executable(footest src/main/jni/foo_unittest.cc src/main/jni/foo.cpp)