Statyczne łącze funkcji biblioteki współdzielonej w gcc


138

Jak mogę statycznie połączyć funkcję biblioteki współdzielonej w gcc?


13
Co masz na myśli mówiąc statycznie połączone? Czy chcesz, aby Twój plik wykonywalny był dystrybuowany bez wymagania pliku .so?
Emiliano,

Odpowiedzi:


108

Odnosić się do:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

Aby ją połączyć, potrzebujesz statycznej wersji biblioteki.

Biblioteka współdzielona jest w rzeczywistości plikiem wykonywalnym w specjalnym formacie z określonymi punktami wejścia (i zawiera kilka lepkich problemów z adresowaniem). Nie zawiera wszystkich informacji potrzebnych do statycznego łączenia.

Nie można łączyć statycznie udostępnionej biblioteki (ani dynamicznie łączyć biblioteki statycznej).

Flaga -staticzmusi konsolidator do użycia bibliotek statycznych (.a) zamiast udostępnionych (.so). Jednak biblioteki statyczne nie zawsze są instalowane domyślnie, więc może być konieczne samodzielne zainstalowanie biblioteki statycznej.

Innym możliwym podejściem jest użycie statifier lub Ermine . Oba narzędzia przyjmują jako dane wejściowe dynamicznie połączony plik wykonywalny, a jako dane wyjściowe tworzą samodzielny plik wykonywalny z osadzonymi wszystkimi bibliotekami współdzielonymi.


11
Jakie informacje ma biblioteka statyczna, aby można ją było łączyć statycznie, a których nie ma biblioteka dynamiczna?
kbolino

75

Jeśli chcesz połączyć, powiedzmy, libapplejuice statycznie, ale nie, powiedzmy, liborangejuice , możesz połączyć w ten sposób:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

Jest zastrzeżenie - jeśli liborangejuiceużywa libapplejuice, libapplejuicezostanie również dynamicznie połączony.

Będziesz musiał łączyć się liborangejuicestatycznie wraz z, libapplejuiceaby uzyskać libapplejuicestatyczny.

I nie zapomnij zachować -Wl,-Bdynamic, w przeciwnym razie skończysz łącząc wszystko statyczne, w tym libc(co nie jest dobre do zrobienia).


2
Czy nie ma sposobu, aby bezpośrednio powiedzieć gcc, co ma łączyć statycznie, a nie omijać go i rozmawiać z linkerem?
Elazar Leibovich

1
@ElazarLeibovich nie można w ten sposób uzyskać połączenia statycznego i dynamicznego.
Haozhun

@EugeneBujak: the zastrzeżenie nie ma zastosowania w moim systemie. Przykład: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB używa libA , jest połączona i lddnie pokazuje odniesienia do libA . Plik wykonywalny działa dobrze. Testowany za pomocą g ++ 4.7.3.
radix

Pośrednia (zagnieżdżona), statyczna zależność bezpośredniej, dynamicznej zależności nie jest sama w sobie dynamicznie łączona.
Vinny

Weź pod uwagę następujące kwestie: binA zależy od libB.so, które zależy od libC. A Jak już powiedzieli inni, pliki .so są same w sobie plikami wykonywalnymi, więc kiedy obiekt współdzielony jest linkowany, wszystkie zależności biblioteki statycznej są przetwarzane przez konsolidator tak samo, jak gdyby plik wykonywalny był łączony: jedynymi symbolami pobieranymi z biblioteki statycznej .a są te, do których odwołuje się plik .so. Oznacza to, że jeśli binA odwołuje się do symbolu w libC.a, do którego nie odwołuje się nigdzie w libB.so, to nawet jeśli binA dowiązuje do libB.so, ten symbol będzie niezdefiniowany (chyba że -Wl, - całe archiwum jest używane podczas łączenia libB.so).
Vinny

18

Jeśli masz plik .a swojej biblioteki współdzielonej (.so), możesz po prostu dołączyć go z pełną ścieżką, tak jakby był plikiem obiektowym, na przykład:

To generuje main.o po prostu kompilując:

gcc -c main.c

To łączy ten plik obiektu z odpowiednią biblioteką statyczną i tworzy plik wykonywalny (o nazwie „main”):

gcc main.o mylibrary.a -o main

Lub jednym poleceniem:

gcc main.c mylibrary.a -o main

Może to być również ścieżka bezwzględna lub względna:

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

Tak, wiem, że to pytanie od 8 lat, ale powiedziano mi, że można statycznie łączyć się z biblioteką obiektów współdzielonych i to był dosłownie największy hit, gdy szukałem więcej informacji na jego temat.

Aby wykazać, że rzeczywiście statycznie łączenie biblioteki dzielonego obiektu nie jest możliwe ld( gcc„s łącznik) - w przeciwieństwie do tylko kilka osób, twierdząc, że nie jest to możliwe - użyć następującego gccpolecenia:

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(Oczywiście będziesz musiał skompilować objectname.oz sourcename.c, i prawdopodobnie powinieneś również stworzyć własną bibliotekę obiektów współdzielonych. Jeśli to zrobisz, użyj -Wl,--library-path,., aby ld mógł znaleźć twoją bibliotekę w lokalnym katalogu.)

Rzeczywisty otrzymany błąd to:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

Mam nadzieję, że to pomoże.


10

Trochę późno, ale ... znalazłem link, który zapisałem kilka lat temu i pomyślałem, że może się wam przydać:

CDE: Automatyczne tworzenie przenośnych aplikacji dla systemu Linux

http://www.pgbovine.net/cde.html

  • Wystarczy pobrać program
  • Wykonaj plik binarny, przekazując jako argument nazwę pliku binarnego, który chcesz uczynić przenośnym, na przykład: nmap

    ./cde_2011-08-15_64bit nmap

Program odczyta wszystkie biblioteki dowiązane do nmap i jego elementów zależnych i zapisze je wszystkie w folderze o nazwie cde-package / (w tym samym katalogu, w którym jesteś).

  • Na koniec możesz skompresować folder i wdrożyć przenośny plik binarny w dowolnym systemie.

Pamiętaj, że aby uruchomić przenośny program, musisz uruchomić plik binarny znajdujący się w cde-package / nmap.cde

Z poważaniem


2
Chociaż nie do końca udziela odpowiedzi na pytanie - jest to godne uwagi rozwiązanie problemu.
razong

Wydaje się, że łącze jest teraz martwe.
sinan

0

W gcc nie jest to obsługiwane. W rzeczywistości nie jest to obsługiwane w żadnym istniejącym kompilatorze / konsolidatorze, o którym wiem.


4
Czy możesz wyjaśnić, dlaczego żaden istniejący kompilator nie obsługuje łączenia statycznego?
jww

5
@noloader, statyczne łączenie biblioteki dynamicznej?
nothrow
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.