Istnieją 2 argumenty przemawiające za udostępnianiem bibliotek:
- Pomaga zmniejszyć miejsce na dysku.
- Gdy biblioteka współdzielona jest aktualizowana, wszystkie pliki binarne zależne od niej otrzymują aktualizację.
Główną wadą bibliotek współdzielonych jest:
- Mogą (mogą) wprowadzić piekło zależności.
Na komputerach stacjonarnych pierwsza przewaga już nie istnieje. Marnowanie miejsca na dysku nie stanowi obecnie większego problemu.
Posiadanie statycznych plików binarnych pozwoliłoby nam uzyskać znacznie lepsze menedżery pakietów - to znaczy, że piekło zależności byłoby już przeszłością. Dodanie programu byłoby po prostu dodaniem pliku binarnego; ostatecznie folder, który pozwoli mu obsługiwać swoje pliki. Usunięcie programu byłoby po prostu usunięciem tego pliku. Zależności? Odszedł.
Druga zaleta wciąż pozostaje, ale myślę, że przewaga statycznych plików binarnych na komputerach stacjonarnych przeważa nad nią. Mam na myśli, że nawet nowe języki, takie jak Go, kompilują wszystkie swoje pliki binarne pomimo zalet bibliotek współdzielonych ze względu na wygodę.
Ponieważ jedna z głównych zalet bibliotek współdzielonych nie jest już niczym wielkim, czy biblioteki statyczne w C wciąż są niezadowolone? Jeśli tak, to dlaczego?
Odpowiedzi:
Przesłanka twojego pytania jest błędna. To, co jest niezadowolone, to trzymanie się doktrynerów i absolutów bez zrozumienia podstaw, które się za nimi kryją (Cargo Cult Programming?).
Powiązana odpowiedź SO jest interesującym badaniem w tym właśnie temacie - pytanie dotyczyło tego, dlaczego kompilacja z opcją -static nie działa, a odpowiedź, z którą się łączyłeś, była niczym innym, jak rantem o niestosowaniu łączenia statycznego. Jeśli nie dyskutuje, dlaczego jest zły, i żąda OP używa dynamicznego linkowania. To niefortunne, że jest oznaczona jako poprawna odpowiedź (następująca odpowiedź ma dwa razy więcej głosów i jest prawidłową odpowiedzią na pytanie PO), ponieważ chociaż prawidłowa odpowiedź istnieje, jest głęboko ukryta w dogmatycznej opinii.
Prawdziwe pytanie brzmi: jakie są zalety i wady łączenia statycznego vs. dynamicznego i kiedy jeden z nich byłby preferowany.
źródło
Z punktu widzenia dewelopera dynamiczne linkowanie może często znacznie przyspieszyć twoją pętlę kompilacji / linku / testu.
Z punktu widzenia zarządzania pakietami, na przykład libGL. Mam około tuzina różnych jego implementacji dostępnych w moim menedżerze pakietów, niektóre ogólne i niektóre ukierunkowane na określone karty graficzne. Gdyby nie było dynamicznie powiązane, musiałoby istnieć kilkanaście wersji każdego programu, który łączy się z libGL, w przeciwnym razie musiałbyś opracować dodatkową warstwę abstrakcji, która nie byłaby tak skuteczna jak wywołanie funkcji.
Pomyśl o problemie bezpieczeństwa w popularnej bibliotece, takiej jak Qt. Dzięki dynamicznemu łączeniu mogę po prostu zaktualizować ten pakiet, zamiast identyfikować, rekompilować i wdrażać każdy pojedynczy pakiet, który łączy się w Qt.
Łączenie statyczne może mieć zalety w niezależnie wdrażanych aplikacjach zamkniętych źródeł, ale w zarządzaniu pakietami open source boli bardziej niż pomaga.
źródło
Biblioteki współdzielone są zdecydowanie preferowane przez opiekunów dystrybucji Linuksa z twojego powodu # 2. Jest to dla nich bardzo ważne, że na przykład, gdy ktoś znajdzie błąd bezpieczeństwa w Zlib , nie musi przekompilować każdego programu korzystającego z Zlib - nie tylko kosztowałoby to więcej cykli procesora rekompilując, każdy, kto użyje dystrybucji, będzie musiał ponownie pobrać wszystkie te programy. Tymczasem w zestawie pakietów dostarczanych przez dystrybucję piekło zależności nie jest problemem, ponieważ wszystko jest testowane pod kątem współpracy z tym zestawem bibliotek.
Jeśli budujesz oprogramowanie innej firmy, które potrzebuje bibliotek, których nie ma w Twojej dystrybucji, statyczne łączenie tych bibliotek może być mniej kłopotliwe niż alternatywa, i to w porządku.
Inną ważną rzeczą, o której należy wiedzieć, jest to, że GNU
libc
i GCClibstdc++
zawierają składniki, które nie działają niezawodnie, jeśli biblioteka jest statycznie połączona. Najczęstszym problemem jestdlopen
, ponieważ z każdym ładowanym modułemdlopen
jest on dynamicznie powiązanylibc.so.6
. Oznacza to, że teraz masz dwie kopie biblioteki C w swojej przestrzeni adresowej, a przezabawność pojawia się, gdy nie zgadzają się, która kopia wewnętrznejmalloc
struktury danych (na przykład) jest autorytatywna. Jest coraz gorzej: cała masa funkcji, które wydają się nie mieć nic wspólnego zdlopen
, jakgethostbyname
iiconv
używaniedlopen
wewnętrznie (aby ich zachowanie można było skonfigurować w środowisku wykonawczym). Na szczęście ABI dla libc i libstdc ++ jest bardzo stabilny, więc prawdopodobnie nie napotkasz problemów dynamicznie łączących je.źródło
Zgadzam się z ostatnim punktem Mattnza: to pytanie jest pytaniem pełnym. Zakłada, że statyczne łączenie jest złe. Mogę wymyślić dwa powody, dla których tak nie jest:
Łączenie statyczne jest bezpieczne: jeśli biblioteka współdzielona zostanie zaktualizowana w taki sposób, że aplikacja korzysta z nowej (być może nowa zastąpi starą lub stara zostanie usunięta), może to stwarzać ryzyko, że nowa wersja zepsuje aplikację. Jest to zmiana kodu poza zakresem oficjalnej aktualizacji aplikacji. Być może nie został przetestowany. Łączenie statyczne omija to, nie udostępniając bibliotek zewnętrznie. Uważam, że ze względu na to ryzyko jest to niekorzystne dla bibliotek współdzielonych. Co jeśli nowa wersja biblioteki współdzielonej wprowadza nowy błąd, który psuje niektóre starsze aplikacje?
Łączenie statyczne zapewnia, że aplikacja jest bardziej samodzielna. Chociaż biblioteki współdzielone mogą być kolokowane przy użyciu głównego pliku wykonywalnego, często są one zdeponowane we wspólnych lokalizacjach. Statycznie połączone aplikacje są łatwiejsze do zapewnienia jako „przenośne” w znaczeniu „nie wymagającym zmian w plikach, katalogach lub ustawieniach należących do systemu operacyjnego” (pomyśl katalog Windows, rejestr itp.).
źródło
Biblioteki statyczne i dynamiczne mają swoje własne zastosowania. Patrząc na zakres pojedynczej aplikacji, mamy inne wyobrażenie o tym, co jest konieczne, a co nie.
Łączenie statyczne znacznie upraszcza wdrażanie aplikacji. Nie trzeba wykrywać różnych wersji i radzić sobie z nimi. Po prostu upiecz i rozprowadź.
Oczywistą zaletą bibliotek dynamicznych jest możliwość niezależnego stosowania aktualizacji.
Jest to jeden z powodów, dla których nienawidzę maven i innych podobnych twórców dynamicznych linków do java. Oczekują, że jedna wersja biblioteki będzie dostępna pod danym adresem URL na zawsze. Nie rozumiem problemu, który pojawia się za 10 lat, kiedy nikt nie może skompilować aplikacji, ponieważ wszystkie źródła i słoiki zniknęły.
źródło
FooLib1.8
powinny mieć możliwości włączenia kodu dla tej biblioteki do swojego pakietu wykonywalnego w standardowy sposób, aby umożliwić narzędzie aktualizacji dostarczane zFooLib1.9
aktualizacją lub wersją starszą? Sposób, w jaki kod był przechowywany w klasycznym komputerze Macintosh, byłby bardzo łatwy; czy jest jakiś powód, dla którego dzisiejsze systemy nie powinny być w stanie tego zrobić jeszcze lepiej?