2012-06-20 9 views
6

Ich habe versucht, mein Projekt zu kompilieren, und ich bekomme undefined reference Fehler. zB .:Verbunden kann Symbole nicht finden, aber Bibliotheken werden gelesen und Symbole existieren

installertest.cpp:(.text+0x9d1): undefined reference to `XmlRpcValue::makeArray()' 
... 
installertest.cpp:(.text+0xede): undefined reference to `dbcancel' 
installertest.cpp:(.text+0xefd): undefined reference to `dbfcmd' 
installertest.cpp:(.text+0xf0f): undefined reference to `dbsqlexec' 
installertest.cpp:(.text+0xf2d): undefined reference to `SHA1_Init' 
... 

Meine Befehlszeile ist:

g++ -o installertest \ 
    -lsybdb \ 
    -lxmlrpc \ 
    -lxmlrpc_cpp \ 
    -lxmlrpc_xmlparse \ 
    -lxmlrpc_xmltok \ 
    -lxmlrpc_util \ 
    -lxmlrpc++ \ 
    -lxmlrpc_server_cgi \ 
    -lssl \ 
    -std=c++0x \ 
    ContractData.o installertest.o 

objdump -T zeigt, dass die Symbole in der .so-Datei sind. zB .:

libsybdb.so: 
... 
0000000000011c30 g DF .text 0000000000000083 Base  dbcancel 
... 

/usr/lib/libxmlrpc_cpp.so: 
... 
0000000000002e78 g DF .text 0000000000000092 Base  _ZN11XmlRpcValue9makeArrayEv 
... 

strace zeigt, dass die Bibliotheksdateien geöffnet werden, und durch den Linker zu lesen:

... 
[pid 5019] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libsybdb.so", {st_mode=S_IFREG|0644, st_size=421608, ...}) = 0 
[pid 5019] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libsybdb.so", O_RDONLY) = 7 
[pid 5019] fcntl(7, F_GETFD)   = 0 
[pid 5019] fcntl(7, F_SETFD, FD_CLOEXEC) = 0 
[pid 5019] fstat(7, {st_mode=S_IFREG|0644, st_size=421608, ...}) = 0 
[pid 5019] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16c200c000 
[pid 5019] lseek(7, 0, SEEK_SET)  = 0 
[pid 5019] read(7, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\0\0\0\0\0\0"..., 4096) = 4096 
... 
[pid 5019] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libxmlrpc.so", {st_mode=S_IFREG|0644, st_size=80936, ...}) = 0 
[pid 5019] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libxmlrpc.so", O_RDONLY) = 8 
[pid 5019] fcntl(8, F_GETFD)   = 0 
[pid 5019] fcntl(8, F_SETFD, FD_CLOEXEC) = 0 
[pid 5019] fstat(8, {st_mode=S_IFREG|0644, st_size=80936, ...}) = 0 
[pid 5019] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16c200d000 
[pid 5019] lseek(8, 0, SEEK_SET)  = 0 
[pid 5019] read(8, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300?\0\0\0\0\0\0"..., 4096) = 4096 
... 

Alle Dateien werden gezielt eingebunden x86-64 und den Header für die C-Bibliotheken sind extern "C" . Ich habe alles versucht, woran ich denken kann, und es wird immer noch nicht verlinken.

Ich habe sogar versucht, alle C++ 11 Code zu entfernen und kompilieren ohne den Befehlszeilenschalter, immer noch nichts.

Mein System ist Ubuntu Precise (12.04) 64-Bit- mit g ++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 ob das hilft. Alle Pakete wurden vom Paketmanager installiert und die Entwicklungspakete wurden installiert.

Edit (2017.05.30): Markiert als Duplikat https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc
Frage fragt, warum Reihenfolge der Argumente wichtig ist. Die Argumentationsreihenfolge war bei der Frage nicht bekannt.
Auch die vorherige Frage enthält keine hilfreiche Erweiterung, während diese Frage zeigt das Problem zur Hand.
Vorherige Frage kann als eine hilfreiche Erweiterung auf die Antwort zu diesem, aber nicht eine Vervielfältigung gesehen werden.

+0

Hallo, Ben. Könnten Sie mir bitte zeigen, wie man mit dem strace den Prozess überprüft? Meine Hauptschwierigkeit besteht darin, wie man die PID bekommt, da der Kompilierprozess sehr schnell abklingt. Ich benutze nur die ps aux | grep um die PID zu bekommen, aber der Prozess ist schon tot. – William

+0

@XingWang, kein Problem. Sie müssen einfach "strace -f -e trace = all" der Befehlszeile voranstellen. Abhängig von Ihrem System müssen Sie möglicherweise auch "sudo" hinzufügen. Also, von meinem Beispiel: "strace -f -e trace = alle g ++ -o installlertest ContractData.o installertest.o" ... –

+0

Mögliche Duplikate von [Warum verursacht die Reihenfolge, in der Bibliotheken verknüpft sind, manchmal Fehler in GCC?] (https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-omethesimes-cause-errors-in-gcc) –

Antwort

9

Sie müssen die Linker-Flags der Bibliotheken nach die Objektdateien setzen. Anstatt also

g++ -o installertest \ 
-lsybdb \ 
-lxmlrpc \ 
-lxmlrpc_cpp \ 
-lxmlrpc_xmlparse \ 
-lxmlrpc_xmltok \ 
-lxmlrpc_util \ 
-lxmlrpc++ \ 
-lxmlrpc_server_cgi \ 
-lssl \ 
-std=c++0x \ 
ContractData.o installertest.o 

Verwendung

g++ -o installertest \ 
ContractData.o installertest.o \ 
-lsybdb \ 
-lxmlrpc \ 
-lxmlrpc_cpp \ 
-lxmlrpc_xmlparse \ 
-lxmlrpc_xmltok \ 
-lxmlrpc_util \ 
-lxmlrpc++ \ 
-lxmlrpc_server_cgi \ 
-lssl \ 
-std=c++0x 
+0

Nur richtig versucht, arbeitete. Ja wirklich!? Ich kann nicht glauben, dass es so einfach war. –

+1

Für jeden, der auf dieses Problem kommt, hier ist die Begründung. Es sieht so aus, als ob gcc jetzt das Linker-Flag - wie benötigt - an ld sendet. Dies hat zur Folge, dass alle angegebenen Bibliotheken verworfen werden, die keine für die Verknüpfung erforderlichen Symbole enthalten. In der ersten Instanz wurden alle Bibliotheken verworfen, da es keine ungelösten Symbole gab, dann konnten die Symbole in der Verknüpfungsphase nicht gefunden werden. In der zweiten Instanz hatte ld die Liste der nicht aufgelösten Symbole gesammelt und dann in den angegebenen Bibliotheken gefunden und sie daher behalten, wenn es um die eigentliche Verknüpfungsphase ging. –

Verwandte Themen