Search code examples
cmakeandroid-ndkjava-native-interface

how to include inter-dependent source files from differnt sub-dirs into cmake


Statement: I've some C code that I generally build (using Makefile) and run on Linux. But now I want to run the same code on an Android device. So here's my approach.

  • Create a empty/basic activity in Android studio and add call to my C code. To start off with I'm just printing hello world and that part works. Here's the code from MainActivity.java
public native String helloC();
TextView tv = (TextView) findViewById(R.id.hello_textview);
tv.setText(helloC());
static {    
System.loadLibrary("native-lib"); 
}

Here's my C code (native-lib.cpp):

JNIEXPORT jstring JNICALL Java_com_example_myapp_MainActivity_helloC(JNIEnv *env, jobject javaobj) {
    return env->NewStringUTF("Hello from JNI ! ");
}

I can successfully build and run this and I do see hello from JNI on the device.

  • Next step is to add my code into the same directory as native-lib.cpp (cpp folder) project_structure

The code in app, config, common and remote have a mixture of .h, .c files and also sub-folders. The entry point into this code is remote_main() which is in remote/remote_main.c file. My plan is to call the remote_main() within my native-lib.cpp. To do that, all my source files should be compile-able. I added include_directories in cmakelist (src/main/cpp/app and so on).

Here are my 2 issues:

  1. Even though I've added include_directories, I see an error with all headers saying "cannot find .h" error
  2. Next issue is how do I compile all the C files within the 4 folders mentioned above and their sub-folders. I tried the method mentioned in this issue. But the problem is my code is interdependent. Files in one folder may need files from other folder. So I cannot create individual cmake file for each folder and build it independently and link them together.

This is my first time using CMake and running on Android. Any suggestion/help is appreciated.

CMakeLists.txt contents:

cmake_minimum_required(VERSION 3.4.1)

include_directories("src/main/cpp/app" "arc/main/cpp/config" "src/main/cpp/common" "src/main/cpp/remote")
add_library( native-lib

             SHARED

             src/main/cpp/native-lib.cpp )

find_library( log-lib log )

target_link_libraries( native-lib ${log-lib} )

Solution

  • You can select all .c files with one command and add them as "files to compile" for your native-lib target:

    FILE(GLOB_RECURSE C_SOURCES "src/main/cpp/*.c")
    add_library( native-lib
                 SHARED
                 src/main/cpp/native-lib.cpp
                 ${C_SOURCES})
    target_include_directories(native-lib PRIVATE src/main/cpp/app src/main/cpp/config src/main/cpp/common src/main/cpp/remote)
    

    You can add arbitrary compile definitions using target_compile_definitions:

    target_compile_definitions(native-lib PRIVATE -D__FLAVOR_CLIENT)