如何解决安卓工作室中NDK构建"undefined reference"问题?

How to solve "undefined reference" for NDK build in Android Studio?

本文关键字:构建 NDK undefined reference 问题 工作室 何解决 解决      更新时间:2023-10-16

我会收到一个"未定义的参考"错误构建我的Android应用程序。我正在使用JNI和NDK。

对我来说,莫名其妙的是,在我构建Android应用程序本身时,它似乎正在做NDK构建。但是,我已经使用了命令行来构建我的android.mk和application.mk文件来生成所需的库。所有的Android应用程序都应该做的就是链接到库并拨打库。但是,即使对此我错了,我也不明白为什么它在ailsuperfft.o中抱怨错误。这个对象文件已经是我成功构建的库的一部分。我的Android应用程序的构建过程不应了解ailsuperfft.cpp或其对超能力库的内部调用。

这是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

,这是消息窗口中非常相似的输出:

: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构建和链接,而且随后在另一个应用程序中使用了最终的库。我还无法()()()这两个应用程序之间有什么区别,但是请注意此处的依赖性:Android应用程序使用我们的专有库,该库在超级能力的LIB中构建和链接。该应用只知道库A所曝光的接口,并且所有这些都可以在一个应用程序中工作。(我正在构建一个测试应用程序来演示某个问题,而主应用程序无法完成)。log2()返回int。

    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-build:
android {
    sourceSets.main {
        jni.srcDirs = []
    }
}

如果您在构建应用程序之前进行的NDK构建工作正常工作,那么Gradle调用的自动化NDK构建的原因很可能会忽略您的android.mk文件。