2014-04-19 11 views
5

Próbuję użyć Google Test z Android NDK. Po NDK README example here, mam skonfigurować Android.mk i jeden test jak poniżej, ale ja dostaję ten błąd:Nieokreślone odniesienie do "typeinfo for testing :: Test" z Google Test na Androida NDK

./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  

Oto, co wiem do tej pory:

  • ::testing::Test jest klasa testów Google automatycznie podklasyfikowana w makrze TEST().
  • undefined reference to 'typeinfo for Błędy pojawiają się zwykle, gdy linker nie może znaleźć definicji dla metody wirtualnej.
  • could be caused by compiling google test with different flags, ale nie powinno tak być w tym przypadku, ponieważ używam statycznej biblioteki testowej google, a flagi są takie same między tymi dwoma modułami.

Czego mi brakuje? Lub gdzie mogę spojrzeć dalej? Dzięki!

zmiana: mogę zbudować prosty Google test, który nie zależy od niczego podobnego podwyższenie lub Android natywnych API Jeśli usunąć SHARED_LIBRARIES, CPP_FLAGS i LDLIBS z ndkfoo_unittest modułu.

Budowa polecenie:

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) 
+0

Musisz nam pokazać wiersz komend dla 'ndkfoo_unittest', z którego wynika błąd. –

+0

@MikeKinghan Pewnie. Dodałem go do pytania. I mam zmienne środowiskowe dla rzeczy takich jak 'BOOST_INCLUDE_PARENT'. Działają poprawnie. – mxdubois

+0

To nie jest polecenie linkera, to polecenie 'ndk-build'. Po kompilacji kompilacji plików źródłowych wywołuje linker ('ld'), aby utworzyć plik wykonywalny. Potrzebujemy wiersza polecenia 'ld', który generuje. Pokazujesz nam błąd połączenia, ale nie pokazuje nam, co jest połączone. –

Odpowiedz

1

Cóż, jeśli chcesz sugestię ... po prostu zachować rzeczy proste. W przypadku, gdy naprawdę musisz wykonać test na natywnym kodzie C++ za pomocą testu Google, zrób to jako test google na komputer.

Jak dotąd mogę stwierdzić, najwyraźniej nie jest to jeszcze w pełni funkcjonalny - przynajmniej nie znalazłem żadnej wartości materiału lub samouczek pokazujący, że naprawdę działa dla każdego projektu na świecie.

Co możesz teraz zrobić, to: użyj JUnit z JNI, aby przetestować swoje C++ w swoim urządzeniu. Tak właśnie będzie działać. Mam nadzieję, że w przyszłości test Google naprawdę zadziała dla Androida NDK.

Tutaj znajdziesz dalszą dyskusję na ten temat: Unit Tests with NDK.

2

Uważam, że dzieje się tak, ponieważ nie masz włączonego interfejsu RTTI. Spróbuj dodać:

do Application.mk. To rozwiązało to dla mnie. Zgodnie z dokumentacją, powinieneś być w stanie określić

LOCAL_CPP_FEATURES := rtti exceptions 

w Android.mk, ale to nie działa dla mnie za pomocą NDK R10C. Należy również zauważyć, że włączenie wyjątków nie jest obowiązkowe w przypadku włączania RTTI, ale kod korzystający z RTTI będzie musiał łączyć się ze standardową biblioteką obsługującą RTTI, a biblioteki z RTTI obsługują wyjątki.

0

Spotykam ten sam problem z tobą. Jim jest poprawny, to z powodu RTTI.Aby to działało, musisz także zbudować bibliotekę libgtest.a z włączoną usługą RTTI. Możesz dodać LOCAL_CFLAGS: = -fexceptions -frtti w Android.MK dla gtest i odbudować plik .a. następnie użyj nowego pliku .a, aby zbudować swój projekt. Próbowałem i to działa dobrze dla mnie. :)

Powiązane problemy