1

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} )
ARao
  • 261
  • 4
  • 14

1 Answers1

1

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)
Botje
  • 26,269
  • 3
  • 31
  • 41
  • Thanks for that suggestion, that helped me include all my source files in the build process. I had to add "PUBLIC" to the"target_include_directories". I see an error saying use of undeclared identifier '_BUFFER_LENGTH', but this code is present. - - - #if defined __FLAVOR_CLIENT \ || defined __FLAVOR_SERVER \ || defined __FLAVOR_DRIVER .... .... # define BUFFER_LENGTH (128 * 1024) - - - But for some reason this code is greyed out. I'm guessing it's because I don't have __FLAVOR_* set. Is this something that can be set in cmake again? – ARao Jan 03 '20 at 15:51
  • Updated my answer. Are you sure this is supposed to be set by the compiler and not in some kind of configuration header file? – Botje Jan 03 '20 at 15:59
  • Not sure, will look into it. Thanks for the help :) – ARao Jan 03 '20 at 16:01