Search code examples
androidc++candroid-ndkcygwin

How to make error log more detailed about undefined reference to


I need to compile some c/c++ code. Using the tools of NDK and Cygwin, more than one time I have come up with the error "undefined reference to". Most guys said that it is caused by invoking a function whose lib file isn't included in your source file. However, I know little about c/c++, and also the error log gives fuzzy info so I can not know in which file which line cause the problem, not even know which lib file it is that I really need.

My hope is that I find some tools or some ways to deal with problems like this so I can locate the error line or get some more detail about the error.

Thanks a lot.

Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
include ../includeOpenCV.mk
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
#try to load OpenCV.mk from default install location
include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE:=AvatarSpeak
LOCAL_SRC_FILES:=AvatarSpeak.cpp
LOCAL_LDLIBS    := -llog
include $(BUILD_SHARED_LIBRARY)

$NDK/ndk-build V=1

$ $NDK/ndk-build V=1
rm -f ./libs/armeabi/lib*.so ./libs/armeabi-v7a/lib*.so ./libs/mips/lib*.so        ./libs/x86/lib*.so
rm -f ./libs/armeabi/gdbserver ./libs/armeabi-v7a/gdbserver ./libs/mips/gdbserver     ./libs/x86/gdbserver
rm -f ./libs/armeabi/gdb.setup ./libs/armeabi-v7a/gdb.setup ./libs/mips/gdb.setup      ./libs/x86/gdb.setup
Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
mkdir -p ./libs/armeabi
install -p /cygdrive/d/android-ndk-r8b/prebuilt/android-arm/gdbserver/gdbserver   ./libs/armeabi/gdbserver
Gdbsetup       : libs/armeabi/gdb.setup
mkdir -p ./libs/armeabi
echo "set solib-search-path ./obj/local/armeabi" > ./libs/armeabi/gdb.setup
echo "directory D:/android-ndk-r8b/platforms/android-14/arch-arm/usr/include   "../../OpenCV-2.3.1/share/OpenCV/../../include/opencv" "../../OpenCV-    2.3.1/share/OpenCV/../../include" D:/android-ndk-r8b/sources/cxx-stl/gnu-     libstdc++/4.6/include D:/android-ndk-r8b/sources/cxx-stl/gnu-    libstdc++/4.6/libs/armeabi/include jni" >> ./libs/armeabi/gdb.setup
SharedLibrary  : libAvatarSpeak.so
/cygdrive/d/android-ndk-r8b/toolchains/arm-linux-androideabi-     4.6/prebuilt/windows/bin/arm-linux-androideabi-g++  -Wl,-soname,libAvatarSpeak.so  -shared       --sysroot=D:/android-ndk-r8b/platforms/android-14/arch-arm  ./obj/local/armeabi/objs-      debug/AvatarSpeak/com_huawei_avatar_AvatarSpeak.o ./obj/local/armeabi/libopencv_contrib.a       ./obj/local/armeabi/libopencv_calib3d.a ./obj/local/armeabi/libopencv_objdetect.a       ./obj/local/armeabi/libopencv_features2d.a ./obj/local/armeabi/libopencv_video.a      ./obj/local/armeabi/libopencv_imgproc.a ./obj/local/armeabi/libopencv_highgui.a          ./obj/local/armeabi/libopencv_ml.a ./obj/local/armeabi/libopencv_legacy.a     ./obj/local/armeabi/libopencv_flann.a ./obj/local/armeabi/libopencv_core.a        ./obj/local/armeabi/libopencv_androidcamera.a ./obj/local/armeabi/liblibjpeg.a       ./obj/local/armeabi/liblibpng.a ./obj/local/armeabi/liblibtiff.a      ./obj/local/armeabi/liblibjasper.a ./obj/local/armeabi/libzlib.a       ./obj/local/armeabi/libgnustl_static.a    -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-      z,relro -Wl,-z,now  -LD:/android-ndk-r8b/platforms/android-14/arch-arm/usr/lib -llog -lc -           lm  -o obj/local/armeabi/libAvatarSpeak.so
./obj/local/armeabi/objs-debug/AvatarSpeak/AvatarSpeak.o: In function      `Java_com_hachi_avatar_AvatarSpeak_speak':
D:\eclipse_workspace\TestSo/jni/com_hachi_avatar_AvatarSpeak.cpp:52: undefined     reference to `Fap2Avi2D(char const*, char const*, char const*, char const*, char const*,    int)'
collect2: ld returned 1 exit status
/cygdrive/d/android-ndk-r8b/build/core/build-binary.mk:378: recipe for target     `obj/local/armeabi/libAvatarSpeak.so' failed
make: *** [obj/local/armeabi/libAvatarSpeak.so] Error 1

AvatarSpeak.cpp

if (fImage != NULL && fPot != NULL) {

    bool sucavi = Fap2Avi2D(str3, str5, str4, str1, str2, -1);
    LOGI("sucess and exit!");
} else {
    LOGI("unsucess and exit!");
}

Animation2D_new.h(the head file where define the method Fap2Avi2D)

#ifndef ANIMATION_2D_NEW_H_
#define ANIMATION_2D_NEW_H_

#include <vector>
#include <string>
#include "public.h"
#include "FaceExpressionEditor.h"
//#define  __declspec(dllexport)

bool Fap2Avi2D(const char *fap_file,const char *avi_file,const char *wav_file, const   char* image_file,const char *pot_file=NULL,int codec_type=-1);
...

Solution

  • More often than not, "undefined reference" means that your build is misconfigured. For example, an unintended line break in the Android.mk file could cause the make tool choose a wrong link command for your project.

    Usually the error message includes the name of the missing function or global variable, and the module (file) which was looking for this reference. If the name is not self-explanatory, you can often find this name called in your source code, and then track it back to one of the external libraries you use, because it is likely to be declared in some header (.h or .hpp) files included in your source.

    It is not likely that you unintentionally use some external library which you have to download, because usually such mistakes manifest themselves earlier, when the compiler cannot find the necessary include (header) files.

    One particular case for Android native projects to display "undefined reference" errors is when the project uses non-official Android APIs, e.g. OpenMax/stagefreight. In such cases, the header files are found in the Android source tree, but compiled libraries needed for the link phase are not there. The usual workaround is to pull the binaries from your development device, e.g.

    adb pull /system/lib/libstagefreight.so .
    

    Anyways, it often helps to run ndk-build with V=1 to see exactly what build commands are executed.