Enlazador de Android: referencia indefinida a bsd_signal

Estoy ejecutando gradlew para compilar una aplicación de Android que tiene una dependencia de gradlew estática. De alguna manera, tengo una referencia indefinida a bsd_signal .

Fui capaz de compilar esta aplicación con gradle 1.X, pero me he visto obligado a cambiar a gradle 2.10 y dejar caer mi archivo Android.mk a favor de poner más instrucciones de construcción en mi archivo gradle.build , y aquí es donde Surge el problema.

¿Puede alguien decirme si hay una biblioteca que define bsd_signal , que debo enlazar a mi proyecto?

Salida del compilador

 Starting process 'command '/home/myself/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++''. Working directory: /home/myself/projects/DroidEar/app Command: /home/myself/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ @/home/myself/projects/DroidEar/app/build/tmp/linkNativeArmeabi-v7aDebugSharedLibrary/options.txt Successfully started process 'command '/home/myself/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++'' /android/ndk/platforms/android-9/arch-arm/usr/include/signal.h:113: error: undefined reference to 'bsd_signal' /android/ndk/platforms/android-9/arch-arm/usr/include/signal.h:113: error: undefined reference to 'bsd_signal' collect2: error: ld returned 1 exit status 

TMI: Aquí está mi archivo gradle.build

 apply plugin: 'com.android.model.application' model { repositories { libs(PrebuiltLibraries) { Superpowered { binaries.withType(StaticLibraryBinary) { def prefix = "src/main/jniLibs/Superpowered" headers.srcDir "${prefix}" if (targetPlatform.getName() == "armeabi-v7a") staticLibraryFile = file("${prefix}/libSuperpoweredAndroidARM.a") else if (targetPlatform.getName() == "arm64-v8a") staticLibraryFile = file("${prefix}/libSuperpoweredAndroidARM64.a") else if (targetPlatform.getName() == "x86_64") staticLibraryFile = file("${prefix}/libSuperpoweredAndroidX86_64.a") else if (targetPlatform.getName() == "X86") staticLibraryFile = file("${prefix}/libSuperpoweredAndroidX86.a") } } } } android { compileSdkVersion = 23 buildToolsVersion = "23.0.3" sources { main { jni { dependencies { library "Superpowered" linkage "static" } } } } ndk { ldLibs.addAll(['log', 'android', 'c']) } defaultConfig { applicationId = "edu.ucdavis.auditoryenhancer" minSdkVersion.apiLevel = 22 targetSdkVersion.apiLevel = 23 versionCode = 1 versionName = "1.0" } } android.ndk { moduleName = "native" } android.buildTypes { release { minifyEnabled = false proguardFiles.add(file("proguard-rules.pro")) } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' } 

Me parece que bsd_signal se define en el componente signal.o de las platforms/android-9/arch-x86/usr/lib/libc.a , pero incluso con mi llamada a ldLibs incluyendo c , obtengo el error.

Hasta el android-19 inclusive NDK-s signal.h declaró bsd_signal extern y la signal era una llamada en línea bsd_signal .

Comenzando con la signal android-21 es un extern y bsd_signal no se declara en absoluto.

Lo que es interesante, bsd_signal todavía estaba disponible como un símbolo en NDK r10e android-21 libc.so (por lo que no hubo errores de enlace si se utiliza r10e ), pero no está disponible en NDK r11 y superior.

La eliminación de bsd_signal de NDK-s android-21 + libc.so resulta en la vinculación de errores si el código construido con android-21 + está vinculado con libs estáticas construidas con niveles inferiores NDK que llaman signal o bsd_signal . La biblioteca más popular que llama a la signal es OpenSSL .

ADVERTENCIA : Construir las librerías estáticas con android-21 + (que pondría signal símbolo de la signal directamente) sería un enlace muy bien, pero resultaría en *.so no cargar en dispositivos Android más antiguos debido al símbolo de signal no encontrado en libc.so .

Por lo tanto, es mejor seguir con <= android-19 para cualquier código que llama signal o bsd_signal .

Para vincular una biblioteca construida con <android-21 terminé declarando un wrapper bsd_signal que llamaría bsd_signal de libc.so (todavía está disponible en libc.so del dispositivo, incluso hasta Android 7.0).

 #if (__ANDROID_API__ > 19) #include <android/api-level.h> #include <android/log.h> #include <signal.h> #include <dlfcn.h> extern "C" { typedef __sighandler_t (*bsd_signal_func_t)(int, __sighandler_t); bsd_signal_func_t bsd_signal_func = NULL; __sighandler_t bsd_signal(int s, __sighandler_t f) { if (bsd_signal_func == NULL) { // For now (up to Android 7.0) this is always available bsd_signal_func = (bsd_signal_func_t) dlsym(RTLD_DEFAULT, "bsd_signal"); if (bsd_signal_func == NULL) { // You may try dlsym(RTLD_DEFAULT, "signal") or dlsym(RTLD_NEXT, "signal") here // Make sure you add a comment here in StackOverflow // if you find a device that doesn't have "bsd_signal" in its libc.so!!! __android_log_assert("", "bsd_signal_wrapper", "bsd_signal symbol not found!"); } } return bsd_signal_func(s, f); } } #endif 

PD. Parece que el símbolo bsd_signal será devuelto a libc.so en NDK r13 :

https://github.com/android-ndk/ndk/issues/160#issuecomment-236295994

Esta es la rotura ABI en el Android NDK. Las bibliotecas / binarios construidos con un NDK pre-android-21 usando la señal () no funcionarán con android-21 o posterior. Y a la inversa. Este boleto de Rust tiene una explicación más detallada: https://github.com/rust-lang/libc/issues/236#issuecomment-198774409

También hay este ticket para el Android NDK: https://github.com/android-ndk/ndk/issues/48

  • Cómo importar el proyecto android como biblioteca y NO compilarlo como apk (Android studio 1.0)
  • Android: Error al convertir byte a dex
  • No se puede resolver el símbolo 'AndroidJUnit4'
  • Uso de Proguard para eliminar clases no utilizadas en la biblioteca de Servicios de Google Play
  • El caché de dependencias de Gradle puede estar dañado
  • Android: La ejecución falló para la tarea ': app: processDebugResources'
  • Creación de Gradle no obtener dependencia del repositorio personalizado de maven
  • Problema con gradle experimental: El plugin android debe ser aplicado al proyecto
  • Android: el paquete está en conflicto con un paquete existente con el mismo nombre
  • ¿Cómo puedo mostrar los archivos de registro, System.out.println (), en la prueba de Android?
  • Problemas incluyendo Apache HttpComponents en el proyecto de Android Gradle
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.