我正在运行 gradlew
来编译一个具有静态库依赖项的 Android 应用程序。不知何故,我对 bsd_signal
有一个 undefined reference 。
我能够使用 gradle 1.X 编译这个应用程序,但我不得不切换到 gradle 2.10 并删除我的 Android.mk
文件以支持将更多构建指令放入我的 gradle.build
文件,这就是问题所在。
谁能告诉我是否有定义 bsd_signal
的库,我应该将其链接到我的项目?
编译器输出
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:这是我的 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'
}
在我看来,bsd_signal
是在 platforms/android-9/arch-x86/usr/lib/libc 的
,但即使我的 signal.o
组件中定义的.aldLibs
调用上面包含 c
,我也会收到错误。
最佳答案
直到 android-19 包含 NDK-s signal.h
声明 bsd_signal
extern 和 signal
是一个内联调用bsd_signal
。
以 android-21 开头的 signal
是一个 extern 而 bsd_signal
根本没有声明。
有趣的是,bsd_signal
在 NDK r10e android-21 libc.so
中仍可用作符号(因此没有链接错误如果使用 r10e),但在 NDK r11 及更高版本中不可用。
从 NDK-s android-21+ libc.so
中删除 bsd_signal
如果使用 android 构建的代码会导致链接错误-21+ 与调用 signal
或 bsd_signal
的较低 NDK 级别构建的静态库链接。调用 signal
的最流行的库是 OpenSSL。
警告:使用 android-21+ 构建那些静态库(这会直接放置 signal
符号)会很好地链接,但会导致在 *.so
中,由于在他们的 libc.so
中找不到 signal
符号,无法在较旧的 Android 操作系统设备上加载。
因此,对于任何调用 signal
或 bsd_signal
的代码,最好坚持使用 <=android-19。
为了链接一个用 bsd_signal
包装器,它将从 libc 调用
(它在设备的 bsd_signal
.solibc.so
中仍然可用,甚至到 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
附言。看起来 bsd_signal
符号将被带回 NDK r13 中的 libc.so
:
https://github.com/android-ndk/ndk/issues/160#issuecomment-236295994
关于安卓链接器 : undefined reference to bsd_signal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36746904/