I am trying to make use of the (experimental) native NDK support in Android Studio. I am new to working with Gradle. The project I am trying to build uses outside libraries which are to be compiled as static libraries when compiling the project and then be used within it. How can I do this?
To elaborate - There is C++ code in the default src/main/jni
, it compiles properly and it can be seen properly in Android Studio under the jni
folder. The project uses external C++ static libraries - some are compiled, some not. I need the project and the libraries to be built correctly and the code t obe visible where possible.
First of all, is there a way to be able to use Android.mk files? They are already available from a previous scheme to import the libraries but it seems that they are ignored now.
I've tried using srcDirs
in android.source
to add the libraries' paths and it works up to some point but strangely some of the paths are not found from the compiler and the compilation stops. Here's the code:
android.sources {
main {
jni {
source {
srcDirs += ["/../../../libPdf/"]
// aes library
srcDirs += ["/../../../libs/aes/include", "/../../../libs/aes"]
// jpeg library
srcDirs += ["/../../../libPdf/platform/Android", "/../../../libs/jpeg/jpeg-9"]
}
}
}
}
I've also tried adding the libraries as separate modules and then compiling each one of them in the project build.gradle
(I saw this one in this sample: https://github.com/googlesamples/android-ndk/tree/master/hello-thirdparty) but I get this error even if I create a build.gradle
file for the library:
Error:Configuration with name 'default' not found.
I don't know if I need an .iml file for the library, I don't have one and I don't know how to create one. I tried altering an existing one an putting it in the library but the same error occurred. Here is the code from the project's build.gradle:
apply plugin: 'com.android.model.library'
apply plugin: 'maven'
def jpeg_sdk_path = file(project(':jpeg').projectDir).absolutePath + "/jpeg-9"
model {
android.buildTypes {
release {
consumerProguardFiles += file('proguard-project.txt')
}
}
android.ndk {
moduleName = "native"
cppFlags += "-I${jpeg_sdk_path}".toString()
ldLibs += ["jpeg"]
}
android {
compileSdkVersion = 23
buildToolsVersion = "21.1.2"
defaultConfig.with {
minSdkVersion.apiLevel = 14
targetSdkVersion.apiLevel = 23
}
lintOptions.with {
disable 'MissingTranslation'
}
//copy resources and stuff tasks
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.0'
compile files('libs/jsoup-1.7.3.jar')
compile project(':jpeg')
}
And here is the settings.gradle:
include ':libPDF'
include ':PDFViewer'
include ':jpeg'
project(':jpeg').projectDir = new File(settingsDir, '/../../../libs/jpeg')
There are more libraries to be included but I am trying to import just one for now - jpeg, to see that it is working. I am trying to make local modules now and somehow connect them from gradle to the code which is elsewhere. I still get the same error - the build.gradle
file does not seem to be found.
Any advice? Thanks in advance.
Edit: I managed to get the whole thing compiled but now I get linker errors. Here's the (shortened version of) build.gradle of the project:
apply plugin: 'com.android.model.library'
apply plugin: 'maven'
def jpeg_sdk_path = file(project(':jpeg').projectDir).absolutePath + "/../../../../../../../libs/jpeg/jpeg-9"
//other defs of paths
model {
android.buildTypes {
release {
minifyEnabled = false
consumerProguardFiles += file('proguard-project.txt')
}
debug {
minifyEnabled = false
consumerProguardFiles += file('proguard-project.txt')
}
}
android.sources {
main {
jni {
source {
srcDirs += ["src/main/jni/"]
//lcms2
srcDirs += [lcms2_out_path + "/src"]
//freetype library
include aes_path + "/aes_modes.c"
include aes_path + "/aescrypt.c"
include aes_path + "/aeskey.c"
include aes_path + "/aestab.c"
// jbig2 library
srcDirs += [jbig2_path + "/src/jbig2", jbig2_path + "/include"]
// sfntly library
include sfntly_path + "/sample/chromium/subsetter_impl.cc"
//many other includes here
// jpeg library
srcDirs += [ jpeg_main_path + "/../../../../../../../libPdf/platform/Android"]
include jpeg_sdk_path + "/jaricom.c"
include jpeg_sdk_path + "/jcapimin.c"
//many other includes here
//native libpdf library
include libpdf_path+ "/PdfCatalog.cpp"
//many other includes here
//openssl library
srcDirs += [openssl_path + "/lib/Android/armeabi-v7a/include"]
}
}
jniLibs{
source{
srcDirs += ['/src/main/libs']
srcDirs += [freetype_path + '/platform/Android/obj/local']
srcDirs += [libpdf_path]
}
}
resources.source.srcDirs += ['src/main/res']
}
}
android.ndk {
moduleName = "native"
CFlags += "-I${openjpeg_path}/prebuilt/armeabi-v7a/include".toString() //figure out how to include for other flavors
CFlags += "-I${jpeg_main_path}/../../../../../../../libPdf/platform/Android".toString()
CFlags += "-I${jpeg_sdk_path}".toString()
//other CFlags here
CFlags += "-DSFNTLY_NO_EXCEPTION"
CFlags += "-DU_STATIC_IMPLEMENTATION"
cppFlags += CFlags
abiFilters += "armeabi-v7a"
ldFlags += "-L${freetype_src_path }/../platform/Android/obj/local/armeabi-v7a".toString()
ldLibs += ["log", "android", "EGL", "GLESv1_CM", "ft2"]
//other ldFlags and ldLibs - for the static .a libraries only
stl = "gnustl_static"
}
compileOptions.with {
sourceCompatibility=JavaVersion.VERSION_1_7
targetCompatibility=JavaVersion.VERSION_1_7
}
android {
compileSdkVersion = 23
buildToolsVersion = "21.1.2"
defaultConfig.with {
minSdkVersion.apiLevel = 14
targetSdkVersion.apiLevel = 23
}
lintOptions.with {
disable 'MissingTranslation'
abortOnError = false
}
//tasks for moving resources and stuff here
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.0'
compile files('libs/jsoup-1.7.3.jar')
compile project(':jpeg')
compile project(':freetype')
compile project(':lcms2')
compile project(':jbig2')
compile project(':aes')
compile project(':openjpeg')
compile project(':sfntly')
}
Now I get a lot of errors like that:
Error:(737, -1) Gradle: undefined reference to 'AndroidBitmap_getInfo'
I think I know why I get this - I should use something else instead of include
to add individual files to the source set.
My question now is: How do I add individual files to a source set so they can be used by the compiler and later by the linker?