Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

undefined reference to 'typeinfo for testing::Test' with Google Test on Android NDK

I'm trying to use Google Test with the Android NDK. Following the NDK README example here, I've set up my Android.mk and a single test as below, but I'm getting this error:

./obj/local/armeabi/objs-debug/ndkfoo_unittest/FilteredPriorityQueue_test.o:FilteredPriorityQueue_test.cpp:function typeinfo for mashbot::FilteredPriorityQueueTest_ShouldRetrieveTop_Test: error: undefined reference to 'typeinfo for testing::Test'
collect2: error: ld returned 1 exit status
make: *** [obj/local/armeabi/ndkfoo_unittest] Error 1    

Here's what I know so far:

  • ::testing::Test is the Google Test class automatically subclassed by the TEST() macro.
  • undefined reference to 'typeinfo for errors usually occur when the linker can't find the definition for a virtual method.
  • could be caused by compiling google test with different flags, but shouldn't be the case here since I'm using the static google test library and the flags are the same between the two modules.

What am I missing? Or where can I look next? Thanks!

update: I can build a simple Google Test that does not depend on anything like Boost or the Android native apis if I remove the SHARED_LIBRARIES, CPP_FLAGS, and LDLIBS from the ndkfoo_unittest module.

Build command:

ndk-build SHELL=/bin/bash NDK_DEBUG=1

FilteredPriorityQueue_test.cpp:

#include "gtest/gtest.h"

// FilteredPriorityQueue is a header-only file with no virtual methods.
#include "FilteredPriorityQueue.h"

// So is Comparator.
#include "Comparator.h"

struct MaskedObject {
    int mMask;
    MaskedObject(int mask) : mMask(mask) { }
    int getMask() const { return mMask; }
    bool operator<(const MaskedObject& rhs) const {
           return this->mMask < rhs.mMask;
    }
};

typedef
FilteredPriorityQueue<int, MaskedObject, Comparator<MaskedObject> > TestQueue;

TEST(FilteredPriorityQueueTest,ShouldRetrieveTop) {
    Comparator<MaskedObject> comparator(Comparator<MaskedObject>::LESS);
    TestQueue q(comparator);
    q.push(1, MaskedObject(1));
    q.push(2, MaskedObject(2));
    q.push(4, MaskedObject(4));
    EXPECT_EQ( 1, q.top().getMask() );
}

Android.mk:

# ndkfoo module
#-------------------------
LOCAL_MODULE    := ndkfoo

LOCAL_CPPFLAGS := -frtti -pthread -fexceptions -std=c++11
LOCAL_LDLIBS   += -lOpenSLES -llog -landroid

LOCAL_C_INCLUDES += $(LIBMASHBOT_ROOT)/include
LOCAL_C_INCLUDES += $(BOOST_INCLUDE_PARENT)

LOCAL_SHARED_LIBRARIES += mashbot \
        gnustl_shared \
        boost_thread-gcc-mt-1_53 \
        boost_system-gcc-mt-1_53 \
        $(BOOST_LIB)

LOCAL_SRC_FILES := ndkfoo.cpp \
        #...more files...

include $(BUILD_SHARED_LIBRARY)


# ndkfoo tests module
#-------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := ndkfoo_unittest

LOCAL_CPPFLAGS := -frtti -pthread -fexceptions -std=c++11

LOCAL_C_INCLUDES += $(BOOST_INCLUDE_PARENT)

LOCAL_STATIC_LIBRARIES := googletest_main
LOCAL_SHARED_LIBRARIES += ndkfoo \
        gnustl_shared \
        $(BOOST_LIB)

LOCAL_SRC_FILES := FilteredPriorityQueue_test.cpp

include $(BUILD_EXECUTABLE)

# this imports $NDK/sources/third_party/googletest/Android.mk
 $(call import-module,third_party/googletest)
like image 452
mxdubois Avatar asked Oct 21 '22 09:10

mxdubois


2 Answers

I believe it's because you don't have RTTI enabled. Try adding

APP_CPPFLAGS += -fexceptions
APP_CPPFLAGS += -frtti

to Application.mk. That solved it for me. According to the documentation, you should be able to specify

LOCAL_CPP_FEATURES := rtti exceptions

in Android.mk, but that did not work for me using NDK r10c. Also, note that enabling exceptions is not mandatory for enabling RTTI, but code that uses RTTI will have to link against a standard library supporting RTTI, and the libraries with RTTI also support exceptions.

like image 170
Jim Reesman Avatar answered Oct 23 '22 09:10

Jim Reesman


Well if you want a suggestion... just keep things simple. In the case you really need to make a test on C++ native code using google test, do it first as google test for desktop.

So far I can tell, apparently it is not really fully functional yet - at least I didn't find any worth material or tutorial showing that it really works for any real world project.

What you can do for now is: use JUnit with JNI to test your C++ embedded in your device. That's the way is going to work. I hope in the future google test really get working for Android NDK.

Here you find further discussion on it: Unit Tests with NDK.

like image 35
Wong Tan Avatar answered Oct 23 '22 08:10

Wong Tan