co to jest ranlib?

13

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ę!

Ying
źródło

Odpowiedzi:

7

ranlibdodaje lub aktualizuje pliki obiektowe w bibliotece statycznej . Łączniki mogą używać bibliotek statycznych podczas łączenia w celu zapewnienia symboli , których kod potrzebuje do działania (w przeciwieństwie do modułu ładującego, który szuka ich w bibliotekach dynamicznych podczas uruchamiania pliku wykonywalnego).

Ignacio Vazquez-Abrams
źródło
Cześć Ignacio, dzięki za odpowiedź. Czy to oznacza, że ​​jeśli uruchomię ranlib na bibliotece, będzie ona dostępna do użycia za każdym razem, gdy linker spróbuje ją „odwołać”? Jak to się usuwa?
Ying,
ranlibsł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 -Li -largumentów gcc szczegóły.
Ignacio Vazquez-Abrams,
5
Ale arteż tego nie robi? Co za różnica?
greatwolf
18

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:

$ ar r fruits.a apple.o orange.o pineapple.o

Potem biegnij

$ ranlib fruits.a

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.

Gość McGuesterson
źródło
„ranlib generuje indeks do zawartości archiwum i przechowuje go w archiwum”. To brzmi bardziej jak coś do połączenia tari powiedziałbym, że nie jest bardzo jasne.
Codebling,
9

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

Albert
źródło
2

ar

W Linuksie arjest to archiwizator ogólnego przeznaczenia GNU. (W arinnych systemach uniksopodobnych istnieją warianty inne niż GNU ). Z opcjąc

ar c... archive-name file...

Tworzy archiwum zawierające kopie file.... archive-nameKonwencjonalnie, ale niekoniecznie ma rozszerzenie .a(do archiwum ). Każdy file...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-namekonwencjonalnie zostanie również nadany prefiks lib, np. libfoo.aTak, że można go wykryć jako plik wejściowy potencjalnego linkera za pomocą opcji linkera -lfoo.

Używany jako plik wejściowy linkera, libfoo.azwykle 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 ​​archiwum libfoo.ajest bardzo podobne do DSO libfoo.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 arprzygotowuje 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łasnym arprzykładzie - a także za pomocą opcji (wielka) S(= brak tablicy symboli ). A jeśli wywołujesz, araby utworzyć lub zaktualizować archiwum, które nie ma (zaktualizowanej) tabeli symboli z jakiegokolwiek powodu, możesz dać jej jedną z sopcją.

ranlib

ranlibw ogóle nie tworzy bibliotek. W systemie Linux ranlibjest starszym programem, który dodaje (aktualizuje) tablicę symboli do ararchiwum, jeśli go nie ma. Jego efekt jest dokładnie taki sam jak ar sw przypadku GNU ar. Historycznie, wcześniej arbył przygotowany do generowania samej tablicy symboli, ranlibbył 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 Unix ranlibmoże być nadal potrzebny do tego celu. Twój przykład:

ar qc libgraphics.a *.o
ranlib libgraphics.a

mówi:

  • Utwórz libgraphics.a, dołączając do archiwum wszystkie *.opliki w bieżącym katalogu, bez tablicy symboli.
  • Następnie dodaj tabelę symboli do libgraphics.a

W Linuksie ma to taki sam efekt netto jak:

ar cr libgraphics.a *.o

Samo ar qc libgraphics.a *.otworzy archiwum, z którego linker nie może korzystać, ponieważ nie ma tablicy symboli.

ld

Twój przykład:

ld -r -o libgraphics.a *.o

jest właściwie dość niekonwencjonalny. To ilustruje dość rzadkie użycie linkera , ldw 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 nie ar archiwum , a określenie wyjściowej nazwy pliku, która wygląda jak nazwa ararchiwum, nie czyni go jednym. Twój przykład ilustruje oszustwo. To:

ld -r -o graphics.o *.o

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.ai jest on wprowadzany do powiązania przez tę nazwę lub przez -lgraphics, linker poprawnie zidentyfikuje go jako plik obiektowy ELF , a nie ararchiwum, 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:

gcc -o prog file.o ... -Ldir ... -lfoo ...

Łączenie DSO:

gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...

Zarówno biblioteki współdzielone, jak i biblioteki statyczne mogą być oferowane konsolidatorowi przez jednolity -lfooprotokół, gdy łączysz jakiś inny program lub DSO. Że opcja kieruje łącznik do skanowania lub jego określonych domyślnych directrories wyszukiwania, aby znaleźć albo libfoo.soalbo libfoo.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 preferowane libfoo.so. Jeśli libfoo.sozostanie wybrane, linker doda ten DSO do listy zależności środowiska wykonawczego dowolnego tworzonego programu lub DSO. Jeśli libfoo.ajest 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 wykonawczego libfoo.asamo 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 .

Royi
źródło