My build.gradle file contains this to build a project with CMake:
externalNativeBuild {
cmake {
// Provides a relative path to your CMake build script.
version "3.13.0+"
path "../subproj/smcxx/CMakeLists.txt"
}
}
The CMakeList.txt defines multiple targets, but the problematic one is this:
set(SOURCES "src/lib.cc")
add_library(smcxx_obj OBJECT ${SOURCES})
An OBJECT target would not build a .so
or .a
file, instead, the .o
files can be used in other targets.
The problem is (from my understanding) that Gradle analyzes the CMake targets and expects an output file for each target. When I compile the whole project using gradlew, I get the following error message:
> Task :app:externalNativeBuildDebug FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:externalNativeBuildDebug'. > Expected output file at /home/cytrinox/src/androidapp/app/.cxx/cmake/debug/armeabi-v7a/smcxx_obj for target smcxx_obj but there was none
The object file lib.cc.o was successfully compiled and exists. But there is no smcxx_obj folder nor a smcxx_obj.so file (which is expected).
Is it possible to solve this error, for example by telling Gradle to skip this check for a specific CMake target?
According to the documentation:
Gradle builds all executables and shared object libraries that you define in your CMake (or ndk-build) project.
However, CMake object libraries don't seem to be supported at all, and cause the issue you are experiencing. I actually believe this is a bug: Gradle should just skip building them, as they are mostly only useful within CMake itself.
Anyhow, you can fix this by manually specifying which CMake targets you want Gradle to build (e.g. just omit object library targets and you'll be fine):
android {
...
defaultConfig {
...
externalNativeBuild {
...
cmake {
targets "target1", "target2"
}
}
}