Utilizzo della libreria statica di Crypto ++ in un progetto QT

Ho sviluppato cryptopp staticamente sul mio sistema e anche tutti i test. Questi sono gli avvertimenti che ricevo durante i test

WARNING: CRYPTOPP_NO_UNALIGNED_DATA_ACCESS is not defined in config.h. WARNING: CRYPTOPP_INIT_PRIORITY is not defined in config.h. WARNING: CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 is defined in config.h. WARNING: You should make these changes in config.h, and not CXXFLAGS. WARNING: You can 'mv config.recommend config.h', but it breaks versioning. WARNING: See http://cryptopp.com/wiki/config.h for more details. 

Ora collego questo nel mio file di progetto QT come

 TEMPLATE = app LIBS += -L/usr/lib/libcryptopp.a #LIBS += -lcryptopp CONFIG += console c++11 CONFIG += staticlib SOURCES += main.cpp \ hashdata.cpp HEADERS += \ hashdata.hpp 

Ma quando compilo, ottengo tutti gli errori non definiti.

 hashdata.o: In function `hashdata::hashfunction(std::string)': hashdata.cpp:(.text+0x1fb): undefined reference to `CryptoPP::Algorithm::Algorithm(bool)' hashdata.cpp:(.text+0x270): undefined reference to `CryptoPP::SHA512::InitState(unsigned long long*)' hashdata.cpp:(.text+0x29a): undefined reference to `CryptoPP::Algorithm::Algorithm(bool)' hashdata.cpp:(.text+0x2a1): undefined reference to `vtable for CryptoPP::StringSinkTemplate' hashdata.cpp:(.text+0x30b): undefined reference to `CryptoPP::Filter::Filter(CryptoPP::BufferedTransformation*)' hashdata.cpp:(.text+0x312): undefined reference to `vtable for CryptoPP::Grouper' hashdata.cpp:(.text+0x35e): undefined reference to `CryptoPP::Filter::Detach(CryptoPP::BufferedTransformation*)' hashdata.cpp:(.text+0x375): undefined reference to `CryptoPP::Filter::Filter(CryptoPP::BufferedTransformation*)' hashdata.cpp:(.text+0x37c): undefined reference to `vtable for CryptoPP::BaseN_Encoder' hashdata.cpp:(.text+0x3d3): undefined reference to `CryptoPP::Filter::Detach(CryptoPP::BufferedTransformation*)' hashdata.cpp:(.text+0x3e5): undefined reference to `CryptoPP::ProxyFilter::ProxyFilter(CryptoPP::BufferedTransformation*, unsigned long, unsigned long, CryptoPP::BufferedTransformation*)' hashdata.cpp:(.text+0x3ec): undefined reference to `vtable for CryptoPP::HexEncoder' hashdata.cpp:(.text+0x452): undefined reference to `vtable for CryptoPP::AlgorithmParametersTemplate' hashdata.cpp:(.text+0x4af): undefined reference to `vtable for CryptoPP::AlgorithmParametersTemplate' ... 

Ho visto un problema simile in precedenza quando ho cercato su google, ma la soluzione non è chiara. Potrebbe essere a causa di flag C ++ 11?

Ho sviluppato cryptopp staticamente sul mio sistema e anche tutti i test. Questi sono gli avvertimenti che ricevo durante i test

ATTENZIONE: CRYPTOPP_NO_UNALIGNED_DATA_ACCESS non è definito in config.h. ATTENZIONE: CRYPTOPP_INIT_PRIORITY non è definito in config.h. ATTENZIONE: CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 è definito in config.h. ATTENZIONE: dovresti apportare queste modifiche in config.h e non in CXXFLAGS. ATTENZIONE: puoi ‘mv config.recommend config.h’, ma interrompe il controllo delle versioni. ATTENZIONE: vedi http://cryptopp.com/wiki/config.h per maggiori dettagli.

