Jak mogę statycznie łączyć tylko niektóre określone biblioteki z moim plikiem binarnym podczas łączenia z GCC?
gcc ... -static ...
próbuje łączyć statycznie wszystkie połączone biblioteki, ale nie mam statycznej wersji niektórych z nich (np .: libX11).
gcc
linker
static-libraries
peoro
źródło
źródło
Odpowiedzi:
gcc -lsome_dynamic_lib code.c some_static_lib.a
źródło
code.c
plikiem gwarantuje, że symbole w niej będą ignorowane, chyba żemain()
funkcja w jednej z bibliotek plików obiektowych.Możesz także użyć
ld
opcji-Bdynamic
Wszystkie biblioteki po nim (w tym biblioteki systemowe połączone automatycznie przez gcc) zostaną połączone dynamicznie.
źródło
możesz także użyć:
-static-libgcc -static-libstdc++
flagi dla bibliotek gccpamiętaj, że jeśli
libs1.so
ilibs1.a
oba istnieją, konsolidator wybierze,libs1.so
czy jest przed,-Wl,-Bstatic
czy po-Wl,-Bdynamic
. Nie zapomnij przejść-L/libs1-library-location/
przed zadzwonieniem-ls1
.źródło
-static
gdzieś w poleceniu kończy się niepowodzeniem (zakładam, że próbuje połączyć więcej rzeczy statycznie niż tylko wybrane biblioteki).-Wl,-Bstatic
i-Wl,-Bdynamic
jest ważna.Ze strony podręcznika
ld
(to nie działa z gcc), odnosząc się do--static
opcji:Jednym z rozwiązań jest umieszczenie dynamicznych zależności przed
--static
opcją w wierszu poleceń.Inną możliwością jest nieużywanie
--static
, ale podanie pełnej nazwy pliku / ścieżki do statycznego pliku obiektowego (tj. Nieużywanie opcji -l) do statycznego łączenia określonej biblioteki. Przykład:Jak widać w przykładzie,
libX11
nie ma go na liście dynamicznie połączonych bibliotek, ponieważ został połączony statycznie.Uwaga:
.so
plik jest zawsze linkowany dynamicznie, nawet jeśli jest określony pełną nazwą pliku / ścieżką.źródło
ldd a.out
?ldd
wyświetla wymagane biblioteki współdzielone, a libX11 nie pojawia się na tej liście.Jak rozumiem, problem jest następujący. Masz kilka bibliotek, niektóre statyczne, niektóre dynamiczne, a niektóre zarówno statyczne, jak i dynamiczne. Domyślnym zachowaniem gcc jest linkowanie „głównie dynamiczne”. Oznacza to, że gcc łączy się z bibliotekami dynamicznymi, jeśli jest to możliwe, ale w przeciwnym razie wraca do bibliotek statycznych. Kiedy używasz opcji -static do gcc zachowanie polega na połączeniu tylko bibliotek statycznych i zakończeniu z błędem, jeśli nie można znaleźć żadnej biblioteki statycznej, nawet jeśli istnieje odpowiednia biblioteka dynamiczna.
Inną opcją, którą przy kilku okazjach życzyłem sobie, by gcc był, jest to, co nazywam - głównie statyczne i zasadniczo jest przeciwieństwem opcji -dynamic (domyślna). -mostly-static wolałoby, gdyby istniało, łączyć się z bibliotekami statycznymi, ale wracałoby do bibliotek dynamicznych.
Ta opcja nie istnieje, ale można ją emulować za pomocą następującego algorytmu:
Konstruowanie wiersza poleceń łącza bez włączania -static .
Powtarzaj opcje łącza dynamicznego.
Gromadzenie ścieżek bibliotek, tj. Tych opcji postaci -L <katalog_lib> w zmiennej <ścieżka_lib>
Dla każdej opcji dowiązania dynamicznego, tj. Tych w postaci -l <nazwa_biblioteki> , uruchom komendę gcc <ścieżka_lib> -print-file-name = lib <nazwa_biblioteki> .a i przechwyć wynik.
Jeśli polecenie wydrukuje coś innego niż to, co przekazałeś, będzie to pełna ścieżka do biblioteki statycznej. Zastąp opcję biblioteki dynamicznej pełną ścieżką do biblioteki statycznej.
Płucz i powtarzaj, aż przetworzysz cały wiersz poleceń łącza. Opcjonalnie skrypt może również pobrać listę nazw bibliotek, które mają być wyłączone z łączenia statycznego.
Poniższy skrypt bash wydaje się działać:
Na przykład:
w moim systemie zwraca:
lub z wykluczeniem:
Otrzymuję wtedy:
źródło
Istnieje również
-l:libstatic1.a
(bez l dwukropka) wariant opcji -l w gcc, który może być użyty do połączenia biblioteki statycznej (dzięki https://stackoverflow.com/a/20728782 ). Czy to jest udokumentowane? Nie ma w oficjalnej dokumentacji gcc (co nie jest dokładne w przypadku bibliotek współdzielonych): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlDokument binutils ld opisuje to.
-lname
Opcja zrobi poszukiwanialibname.so
następnie przezlibname.a
dodanie prefiksu lib i.so
(jeśli jest włączona w tej chwili) lub.a
przyrostek. Ale-l:name
opcja wyszuka tylko dokładnie podaną nazwę: https://sourceware.org/binutils/docs/ld/Options.htmlWariant
-l:namespec
jest udokumentowany od wersji binutils 2.18 (2007): https://sourceware.org/binutils/docs-2.18/ld/Options.htmlźródło
Niektóre programy ładujące (konsolidatory) zapewniają przełączniki do włączania i wyłączania dynamicznego ładowania. Jeśli GCC działa na takim systemie (Solaris - i być może inne), możesz użyć odpowiedniej opcji.
Jeśli wiesz, które biblioteki chcesz łączyć statycznie, możesz po prostu określić plik biblioteki statycznej w wierszu dowiązania - za pomocą pełnej ścieżki.
źródło
aby połączyć bibliotekę dynamiczną i statyczną w jednym wierszu, należy umieścić biblioteki statyczne po bibliotekach dynamicznych i plikach obiektowych, na przykład:
gcc -lssl main.o -lFooLib -o main
w przeciwnym razie to nie zadziała. zajmuje mi trochę czasu, zanim to wymyślę.
źródło