0

In an Android project that loads a C library (mylib.so, which includes a JNI API already), I have a CMakeLists.txt that import the prebuilt library, as per the documentation, like so:

cmake_minimum_required(VERSION 3.10.2)
project(ImportMyLib)

set(MYLIB_PREBUILT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/build/arm64/src")

add_library(mylib SHARED IMPORTED)
set_target_properties(mylib
                      PROPERTIES IMPORTED_LOCATION
                      "${MYLIB_PREBUILT_PATH}/libmylib.so")

I did print ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/build/arm64/src and checked that ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/build/arm64/src/libmylib.so does exist.

However, libmylib.so is not included in the resulting .aar, and I don't understand why.

My build.gradle does include the CMakeLists.txt above, like so:

externalNativeBuild {
    cmake {
        path "src/main/cpp/CMakeLists.txt"
    }
}

This is similar to this question, except that it seems there that there was a need to add an IMPORTED target (because of the ExternalProject_Add), whereas here I'm trying to import an already built library.

What am I missing?

JonasVautherin
  • 7,297
  • 6
  • 49
  • 95

2 Answers2

1

You can explicitly request libmylib.so to be included:

externalNativeBuild {
    cmake {
        path "src/main/cpp/CMakeLists.txt"
        targets "mylib" # matches add_library(mylib SHARED IMPORTED)
    }
}
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • Hmm I get "Could not find method targets() for arguments [mylib] on object of type com.android.build.gradle.internal.dsl.CmakeOptions$AgpDecorated.", but I can't see what I'm missing there. Really I use the CMakeLists.txt above. Actually it fails before it reaches `add_library` in my CMakeLists (I added a `message(FATAL_ERROR "something")` at the beginning of the file and it's not showing) – JonasVautherin Jan 15 '23 at 15:19
  • Also I can't find it in the documentation: https://developer.android.com/reference/tools/gradle-api/4.1/com/android/build/api/dsl/Cmake – JonasVautherin Jan 15 '23 at 15:29
  • Following https://stackoverflow.com/questions/64829357/specify-targets-in-externalnativebuild-of-the-build-gradle-file-no-signature-o, I put it in `defaultConfig { externalNativeBuild { cmake` and now it goes further to "Unexpected native build target mylib. Valid values are:". Not sure why valid values are empty, though :/. – JonasVautherin Jan 15 '23 at 15:47
  • 1
    Indeed, `targets` belong to a different clause, see https://stackoverflow.com/a/64829814/192373 – Alex Cohn Jan 16 '23 at 13:47
1

I had missed this part of the documentation:

If you want Gradle to package prebuilt native libraries that are not used in any external native build, add them to the src/main/jniLibs/ABI directory of your module. Versions of the Android Gradle Plugin prior to 4.0 required including CMake IMPORTED targets in your jniLibs directory for them to be included in your app. [...] If you are using Android Gradle Plugin 4.0, move any libraries that are used by IMPORTED CMake targets out of your jniLibs directory to avoid this error.

Moving mylib.so to src/main/jniLibs/ABI does work indeed.

JonasVautherin
  • 7,297
  • 6
  • 49
  • 95