Posso commentare questo avviso. Dovresti eseguire i passaggi che dice:

 mv config.recommend config.h 

config.recommend mette la libreria in una migliore configurazione, evitando completamente comportamenti noti indefiniti che non possono essere rimossi senza interrompere il controllo delle versioni. Dal momento che non sembra che ci siano problemi di versioning (come dire, Fedora o Debian), allora puoi eseguire la mossa.


Ora collego questo nel mio file di progetto QT come

 TEMPLATE = app LIBS += -L/usr/lib/libcryptopp.a #LIBS += -lcryptopp CONFIG += console c++11 ... 

Quando costruisci Crypto ++, dovresti usare lo stesso compilatore e gli stessi flag per la libreria e l’app. Suggerisco quanto segue

Crypto ++ :

 # Be sure to 'mv config.recommend config.h' export CXXFAGS="-DNDEBUG -g2 -O3 -std=c++11" make static dynamic test 

App Qt

 # main.pro file QMAKE_CXXFLAGS += -DNDEBUG -g2 -O3 

Vedi anche GNUmafile | Costruire la libreria sul wiki di Crypto ++.


 hashdata.o: In function `hashdata::hashfunction(std::string)': hashdata.cpp:(.text+0x1fb): undefined reference to `CryptoPP::Algorithm::Algorithm(bool)' hashdata.cpp:(.text+0x270): undefined reference to `CryptoPP::SHA512::InitState(unsigned long long*)' ... 

Questi provengono da file sorgente ( *.cpp ). Sto indovinando (ed è solo una supposizione) uno dei due problemi:

  • C ++ 03 vs C ++ 11 sta causando simboli mancanti
  • QT Creator non sta utilizzando libcryptopp.a

Utilizzare nm per ispezionare i simboli. Qualcosa di simile al seguente (la “T” ti dice che è definito e nella sezione di testo):

 $ nm libcryptopp.a 2>/dev/null | c++filt | \ grep 'Algorithm::Algorithm(bool)' | grep ' T ' 0000000000000060 T CryptoPP::Algorithm::Algorithm(bool) 0000000000000070 T CryptoPP::Algorithm::Algorithm(bool) 

Se i simboli sono presenti da QT Creator non trova la libreria di Crypto ++, quindi vedi qualcosa come Aggiungere una libreria esterna nel progetto Qt Creator .


Dai commenti :

-lcryptopp funziona, ma non so perché -L/usr/lib/libcryptopp.a no. … Perché se una persona avesse sia librerie statiche che dinamiche, non so ancora come forzare il collegamento di quelle statiche.

Un archivio, come libcryptopp.a , è una raccolta di file object. Lo aggiungi a OBJECTS , non a LIBS , quindi desideri qualcosa come :

 # main.pro file OBJECTS += /usr/lib/libcryptopp.a 

Si utilizza -L per specificare un percorso di libreria per un linker. Non ha molto senso usare -L/usr/lib/libcryptopp.a dato che è usato per i percorsi.


Nota aggiuntiva: quando erano presenti sia le librerie statiche che quelle dinamiche, collegava automaticamente la lib dynamic. Sai come forzare il collegamento statico?

Su Linux, puoi forzare il collegamento statico con (1) -Bstatic -lcryptopp ; o (2) specificando direttamente /usr/lib/libcryptopp.a . Il programma di test di Crypto ++ utilizza il metodo (2) :

 g++ main.cpp /usr/lib/libcryptopp.a -o main.exe 

Su OS X, il linker si collega sempre all’object dinamico. Lo fa anche su iOS, dove userland di solito non è autorizzato a caricare oggetti dinamici. Per evitare il collegamento dinamico, (1) sposta o rinomina il *.dylib ; o (2) specificando direttamente /usr/lib/libcryptopp.a . Il programma di test di Crypto ++ utilizza il metodo (2) :

 g++ main.cpp /usr/lib/libcryptopp.a -o main.exe