что такое ранлиб?

13

Я уже давно пользуюсь системой MacOSX, но только недавно начал разбираться в ней. Я нашел руководство, в котором говорилось, что нужно запустить 'sudo ranlib /usr/local/lib/libjpeg.a'(install libjpeg). Я прочитал руководство по ranlib и попытался найти его в Интернете. Я просто не понимаю. Какие ресурсы мне нужно найти, чтобы узнать больше, или кто-то может дать краткое объяснение по его использованию? Заранее спасибо!

Ин
источник

Ответы:

7

ranlibдобавляет или обновляет объектные файлы в статической библиотеке . Linkers может использовать статические библиотеки , когда связь с тем , чтобы обеспечить символы , что потребности кода для того , чтобы работать (в отличие от погрузчика ищет их в динамических библиотеках при запуске исполняемого файла).

Игнасио Васкес-Абрамс
источник
Привет Игнасио, спасибо за ответ. Означает ли это, что если я выполню ranlib в библиотеке, она будет доступна для использования каждый раз, когда компоновщик пытается «ссылаться» на нее? Как это удалить?
Ин
ranlibиспользуется для создания и изменения библиотек. Их может использовать компоновщик, обычно передавая местоположение библиотеки и / или имя в командной строке. Смотрите -Lи -lаргументы НКУ для деталей.
Игнасио Васкес-Абрамс
5
Но разве это не arтак? Какая разница?
greatwolf
18

Это описание выглядит довольно ясно: http://sourceware.org/binutils/docs/binutils/ranlib.html

Поэтому, если вы архивируете коллекцию объектных файлов, скажите:

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

Потом работает

$ ranlib fruits.a

создает индекс содержимого fruits.a и сохраняет индекс в fruits.a. Это полезно для связи и в случае, если объекты вызывают друг друга.

Гость МакГестерсон
источник
msgstr "ranlib генерирует индекс содержимого архива и сохраняет его в архиве". Это больше похоже на то, с чем нужно сочетаться, tarи я бы сказал, не очень понятно.
Codebling
9

ranlib генерирует индекс содержимого архива и сохраняет его в архиве. В индексе перечислены все символы, определенные участником архива, который является перемещаемым объектным файлом. Архив с таким индексом ускоряет соединение с библиотекой и позволяет подпрограммам в библиотеке вызывать друг друга независимо от их размещения в архиве.

источник: страница руководства ranlib

Альберт
источник
2

Арканзас

В Linux arGNU является архиватором общего назначения. (Существуют не-GNU варианты arв других Unix-подобных ОС). С возможностьюc

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

Создает архив, содержащий копии file.... archive-nameОбычно , но не обязательно имеет расширение .a(для архива ). Каждый file...может быть любым видом файла, не обязательно объектным файлом.

Когда заархивированными файлами являются все объектные файлы, обычно предполагается использовать архив для доставки этого набора объектных файлов в связывание программ или DSO (динамических общих объектов). В этом случае archive-nameтакже будет условно задан префикс lib, например libfoo.a, чтобы он мог быть обнаружен в качестве входного файла-компоновщика-кандидата с помощью опции компоновщика -lfoo.

Используется как входной файл компоновщика, libfoo.aобычно называется статической библиотекой . Такое использование является постоянным источником путаницы для неопытных программистов, потому что это заставляет их думать, что архив libfoo.a- это то же самое, что DSO libfoo.so, обычно называемый динамической / разделяемой библиотекой , и строить ложные ожидания на этой основе. Фактически, «статическая библиотека» и «динамическая библиотека» совсем не похожи и используются в связях совершенно по-разному.

Заметным отличием является то, что статическая библиотека создается не компоновщиком , а с помощью ar. Так что никакой связи не происходит, никакого разрешения символов не происходит. Архивные объектные файлы остаются без изменений: они просто помещаются в сумку.

Когда архив вводится в связи с чем - то , что это производится с помощью линкера - например, программы или DSO - линкер выглядит в сумке , чтобы увидеть , если есть какие - объектные файлы в нем , которые обеспечивают определения для неразрешенных ссылок символов , которые накопились ранее в связи. Если он находит какие-либо файлы, он извлекает эти объектные файлы из пакета и связывает их в выходной файл, точно так же, как если бы они были названы индивидуально в командной строке компоновщика, а архив вообще не упомянут. Таким образом, вся роль архива в связывании заключается в том, что он представляет собой пакет объектных файлов, из которых компоновщик может выбрать те, которые ему нужны для связывания.

По умолчанию GNU arготовит свои выходные архивы для использования в качестве входных данных компоновщика. Он добавляет в архив фальшивый «файл» с волшебным фальшивым именем файла и в этом фальшивом файле записывает содержимое, которое компоновщик может прочитать как справочную таблицу из глобальных символов, которые определены любыми объектными файлами в архиве. на имена и позиции этих объектных файлов в архиве. Эта таблица поиска позволяет компоновщику просматривать архив и идентифицировать любые объектные файлы, которые определяют любые неразрешенные ссылки на символы, которые он получил.

