2010-07-29 8 views
26

Przedtem zawsze uważałem, że kolejność przekazywania obiektów i bibliotek do g ++ podczas etapu łączenia nie jest ważna. Następnie, dzisiaj, starałem się linkować z kodu C++ do kodu c. Zapakowałem wszystkie nagłówki C w zewnętrzny blok "C", ale linker wciąż miał trudności ze znalezieniem symboli, które znałem w archiwach obiektów C.g ++ uzależniając zależność od kolejności przy łączeniu kodu c do kodu C++

Zaskoczony, stworzyłem stosunkowo prosty przykład wyizolowania błędu łączenia, ale ku mojemu zdziwieniu prostszy przykład został połączony bez żadnych problemów.

Po krótkiej próbie i błędzie stwierdziłem, że poprzez emulację wzorca łączenia używanego w prostym przykładzie, mógłbym uzyskać główny kod do połączenia OK. Wzór został pierwszy kod obiektu, obiekt archiwa Drugi przykład:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

Czy ktoś może rzucić nieco światła na dlaczego to może być tak ?. Nigdy nie widziałem tego problemu podczas łączenia zwykłego kodu C++.

+0

Aby uzyskać szczegółowe informacje, patrz: http://stackoverflow.com/questions/1095298/gcc-c-linker-errors- nieokreślona-referencja -to-vtable-for-xxx-undefined-refer/1095321 # 1095321 –

Odpowiedz

35

Kolejność określania plików i bibliotek obiektów jest BARDZO ważna w GCC - jeśli nie zostałeś przez to ukąszony, zanim poprowadzisz zaklęte życie. Łącznik przeszukuje symbole w kolejności, w jakiej się pojawiają, więc jeśli masz plik źródłowy, który zawiera wywołanie funkcji biblioteki, musisz umieścić go przed biblioteką lub linker nie będzie wiedział, że musi go rozwiązać. Skomplikowane korzystanie z bibliotek może oznaczać, że musisz określić bibliotekę więcej niż jeden raz, co jest królewskim bólem, który należy naprawić.

+0

Uwierz mi, nie mam :-), czy jest jakaś dokumentacja na temat tej nieruchomości? –

+0

Tutaj mamy: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html –

+0

Ja też zawsze uważałem, że kolejność linków jest krytyczna; może być trudno zrozumieć, dlaczego pojawiają się błędy linków, dopóki nie zgadniesz, że zamówienie jest błędne ... –

6

Biblioteka statyczna to zbiór plików obiektowych zgrupowanych w archiwum. Łącząc się z nim, linker wybiera tylko te obiekty, które są potrzebne do rozwiązania aktualnie nieokreślonych symboli. Ponieważ obiekty są połączone w kolejności podanej w wierszu poleceń, obiekty z biblioteki będą uwzględniane tylko wtedy, gdy biblioteka znajdzie się za wszystkimi obiektami, które od niej zależą.

Tak więc kolejność linków jest bardzo ważna; jeśli zamierzasz używać bibliotek statycznych, musisz uważać, aby śledzić zależności i nie wprowadzać cyklicznych zależności pomiędzy bibliotekami.

+0

Zależności cykliczne są OK - po prostu oznacza to, że potrzebujesz linii łącza, takiej jak "' ao bo ao' ". – caf

+1

@caf: jeśli dodatkowe obiekty z drugiego włączenia 'a' zależą od obiektów w' b', które nie zostały jeszcze uwzględnione, to nie jest to wystarczająco dobre; na końcu musisz ponownie dodać 'b'. Co z kolei może wprowadzić więcej zależności od 'a'. Zależności cykliczne nie są tak naprawdę "w porządku", rzadko zdarza się, aby były wystarczająco patologiczne, aby wymagały więcej niż jednego powtórzenia. –

17

Kolejność przesyłania bibliotek do gcc/g ++ ma znaczenie. Jeśli A zależy od B, A musi być wymienione jako pierwsze. Powodem jest to, że optymalizuje symbole, do których nie ma odniesienia, więc jeśli najpierw zobaczy bibliotekę, a nikt nie odwołał się do niej w tym miejscu, to w ogóle nie będzie w niej niczego łączył.

0

Można użyć --start grupa archiwa --end grupa i napisać bibliotek zależnych 2 zamiast archiwum

gcc main.o -L. -Wl, - grupa początkowa -lobj_A -lobj_b -Wl, - grupa końcowa