Alyoshak
Alyoshak

Reputation: 2746

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

I am getting an "undefined reference" error building my Android app. I am using JNI and the NDK.

What is inexplicable to me is that it seems to be doing an NDK build during my build of the Android app itself. Yet I've already used the command line to build my Android.mk and Application.mk files to produce the desired library. All the the Android app is supposed to do is link to the library and make calls into it. But even if I'm wrong about this, I don't understand why it is complaining about errors in AILSuperFFT.o. This object file is already a part of the library I successfully built. The build process of my Android app should not know anything about AILSuperFFT.cpp or its internal calls to the Superpowered library.

Here's the Console output in 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

and here is very similar output in the Messages 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

Upon request below is the source code function call that is being complained about. Note that not only does this code build and link fine using ndk-build in Mac's Terminal, but the resulting library is then used without problem in a different app. I am not able to tell (yet) what is the difference between these two apps, but be aware of the dependencies here: Android app uses our proprietary library, which builds and links in the Superpowered lib. The app only knows about the interface exposed by library A, and all of this works fine in one app. (I'm constructing a test app to demonstrate a certain issue, which can't be done with the main app). Log2() returns an 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);

Upvotes: 1

Views: 5616

Answers (1)

Francesca Nannizzi
Francesca Nannizzi

Reputation: 1705

An ndk-build will be attempted if you have JNI files and haven't explicitly turned off the auto-build by adding this to your build.gradle:

android {
    sourceSets.main {
        jni.srcDirs = []
    }
}

If the ndk-build you did prior to building the app worked correctly, the reason is likely that the automated ndk-build called by Gradle ignores your Android.mk file.

Upvotes: 4

Related Questions