Bezpośrednie polecenie gcc, aby statycznie połączyć bibliotekę

138

Wydaje mi się dziwne, że używa się go -Wl,-Bstaticw celu określenia, z gccktórymi bibliotekami chcę łączyć się statycznie. W końcu podam gccbezpośrednio wszystkie inne informacje o linkowaniu z bibliotekami ( -Ldir, -llibname).

Czy można bezpośrednio powiedzieć sterownikowi gcc, które biblioteki powinny być linkowane statycznie?

Wyjaśnienie: wiem, że jeśli pewna biblioteka istnieje tylko w wersjach statycznych, będzie z niej korzystać bez -Wl,-Bstatic, ale chcę zasugerować, gccże wolę bibliotekę statyczną. Wiem również, że bezpośrednie określenie pliku biblioteki będzie się z nim wiązało, ale wolę zachować semantykę obejmującą biblioteki statyczne i dynamiczne.

Elazar Leibovich
źródło

Odpowiedzi:

198

Można oczywiście użyć -l:zamiast -l. Na przykład, -l:libXYZ.aaby połączyć z libXYZ.a. Zwróć uwagę na libwypisane, w przeciwieństwie do tego, -lXYZktóre rozwija się automatycznie do libXYZ.

Radek
źródło
67
Boże, gdyby tylko Gnu uczynił to przede wszystkim domyślnym zamiast szaleństwa przedrostka lib. Och, oszczędzilibyśmy czas i frustrację.
Timmmm
9
Radek, czy ta -l:opcja jest udokumentowana? Której wersji gcc potrzebuję, aby jej użyć?
osgx
19
Właściwie jest to opcja ldlinkera sourceware.org/binutils/docs/ld/Options.html " -l namespec.. Jeśli nazwa_nazwa ma postać: nazwa_pliku, ld przeszuka ścieżkę do biblioteki w celu znalezienia pliku o nazwie nazwa_pliku, w przeciwnym razie przeszuka bibliotekę ścieżka do pliku o nazwie libnamespec.a. .. w systemach ELF .., ld przeszuka katalog w poszukiwaniu biblioteki o nazwie libnamespec.so przed wyszukaniem biblioteki o nazwie libnamespec.a. .. Zauważ, że to zachowanie nie dotyczy: nazwa_pliku , która zawsze określa plik o nazwie nazwa_pliku. ”. Od binutils 2.18 - sourceware.org/binutils/docs-2.18/ld/Options.html
osgx
17
GNU nigdzie nie jest odpowiedzialne za ten interfejs, został odziedziczony z łańcucha narzędzi Unix.
akim
1
Szkoda, że ​​to nie działa w linkerach innych niż GNU. To dobry sposób na „wymuszenie” LDLIBS i podobnych opcji konfiguracyjnych w celu znalezienia bibliotek statycznych bez dziwnych obejść związanych z flagami linków.
nneonneo
133

Możesz dodać plik .a w poleceniu łączenia:

  gcc yourfiles /path/to/library/libLIBRARY.a

Ale to nie jest rozmowa ze sterownikiem gcc, ale z ldlinkerem jako opcjami takimi jak -Wl,anythingsą.

Kiedy powiesz gcc lub ld -Ldir -lLIBRARY, linker sprawdzi zarówno statyczną, jak i dynamiczną wersję biblioteki (możesz zobaczyć proces z -Wl,--verbose). Aby zmienić kolejność zaznaczonych typów bibliotek, możesz użyć -Wl,-Bstatici -Wl,-Bdynamic. Oto strona podręcznika systemowego gnu LD: http://linux.die.net/man/1/ld

Aby połączyć swój program z lib1, lib3 dynamicznie i lib2 statycznie, użyj takiego wywołania gcc:

gcc program.o -llib1 -Wl,-Bstatic -llib2 -Wl,-Bdynamic -llib3

Zakładając, że domyślnym ustawieniem ld jest używanie bibliotek dynamicznych (jest to na Linuksie).

osgx
źródło
3
Wersja skrócona: nie można tego zrobić z prądem gcc.
Elazar Leibovich,
7
Elazar Leibovich, ale załatwia sprawę gcc program.o -llib1 -Wl,-Bstatic -llib2 -Wl,-Bdynamic -llib3.
osgx,
13
Łączenie (i wyszukiwanie bibliotek dyn / static) jest wykonywane przez konsolidator, więc musisz użyć opcji konsolidatora. -li -Lsą również opcjami konsolidatora.
osgx,
3
Czy ta odpowiedź jest przegłosowana z powodu gcc yourfiles /path/to/library/libLIBRARY.alub -Wl,-Bstatic?
Tor Klingberg
8
@TorKlingberg, wariant 1 /path/to/library/libLIBRARY.awymaga pełnej ścieżki do napisania, wariant 2 -Wl,-Bstatic -llib2 -Wl,-Bdynamicjest po prostu długi i dodaje 2 dodatkowe opcje i zakłada domyślny tryb Bdynamic, a zaakceptowany wariant 3 -l:libXYZ.ajest krótki i po prostu działa. Wszystkie trzy będą działać w wielu przypadkach, a wariant 2 może nie działać podczas łączenia programów statycznych. Rzeczywisty krok łączenia dla biblioteki jest taki sam we wszystkich wariantach, jak rozumiem.
osgx