Saturday, February 19, 2022

[SOLVED] How to get the BUILD TYPE while using Android NDK built via CMAKE?

Issue

I'm pretty new to integrating Android NDK. I'm trying to return different text while calling a native function to my main app. I have two build types - release and debug. How do I send different strings to my main app for different build types?

Below is the code :

native-lib.cpp

extern "C"
JNIEXPORT jstring JNICALL
Java_test_main_MainActivity_getStringFromJNI(JNIEnv *env, jobject thiz) {
    std::string stringToBeReturned = "Hello";
    return env->NewStringUTF(stringToBeReturned.c_str());
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )
target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib})

I'd like to get the build type in the native-lib.cpp so that I can change the value of stringToBeReturned depending upon the build type. Kindly help.


Solution

So I was able to achieve what I wanted with the help of the suggestions in the comment section as below:

I started by adding my build.gradle while at module level.

{
defaultConfig
   ...
   ...
   ...
   //other properties
  externalNativeBuild{
            cmake{
                cppFlags "-DBUILD_TYPE=debug"
            }
        }
}

buildTypes {
        release {
           ...
           ...
           //other properties
            externalNativeBuild{
                cmake{
                    cppFlags "-DBUILD_TYPE=release"
                }
            }
        }
}

Here, BUILD_TYPE is the name of the variable being passed and debug and release are it value for different build types.

Then in my native-lib.cpp, I applied the following code:

#define xstr(s) str(s) //important header
#define str(s) #s //important header
extern "C"
JNIEXPORT jstring JNICALL
Java_test_main_MainActivity_getStringFromJNI(JNIEnv *env, jobject thiz) {
    std::string stringToBeReturned;
    std::string build_type = xstr(BUILD_TYPE); //get the value of the variable from grade.build
    if(build_type=="debug"){
      stringToBeReturned = "Yay!! String returned from debug variant!"
    }else if(build_type=="release"){
      stringToBeReturned = "Yay!! String returned from release variant!"
    }
    return env->NewStringUTF(stringToBeReturned.c_str());
}


Answered By - Kavach Chandra
Answer Checked By - Terry (WPSolving Volunteer)