Вы можете запретить создание или обновление этой справочной таблицы с помощью опции q(= quick ), которую вы фактически использовали в своем собственном arпримере, а также с опцией (заглавной) S(= без таблицы символов ). И если вы вызываете arдля создания или обновления архива, который по какой-либо причине не имеет (обновленной) таблицы символов, то вы можете дать ему одну с sопцией.

ranlib

ranlibне создает библиотеки вообще. В Linux ranlibэто устаревшая программа, которая добавляет (обновляет) таблицу символов в arархив, если у нее ее нет. Эффект такой же, как ar sи с GNU ar. Исторически сложилось так, что до того, как arбыл создан сам для создания таблицы символов, ranlibбыл kludge, который вставлял магический фальшивый файл в архив, чтобы компоновщик мог выбрать объектные файлы из него. В Unix-подобных ОС, отличных от GNU, ranlibдля этой цели все еще может понадобиться. Ваш пример:

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

говорит:

  • Создайте libgraphics.a, добавив в архив все *.oфайлы в текущем каталоге, без таблицы символов.
  • Затем добавьте таблицу символов в libgraphics.a

В Linux это имеет тот же чистый эффект, что и:

ar cr libgraphics.a *.o

Сам по себе ar qc libgraphics.a *.oсоздает архив, который компоновщик не может использовать, поскольку у него нет таблицы символов.

л.д.

Ваш пример:

ld -r -o libgraphics.a *.o

на самом деле довольно неортодоксально. Это иллюстрирует достаточно редкое использование линкера , ldдля получения объединенного файла объекта путем объединения нескольких входных файлов в один выходной файл объект, в котором разрешение символа было сделано , насколько это возможно , учитывая входные файлы. Опция -r(= relocatable ) указывает компоновщику создать целевой объектный файл (а не программу или DSO), связывая входные данные насколько это возможно, и не прерывать ссылку, если в выходном файле остаются неопределенные ссылки на символы. Такое использование называется частичным связыванием .

Выходной файл ld -r ... является объектным файлом, а не ar архивом , и указание выходного имени файла, которое выглядит как файл arархива, не делает его одним. Итак, ваш пример иллюстрирует обман. Эта:

ld -r -o graphics.o *.o

было бы правдивым. Мне непонятно, какова цель такого обмана, потому что даже если объектный файл ELF вызывается libgraphics.aи вводится в связь либо по этому имени, либо через -lgraphicsкомпоновщик, он правильно идентифицирует его как объектный файл ELF. , а не arархив, и будет использовать его так же, как он использует любой объектный файл в командной строке: он безоговорочно связывает его с выходным файлом, тогда как смысл ввода подлинного архива состоит в том, чтобы связывать элементы архива только при условии, что на них есть ссылки . Возможно, у вас просто есть пример плохо информированных ссылок здесь.

Завершение ...

На самом деле мы видели только один способ создания чего-то, что обычно называется библиотекой , и это создание так называемой статической библиотеки , путем архивирования некоторых объектных файлов и помещения таблицы символов в архив.

И мы вообще не видели, как создать другую и самую важную вещь, которая обычно называется библиотекой , а именно: динамический общий объект / общая библиотека / динамическая библиотека.

Как и программа, DSO создается компоновщиком . Программа и DSO являются вариантами двоичного файла ELF, который загрузчик ОС понимает и может использовать для сборки запущенного процесса. Обычно мы вызываем линкер через один один из GCC фронтэндов ( gcc, g++, gfortranи т.д.):

Связывание программы:

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

Связывание DSO:

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

Как общие библиотеки, так и статические библиотеки могут предлагаться компоновщику по единому -lfooпротоколу, когда вы связываете какую-то другую программу или DSO. Этот вариант направляет линкер для сканирования его поименованные или по умолчанию поиск directrories найти либо libfoo.soили libfoo.a. По умолчанию, когда он находит один из них, он вводит этот файл в связь, и если он находит оба в одном каталоге поиска, он предпочитает libfoo.so. Если libfoo.soвыбрано, то компоновщик добавляет этот DSO в список зависимостей времени выполнения любой программы или DSO, которые вы создаете. Если libfoo.aвыбрано, то компоновщик использует архив как выборку объектных файлов для связи с выходным файлом, если необходимо, прямо здесь и тогда. Нет зависимости во время выполнения от libfoo.aсамо по себе возможно; это не может быть отображено в процессе; это ничего не значит для загрузчика ОС.

Скопировано с https://stackoverflow.com/a/47924864/195787 .

Royi
источник