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.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)
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With