Od jakiegoś czasu korzystam z systemu MacOSX, ale dopiero niedawno zacząłem grzebać w brzuchu. Znalazłem przewodnik z poleceniem uruchomienia „sudo ranlib /usr/local/lib/libjpeg.a” (instalowanie libjpeg). Przeczytałem instrukcję ranlib i próbowałem na niej szukać online. Po prostu nie rozumiem. Jakie zasoby muszę wyszukać, aby dowiedzieć się więcej, czy ktoś może udzielić zwięzłego wyjaśnienia na temat jego wykorzystania? Z góry dziękuję!
13
ranlib
służy do tworzenia i modyfikowania bibliotek. Korzystanie z nich zależy od linkera, zwykle poprzez przekazanie lokalizacji biblioteki i / lub nazwy w wierszu poleceń. Patrz-L
i-l
argumentów gcc szczegóły.ar
też tego nie robi? Co za różnica?Ten opis wygląda dość jasno: http://sourceware.org/binutils/docs/binutils/ranlib.html
Jeśli więc zarchiwizujesz zbiór plików obiektowych, powiedz:
Potem biegnij
tworzy indeks zawartości owoców. a i przechowuje indeks w owocach. a. Jest to przydatne do łączenia i na wypadek, gdyby obiekty się nawzajem wywoływały.
źródło
tar
i powiedziałbym, że nie jest bardzo jasne.ranlib generuje indeks do zawartości archiwum i przechowuje go w archiwum. Indeks zawiera każdy symbol zdefiniowany przez członka archiwum będącego przemieszczalnym plikiem obiektowym. Archiwum z takim indeksem przyspiesza łączenie z biblioteką i pozwala na nawiązywanie połączeń między procedurami w bibliotece bez względu na ich umiejscowienie w archiwum.
źródło: strona man ranlib
źródło
ar
W Linuksie
ar
jest to archiwizator ogólnego przeznaczenia GNU. (War
innych systemach uniksopodobnych istnieją warianty inne niż GNU ). Z opcjąc
Tworzy archiwum zawierające kopie
file...
.archive-name
Konwencjonalnie, ale niekoniecznie ma rozszerzenie.a
(do archiwum ). Każdyfile...
może być dowolnym plikiem, niekoniecznie plikiem obiektowym.Gdy wszystkie zarchiwizowane pliki są plikami obiektowymi, zwykle intencją jest użycie archiwum do dostarczenia tego wyboru plików obiektowych do połączenia programów lub DSO (dynamiczne obiekty współdzielone). W tym przypadku
archive-name
konwencjonalnie zostanie również nadany prefikslib
, np.libfoo.a
Tak, że można go wykryć jako plik wejściowy potencjalnego linkera za pomocą opcji linkera-lfoo
.Używany jako plik wejściowy linkera,
libfoo.a
zwykle nazywany jest biblioteką statyczną . Takie użycie jest nieustannym źródłem zamieszania dla niedoświadczonych programistów, ponieważ prowadzi ich do myślenia, że archiwumlibfoo.a
jest bardzo podobne do DSOlibfoo.so
, zwykle nazywanego biblioteką dynamiczną / współdzieloną , i do budowania fałszywych oczekiwań na tej podstawie. W rzeczywistości „biblioteka statyczna” i „biblioteka dynamiczna” wcale nie są do siebie podobne i są używane w łączeniu na zupełnie różne sposoby.Wyraźną różnicą jest to, że linker nie tworzy biblioteki statycznej , lecz
ar
. Tak więc nie dochodzi do powiązania, nie występuje rozdzielczość symboli. Zarchiwizowane pliki obiektowe pozostają niezmienione: są po prostu wkładane do torby.Kiedy archiwum jest wprowadzane do połączenia czegoś, co jest tworzone przez linker - takiego jak program lub DSO - linker szuka w torbie, aby sprawdzić, czy są w nim jakieś pliki obiektów, które zawierają definicje nierozwiązanych odniesień symboli, które się zgromadziły wcześniej w powiązaniu. Jeśli je znajdzie, wyodrębnia te pliki obiektowe z worka i łączy je z plikiem wyjściowym, dokładnie tak, jakby zostały nazwane indywidualnie w linii poleceń programu łączącego, a archiwum w ogóle nie wspomniano. Cała rola archiwum w łączeniu polega na tym, że jako zbiór plików obiektowych łącznik może wybrać te, które musi wykonać łączenie.
Domyślnie GNU
ar
przygotowuje archiwa wyjściowe do użycia jako dane wejściowe linkera. Dodaje fałszywy „plik” do archiwum z magiczną fałszywą nazwą pliku, aw tym fałszywym pliku zapisuje zawartość, którą linker może odczytać jako tabelę odnośników z globalnych symboli, które są zdefiniowane przez dowolne pliki obiektowe w archiwum do nazw i pozycji tych plików obiektowych w archiwum. Ta tabela odnośników umożliwia konsolidatorowi przeglądanie archiwum i identyfikowanie plików obiektowych, które definiują wszelkie nierozstrzygnięte odwołania do symboli, które ma pod ręką.Możesz pominąć tworzenie lub aktualizowanie tej tabeli odnośników za pomocą opcji
q
(= szybka ) - której tak naprawdę użyłeś we własnymar
przykładzie - a także za pomocą opcji (wielka)S
(= brak tablicy symboli ). A jeśli wywołujesz,ar
aby utworzyć lub zaktualizować archiwum, które nie ma (zaktualizowanej) tabeli symboli z jakiegokolwiek powodu, możesz dać jej jedną zs
opcją.ranlib
ranlib
w ogóle nie tworzy bibliotek. W systemie Linuxranlib
jest starszym programem, który dodaje (aktualizuje) tablicę symboli doar
archiwum, jeśli go nie ma. Jego efekt jest dokładnie taki sam jakar s
w przypadku GNUar
. Historycznie, wcześniejar
był przygotowany do generowania samej tablicy symboli,ranlib
był kludge, który wstrzyknął magiczny fałszywy plik do archiwum, aby umożliwić linkerowi wybranie z niego plików obiektowych. W systemach operacyjnych innych niż GNU Unixranlib
może być nadal potrzebny do tego celu. Twój przykład:mówi:
libgraphics.a
, dołączając do archiwum wszystkie*.o
pliki w bieżącym katalogu, bez tablicy symboli.libgraphics.a
W Linuksie ma to taki sam efekt netto jak:
Samo
ar qc libgraphics.a *.o
tworzy archiwum, z którego linker nie może korzystać, ponieważ nie ma tablicy symboli.ld
Twój przykład:
jest właściwie dość niekonwencjonalny. To ilustruje dość rzadkie użycie linkera ,
ld
w celu utworzenia scalonego pliku obiektowego poprzez połączenie wielu plików wejściowych w jeden plik obiektowy wyjściowy, w którym rozdzielenie symboli zostało wykonane w miarę możliwości , biorąc pod uwagę pliki wejściowe. Opcja-r
(= relocatable ) nakazuje konsolidatorowi utworzenie obiektu docelowego pliku obiektowego (a nie programu lub DSO) poprzez połączenie danych wejściowych tak daleko, jak to możliwe i nie zawiedzie linkaqe, jeśli w pliku wyjściowym pozostaną niezdefiniowane odwołania do symboli. Takie użycie nazywa się częściowym łączeniem .Plik wyjściowy to plik
ld -r ...
obiektowy, a niear
archiwum , a określenie wyjściowej nazwy pliku, która wygląda jak nazwaar
archiwum, nie czyni go jednym. Twój przykład ilustruje oszustwo. To:byłoby zgodne z prawdą. Nie jest dla mnie jasne, jaki może być cel takiego oszustwa, ponieważ nawet jeśli wywoływany jest plik obiektowy ELF
libgraphics.a
i jest on wprowadzany do powiązania przez tę nazwę lub przez-lgraphics
, linker poprawnie zidentyfikuje go jako plik obiektowy ELF , a niear
archiwum, i zużyje go tak, jak zużywa dowolny plik obiektowy w wierszu poleceń: łączy go bezwarunkowo z plikiem wyjściowym, podczas gdy celem wprowadzenia prawdziwego archiwum jest połączenie członków archiwum tylko pod warunkiem, że są do nich odniesienia . Być może masz tutaj przykład nieuczciwego linkowania.Podsumowanie ...
Właściwie widzieliśmy tylko jeden sposób na stworzenie czegoś, co jest tradycyjnie nazywane biblioteką , a jest to tak zwana biblioteka statyczna , poprzez archiwizację niektórych plików obiektów i umieszczenie tablicy symboli w archiwum.
I w ogóle nie widzieliśmy, jak stworzyć inną i najważniejszą rzecz, która jest tradycyjnie nazywana biblioteką , a mianowicie dynamiczny obiekt współdzielony / biblioteka współdzielona / biblioteka dynamiczna.
Linker tworzy DSO, podobnie jak program . Program i DSO to warianty pliku binarnego ELF, które moduł ładujący systemu rozumie i może wykorzystać do złożenia uruchomionego procesu. Zazwyczaj możemy wywołać poprzez jeden łącznik jednej z nakładki GCC (
gcc
,g++
,gfortran
, etc):Łączenie programu:
Łączenie DSO:
Zarówno biblioteki współdzielone, jak i biblioteki statyczne mogą być oferowane konsolidatorowi przez jednolity
-lfoo
protokół, gdy łączysz jakiś inny program lub DSO. Że opcja kieruje łącznik do skanowania lub jego określonych domyślnych directrories wyszukiwania, aby znaleźć albolibfoo.so
albolibfoo.a
. Domyślnie, gdy znajdzie którykolwiek z nich, wprowadzi ten plik do powiązania, a jeśli znajdzie oba w tym samym katalogu wyszukiwania, będzie to preferowanelibfoo.so
. Jeślilibfoo.so
zostanie wybrane, linker doda ten DSO do listy zależności środowiska wykonawczego dowolnego tworzonego programu lub DSO. Jeślilibfoo.a
jest zaznaczone, linker używa archiwum jako zbioru plików obiektowych do połączenia z plikiem wyjściowym, jeśli to konieczne, tam i teraz. Brak zależności od środowiska wykonawczegolibfoo.a
samo jest możliwe; nie można go zmapować na proces; to nic nie znaczy dla modułu ładującego system operacyjny.Skopiowano z https://stackoverflow.com/a/47924864/195787 .
źródło