如何在 Android Studio 中为 NDK 构建解决 "undefined reference"?
How to solve "undefined reference" for NDK build in Android Studio?
我在构建 Android 应用程序时遇到 "undefined reference" 错误。我正在使用 JNI 和 NDK。
令我莫名其妙的是,它似乎在我构建 Android 应用程序本身的过程中进行了 NDK 构建。然而,我已经使用命令行构建我的 Android.mk 和 Application.mk 文件来生成所需的库。 Android 应用程序应该做的就是 link 到库并调用它。但即使我对此有误,我也不明白为什么它会抱怨 AILSuperFFT.o 中的错误。这个目标文件已经是我成功构建的库的一部分。我的 Android 应用程序的构建过程不应该知道任何关于 AILSuperFFT.cpp 或其对 Superpowered 库的内部调用的信息。
这是 Android Studio 中的控制台输出。
. . .
:app:compileDebugJavaWithJavac
:app:compileDebugJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:app:compileDebugNdk
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::LinearFFT_Quick(DSPSplitComplex*, int, int, int, FFTDirection, bool)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp:139: undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp:139: undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::FFT2D(DSPSplitComplex*, int, int, FFTDirection)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp:52: undefined reference to `__android_log_print'
collect2: error: ld returned 1 exit status
make: *** [/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libhello-jni.so] Error 1
FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/user1/Documents/NDKDev/android-ndk-r10e/ndk-build'' finished with non-zero exit value 2
BUILD FAILED
消息 window:
中的输出非常相似
:app:incrementalDebugJavaCompilationSafeguard
:app:compileDebugJavaWithJavac
:app:compileDebugJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:app:compileDebugNdk
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::LinearFFT_Quick(DSPSplitComplex*, int, int, int, FFTDirection, bool)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::FFT2D(DSPSplitComplex*, int, int, FFTDirection)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp
Error:(139) undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
Error:(139) undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
Error:(52) undefined reference to `__android_log_print'
Error:error: ld returned 1 exit status
make: *** [/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libhello-jni.so] Error 1
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/user1/Documents/NDKDev/android-ndk-r10e/ndk-build'' finished with non-zero exit value 2
Information:BUILD FAILED
Information:Total time: 5.858 secs
Information:5 errors
根据要求,下面是被投诉的源代码函数调用。请注意,不仅在 Mac 的终端中使用 ndk-build 可以构建此代码并且 link 很好,而且生成的库随后可以在不同的应用程序中毫无问题地使用。我无法说出(还)这两个应用程序之间的区别,但请注意这里的依赖关系:Android 应用程序使用我们的专有库,它在 Superpowered 库中构建和 links .该应用程序只知道库 A 公开的接口,所有这些都在一个应用程序中运行良好。 (我正在构建一个测试应用程序来演示某个问题,这是主应用程序无法完成的)。 Log2() returns 一个整数。
DSPSplitComplex data;
data.imagp=(float *) malloc(sizeof(float)*BUF_SIZE*BUF_SIZE);
data.realp=(float *) malloc(sizeof(float)*BUF_SIZE*BUF_SIZE);
. . . (some code)
DSPSplitComplex *pBuffer = &data;
SuperpoweredFFTComplex(&pBuffer->realp[0]), &(pBuffer->imagp[0]), Log2(length), (direction==kFFTDirection_Forward) ? true : false);
如果您有 JNI 文件并且没有通过将其添加到您的 build.gradle:
中明确关闭自动构建,将尝试进行 ndk 构建
android {
sourceSets.main {
jni.srcDirs = []
}
}
如果您在构建应用程序之前执行的 ndk-build 工作正常,原因很可能是 Gradle 调用的自动 ndk-build 忽略了您的 Android.mk 文件。
我在构建 Android 应用程序时遇到 "undefined reference" 错误。我正在使用 JNI 和 NDK。
令我莫名其妙的是,它似乎在我构建 Android 应用程序本身的过程中进行了 NDK 构建。然而,我已经使用命令行构建我的 Android.mk 和 Application.mk 文件来生成所需的库。 Android 应用程序应该做的就是 link 到库并调用它。但即使我对此有误,我也不明白为什么它会抱怨 AILSuperFFT.o 中的错误。这个目标文件已经是我成功构建的库的一部分。我的 Android 应用程序的构建过程不应该知道任何关于 AILSuperFFT.cpp 或其对 Superpowered 库的内部调用的信息。
这是 Android Studio 中的控制台输出。
. . .
:app:compileDebugJavaWithJavac
:app:compileDebugJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:app:compileDebugNdk
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::LinearFFT_Quick(DSPSplitComplex*, int, int, int, FFTDirection, bool)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp:139: undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp:139: undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::FFT2D(DSPSplitComplex*, int, int, FFTDirection)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp:52: undefined reference to `__android_log_print'
collect2: error: ld returned 1 exit status
make: *** [/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libhello-jni.so] Error 1
FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/user1/Documents/NDKDev/android-ndk-r10e/ndk-build'' finished with non-zero exit value 2
BUILD FAILED
消息 window:
中的输出非常相似:app:incrementalDebugJavaCompilationSafeguard
:app:compileDebugJavaWithJavac
:app:compileDebugJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:app:compileDebugNdk
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::LinearFFT_Quick(DSPSplitComplex*, int, int, int, FFTDirection, bool)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/hello-jni//Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.o: In function `CAILSuperFFT::FFT2D(DSPSplitComplex*, int, int, FFTDirection)':
/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/src/main/jni/sources/AILSuperFFT.cpp
Error:(139) undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
Error:(139) undefined reference to `SuperpoweredFFTComplex(float*, float*, int, bool)'
Error:(52) undefined reference to `__android_log_print'
Error:error: ld returned 1 exit status
make: *** [/Users/user1/Documents/AndroidStudioProjects/hello-jnicpp/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libhello-jni.so] Error 1
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/user1/Documents/NDKDev/android-ndk-r10e/ndk-build'' finished with non-zero exit value 2
Information:BUILD FAILED
Information:Total time: 5.858 secs
Information:5 errors
根据要求,下面是被投诉的源代码函数调用。请注意,不仅在 Mac 的终端中使用 ndk-build 可以构建此代码并且 link 很好,而且生成的库随后可以在不同的应用程序中毫无问题地使用。我无法说出(还)这两个应用程序之间的区别,但请注意这里的依赖关系:Android 应用程序使用我们的专有库,它在 Superpowered 库中构建和 links .该应用程序只知道库 A 公开的接口,所有这些都在一个应用程序中运行良好。 (我正在构建一个测试应用程序来演示某个问题,这是主应用程序无法完成的)。 Log2() returns 一个整数。
DSPSplitComplex data;
data.imagp=(float *) malloc(sizeof(float)*BUF_SIZE*BUF_SIZE);
data.realp=(float *) malloc(sizeof(float)*BUF_SIZE*BUF_SIZE);
. . . (some code)
DSPSplitComplex *pBuffer = &data;
SuperpoweredFFTComplex(&pBuffer->realp[0]), &(pBuffer->imagp[0]), Log2(length), (direction==kFFTDirection_Forward) ? true : false);
如果您有 JNI 文件并且没有通过将其添加到您的 build.gradle:
中明确关闭自动构建,将尝试进行 ndk 构建android {
sourceSets.main {
jni.srcDirs = []
}
}
如果您在构建应用程序之前执行的 ndk-build 工作正常,原因很可能是 Gradle 调用的自动 ndk-build 忽略了您的 Android.mk 文件。