2014-04-19 24 views
5

Sto provando a utilizzare Google Test con NDK Android. A seguito del NDK README example here, ho impostato il mio Android.mk e un singolo test, come di seguito, ma io sto ottenendo questo errore:riferimento non definito a "typeinfo per test :: Test" con Google Test su Android 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  

Ecco quello che so finora:

  • ::testing::Test è la classe di test di Google viene automaticamente suddivisa in sottoclassi dalla macro TEST().
  • Gli errori undefined reference to 'typeinfo for si verificano in genere quando il linker non riesce a trovare la definizione per un metodo virtuale.
  • could be caused by compiling google test with different flags, ma non dovrebbe essere il caso qui poiché sto usando la libreria di test google statico e le bandiere sono le stesse tra i due moduli.

Cosa mi manca? O dove posso guardare dopo? Grazie!

aggiornamento: posso costruire un semplice test di Google che non dipende da nulla come Boost o le API native di Android se mi tolgo la SHARED_LIBRARIES, CPP_FLAGS e LDLIBS dal modulo ndkfoo_unittest.

comando build:

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

Devi mostrare la riga di comando del linker per 'ndkfoo_unittest' da cui proviene l'errore. –

+0

@ MikeKinghan Una cosa sicura. L'ho aggiunto alla domanda. E ho variabili d'ambiente per cose come 'BOOST_INCLUDE_PARENT'. Funzionano correttamente. – mxdubois

+0

Questo non è il comando linker, è il comando 'ndk-build'. Dopo che la compilazione ha compilato i tuoi file sorgente, richiama il linker ('ld') per creare il tuo eseguibile. Abbiamo bisogno della linea di comando 'ld' che genera. Ci stai mostrando un errore di collegamento ma non ci mostra cosa viene collegato. –

risposta

1

Beh, se volete un suggerimento ... basta mantenere le cose semplici. Nel caso in cui tu abbia davvero bisogno di fare un test sul codice nativo C++ usando google test, fallo prima come google test per desktop.

Finora posso dire che, a quanto pare, non è ancora completamente funzionale, almeno non ho trovato alcun materiale valido o tutorial che dimostri che funziona davvero per qualsiasi progetto del mondo reale.

Quello che puoi fare per ora è: usa JUnit con JNI per testare il tuo C++ incorporato nel tuo dispositivo. Questo è il modo in cui funzionerà. Spero che in futuro Google Test diventi davvero funzionante per Android NDK.

Qui trovate ulteriori discussioni su di esso: Unit Tests with NDK.

2

Credo che sia perché non è abilitato RTTI. Prova ad aggiungere

APP_CPPFLAGS += -fexceptions 
APP_CPPFLAGS += -frtti 

a Application.mk. Questo l'ha risolto per me. Secondo la documentazione, si dovrebbe essere in grado di specificare

LOCAL_CPP_FEATURES := rtti exceptions 

in Android.mk, ma che non ha funzionato per me usando NDK R10C. Inoltre, notare che abilitare le eccezioni non è obbligatorio per abilitare RTTI, ma il codice che utilizza RTTI dovrà essere collegato a una libreria standard che supporta RTTI e le librerie con RTTI supportano anche le eccezioni.

0

Ho incontrato lo stesso problema con voi. JIM è corretto, è a causa della RTTI.Per farlo funzionare, devi anche creare il tuo libgtest.a con RTTI abilitato. Puoi aggiungere LOCAL_CFLAGS: = -fexceptions -frtti in Android.MK per gtest e ricostruire il file .a. quindi utilizza il nuovo file .a per creare il tuo progetto. Ho provato e funziona bene per me :)