2013-08-27 14 views
6

Perché mi appare il seguente errore di linker quando si utilizza clang con libC++:clang ++ -stdlib = libC++ porta a undefined reference

$ clang++ -stdlib=libc++ po.cxx -lpoppler 
/tmp/po-QqlXGY.o: In function `main': 
po.cxx:(.text+0x33): undefined reference to `Dict::lookup(char*, Object*, std::__1::set<int, std::__1::less<int>, std::__1::allocator<int> >*)' 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Dove:

$ nm -D /usr/lib/x86_64-linux-gnu/libpoppler.so | grep lookup | c++filt| grep \ Dict::lookup\(
00000000000c1870 T Dict::lookup(char*, Object*, std::set<int, std::less<int>, std::allocator<int> >*) 

Codice è semplicemente:

#include <poppler/PDFDoc.h> 

int main() 
{ 
    Dict *infoDict; 
    Object obj; 
    infoDict->lookup((char*)"key", &obj); 
    return 0; 
} 

risposta

7

voi secondo errore, dovrebbe essere come si sta cercando di collegare un libC++ con stdlibC++, libC++ e ++ stdlibc è diverso, stdlibC++ è la libreria standard C++ di gcc, esso non compatibili tra loro.

Per il vostro problema, è come il tuo libpoppler.so utilizza stdlibC++, ma nella riga di comando clang, si sta cercando di uso libC++ come lib di serie, hanno nome diverso nel collegare fase, vedi link alla fine di questa risposta per i dettagli perché.

Così, forse la soluzione è solo cambiare il comando di compilazione per

clang++ -stdlib=libstdc++ po.cxx -lpoppler 

Si prega di consultare questa domanda per dettaglio perché std: __ 1 :: set e std :: set.

Why can't clang with libc++ in c++0x mode link this boost::program_options example?

3

Perché libpoppler.so è collegato a GNU stdlibC++. Tutte le parti di un singolo eseguibile devono essere collegate allo stesso standard di C e alle stesse librerie standard di C++.

L'opzione più semplice è semplicemente andare con la libreria standard predefinita. Entrambi ora sono per lo più C++ 11-completi.

In alternativa è possibile creare la versione di libpoppler.so in base a libc++, ma è necessario assegnargli un nome diverso in modo che il linker dinamico trovi quello giusto.

Nella errore di collegamento si può vedere che si riferisce a libpoppler.sostd::set e std::less ecc, ma gli oggetti voler fare riferimento a std::__1::set e std::__1::less ecc Questo è dovuto al fatto GNU stdlibC++ e Clang libC++ approccio delle versioni in modo diverso.

3

Poiché libC++ utilizza uno spazio dei nomi diverso dalla libreria standard GNU C++. Questo errore del linker è una buona cosa perché il layout dei tipi delle due librerie sarà sicuramente diverso per alcuni tipi.

Quindi, ciò significa che la libreria "poppler" è stata costruita contro la libreria std GNU C++, che ha un set di nomi, mentre il compilatore ha utilizzato le dichiarazioni in libC++ per le chiamate di funzione nella traduzione del programma. Pertanto, il linker cerca i simboli negli oggetti (ad esempio la libreria poppler) che hanno il nome libC++ per le dichiarazioni della libreria std, ma non li trova perché non sono stati emessi con lo stesso nome - probabilmente esistono nella libreria di poppler con i nomi GNU.

Naturalmente, probabilmente ti interessa solo come questo può essere risolto: crea sia il tuo programma che la libreria di poppler usando la stessa libreria standard. Se non riesci a creare la libreria di poppler, dovrai aspettare che inviino un binario costruito contro libC++.

Problemi correlati