android - descargar - ndk r16
Cómo usar bibliotecas extra*.so en Android Studio y NDK (1)
Estoy intentando generar una aplicación de Android para usar algunas bibliotecas * .so adicionales (específicamente ''libinterface.so''). Esas bibliotecas se generan externamente y se incluyen como una dependencia dentro de una clase contenedora llamada desde el lado Java. La biblioteca se almacena en ''src / main / jniLibs / armeabi-v7a''. El sistema incluye todo el archivo .so en la aplicación generada.
Anteriormente, estaba usando Eclipse para este fin y pude usar esta biblioteca, pero tengo problemas para hacer esto con Android Studio.
El error generado es:
/home/******/Libraries/android-sdk-linux/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9/../../../../aarch64-linux-android/bin/ld: cannot find -linterface
A medida que el error arroja el vinculador, parece relacionado con el paso de inclusión de la biblioteca. En Eclipse, estaba usando un archivo ''Android.mk'' para incluir la nueva biblioteca, pero no puedo encontrar la manera de hacerlo con Gradle.
#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libinterface-prebuilt
LOCAL_SRC_FILES := prebuilt/libinterface.so
include $(PREBUILT_SHARED_LIBRARY)
Estoy intentando incluir las bibliotecas con esta definición gradle (Nota: he incluido el último soporte JNI y gradle-experimental usando este tutorial ):
...
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file(''proguard-android.txt''))
}
}
android.ndk {
moduleName = "custom_wrapper_jni"
cppFlags.add("-I" + file("src/main/jni").absolutePath)
cppFlags.add("-I" + file("../Integration/include").absolutePath) // <- New library header include path
cppFlags.add("-L" + file("src/main/jniLibs/armeabi-v7a").absolutePath) // <- Path where the library is stored
cppFlags.add("-std=c++11")
stl = "stlport_static" // Which STL library to use: gnustl or stlport
ldLibs.add("log")
ldLibs.add("interface") //<- Library to be included
}
...
La biblioteca se compila externamente con las herramientas CMake y makefile, y se compila de forma cruzada ''correctamente'' para la plataforma Android (probada con Eclipse y ADT).
Implementé el contenedor de esta manera:
// custom_wrapper_jni.h
#ifndef ANDROID_JNI_H
#define ANDROID_JNI_H
#include <jni.h>
extern "C"
{
JNIEXPORT jint JNICALL
Java_com_example_goe_android_JniInterface_testFunction(JNIEnv *env,
jobject instance);
}
#endif
y
// custom_wrapper_jni.cpp
#include <custom_wrapper_jni.h>
#include "Interface.h" // Header of the included library
Interface* mInterface = Interface::create(); // Generate the library class instance
JNIEXPORT jint JNICALL
Java_com_example_goe_android_JniInterface_testFunction(JNIEnv *env,
jobject instance)
{
LOGI("Test function called in wrapper!");
return mInterface->test(); // Use the instance
}
El encabezado de la biblioteca se ve así:
#ifndef INTERFACE_H__
#define INTERFACE_H__
#include <string>
class Interface
{
public:
static Interface* create();
virtual ~Interface(){}
// Testing function
virtual int test() = 0;
protected:
Interface();
};
#endif // INTERFACE_H__
Gracias por adelantado.
ACTUALIZAR:
Siguiendo este ejemplo , he incluido algunos bloques en el script de Gradle:
def lib_path = file("src/main/jniLibs").absolutePath
model {
repositories {
libs(PrebuiltLibraries) {
newlibs {
headers.srcDir file("../Integration/include").absolutePath
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${lib_path}/${targetPlatform.getName()}/libinterface.so")
println "Included libraries: " + file("${lib_path}/${targetPlatform.getName()}/libinterface.so")
}
}
}
}
android {
...
}
android.sources {
main {
jni {
dependencies {
library "newlibs" linkage "shared"
}
}
}
}
}
pero no está funcionando:
Error: org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationFailure: Linker failed while linking libcustom_wrapper_jni.so.
Ok, podría haber dos problemas diferentes.
Primero, debe asegurarse de que la biblioteca esté compilada para la arquitectura correcta. Si está utilizando una biblioteca armeabi-v7a, pero el compilador intenta cargar una biblioteca armeabi, la compilación fallará.
En segundo lugar, y siguiendo también con el primer problema, debe incluir las bibliotecas según la arquitectura utilizada. Use la configuración '' sabores '' en su secuencia de comandos module build.gradle.
Por ejemplo, puedes intentar hacer algo como esto:
android.productFlavors {
create("arm") {
ndk.with{
abiFilters.add("armeabi")
File curDir = file(''./'')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/"
ldLibs.add(libsDir + "libinterface.so")
}
}
create("armv7") {
ndk.with {
abiFilters.add("armeabi-v7a")
File curDir = file(''./'')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi-v7a/"
ldLibs.add(libsDir + "libinterface.so")
}
}
}
Además, le sugiero que use ''jniLibs'' para almacenar las bibliotecas, porque es la ruta predeterminada para ellas, pero use una carpeta diferente para cada arco.
Puedes consultar otros ejemplos como este .
Espero que esto ayude. Saludos.