Я получаю ошибку «неопределенная ссылка» при создании приложения для Android. Я использую JNI и NDK.
Что мне необъяснимо, так это то, что он, кажется, выполняет сборку NDK во время моей сборки самого приложения для Android. Тем не менее, я уже использовал командную строку для создания своих файлов Android.mk и Application.mk для создания желаемой библиотеки. Все, что должно делать приложение для Android, — это ссылаться на библиотеку и совершать звонки в нее. Но даже если я ошибаюсь по этому поводу, я не понимаю, почему он жалуется на ошибки в 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 1FAILED
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
По запросу ниже приведен вызов функции из исходного кода, на который жалуются. Обратите внимание, что этот код не только хорошо строится и связывается с помощью ndk-build в терминале Mac, но и полученная библиотека без проблем используется в другом приложении. Я не могу сказать (пока), в чем разница между этими двумя приложениями, но помните о зависимостях здесь: приложение Android использует нашу проприетарную библиотеку, которая собирает и связывает в Superpowered 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);
Будет предпринята попытка ndk-сборки, если у вас есть файлы JNI и вы не отключили автоматическую сборку явно, добавив это в свой build.gradle:
android {
sourceSets.main {
jni.srcDirs = []
}
}
Если ndk-сборка, которую вы делали до сборки приложения, работала правильно, вероятно, причина в том, что автоматическая ndk-сборка, вызванная Gradle, игнорирует ваш файл Android.mk.
Других решений пока нет …