2012-06-20 9 views
6

Próbowałem skompilować mój projekt i dostaję błędy undefined reference. np .:Linked nie może znaleźć symboli, ale biblioteki są odczytywane i istnieją symbole

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

Moje wiersza polecenia jest:

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 pokazuje, że symbole są w pliku .so. np .:

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

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

strace pokazuje, że pliki biblioteczne są otwierane i czytane przez łącznik:

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

Wszystkie pliki związane są kierowane do x86-64 i nagłówek na C bibliotek extern "C" . Próbowałem wszystkiego, co tylko mogę wymyślić i nadal nie będzie się z nim wiązało.

Próbowałem nawet usunąć cały kod C++ 11 i kompilacji bez przełącznika wiersza poleceń, nadal nic.

Mój system jest Ubuntu Precise (12.04) 64-bitowy użyciu g ++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 czy to pomaga. Wszystkie pakiety zostały zainstalowane z menedżera pakietów i zainstalowane są pakiety rozwojowe.

Edit (30.05.2017): Oznaczono jako duplikat https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc
inne pytanie pyta, dlaczego kolejność argumentów jest ważne. Kolejność argumentów nie była znana, gdy zadano pytanie.
Również poprzednie pytanie nie zawiera żadnych przydatnych rozszerzeń, podczas gdy to pytanie pokazuje problem pod ręką.
Poprzednie pytanie może być postrzegane jako pomocna ekspansja w odpowiedzi na to pytanie, ale nie jest to dublowanie.

+0

Cześć, Ben. Czy możesz mi pokazać, jak użyć strace, aby sprawdzić proces. Moja główna trudność polega na tym, jak uzyskać PID, ponieważ proces kompilacji bardzo szybko ginie. Używam tylko ps aux | grep, aby uzyskać PID, ale proces jest już martwy. – William

+0

@XingWang, bez problemu. Po prostu musisz wstawić "strace -f -e trace = all" do linii poleceń. W zależności od systemu może być konieczne dodanie "sudo". Tak więc z mojego przykładu: "strace -f -e trace = all g ++ -o installertest ContractData.o installertest.o" ... –

+0

Możliwy duplikat [Dlaczego kolejność, z którą biblioteki są połączone czasami powoduje błędy w GCC?] (https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-ccc) –

Odpowiedz

9

Musisz wstawić flagi łączników bibliotek po pliki obiektów. Tak więc, zamiast

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 

użytku

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

Po prostu starałem się poprawnie, zadziałało. Naprawdę!? Nie mogę uwierzyć, że to było takie proste. –

+1

Dla każdego, kto napotka na ten problem, oto uzasadnienie. Wygląda na to, że gcc wysyła teraz flagę linkera - potrzebną do ld. Powoduje to odrzucenie określonych bibliotek, które nie mają symboli wymaganych do łączenia. Po pierwsze, wszystkie biblioteki zostały odrzucone, ponieważ w fazie łączenia nie było nierozwiązanych symboli, nie można było znaleźć symboli. W drugiej instancji, ld zebrał listę nierozwiązanych symboli, a następnie znalazł je w określonych bibliotekach i dlatego zachował je, jeśli chodzi o faktyczną fazę łączenia. –

Powiązane problemy