Что такое библиотека?

В реальной жизни библиотека - это то место, куда мы идем, когда хотим найти книги о конкретных вещах. Если бы я хотел научиться программировать на C или говорить на иностранном языке, я бы пошел в библиотеку, чтобы найти книгу, чтобы научить меня. Основная предпосылка этой концепции состоит в том, что я хожу в библиотеку, когда хочу узнать что-то новое или почитать что-то интересное, и брать книги, которые удовлетворят это желание. Чтобы найти эти книги, у них есть названия и они организованы с использованием специальной организационной системы, которая поможет мне найти нужный раздел и книгу для моих нужд; но сама книга - это то, что я использую, чтобы получить эти знания. Другими словами, различные организационные системы и названия книг говорят мне, как правильно взаимодействовать с библиотекой или использовать ее, а сами книги помогают мне в выполнении моей конкретной задачи.

Именно это и есть библиотека C. Файлы заголовков, такие как stdio.h, содержат переменные, имена функций, типы возвращаемых значений, аргументы и имена, которые помогают определить интерфейс и помогают правильно использовать библиотеку, но библиотека сам по себе содержит конкретную функцию реализацию в виде машинного кода, который читает компьютер.

В C библиотеки - это архивы файлов объектного кода, которые функционируют как единое целое. Они являются основными силами на этапе компоновки компиляции, потому что они предоставляют список проиндексированных символов и определений, которые связаны с исполняемым файлом в конце компиляции. Файлы стандартной библиотеки можно найти в /usr/lib/ и /lib/ в системе Linux. В C есть два типа библиотек

  1. Статические библиотеки
  2. Динамические (общие) библиотеки

Основное различие между ними заключается в том, что все статические библиотеки связаны с исполняемыми файлами на этапе компоновки в процессе компиляции, в то время как динамические библиотеки связываются с исполняемым файлом во время выполнения программы, а не во время компоновки. Таким образом, необходимое содержимое библиотеки физически существует в исполняемом файле, связанном со статической библиотекой, в то время как необходимое содержимое для исполняемых файлов, связанных с динамическими библиотеками, доступно из памяти во время выполнения программы. В этом сообщении блога будут рассмотрены все тонкости статических библиотек.

Зачем нужны статические библиотеки?

Итак, почему статические библиотеки так важны и полезны?

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

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

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

Короче говоря, библиотеки повышают производительность, мобильность и эффективность!

Каковы преимущества статических библиотек перед динамическими?

В частности, для статических библиотек их основное преимущество перед динамическими библиотеками заключается во времени выполнения. Поскольку все символы доступны и связаны во время компиляции, и поскольку машинный код физически присутствует в исполняемом файле, время выполнения программ, связанных со статическими библиотеками, имеет тенденцию быть быстрее, чем тех, которые связаны с динамическими библиотеками. Это, конечно, происходит за счет размера файла, поскольку исполняемые файлы, как правило, намного больше.

Как работают библиотеки и как мы их используем?

Хватит болтать, давай запачкаем руки!

Так как же работают библиотеки? По сути, они содержат объектный код из объектных (двоичных) файлов с расширением .o, и все они объединены в один архивный файл с расширением .a. Архив - это, по сути, «набор инструментов» всех инструментов и функций, которые могут понадобиться программе, которые компоновщик ищет определенные символы при связывании. Вот краткое изложение того, что должно произойти.

Давай попробуем что-нибудь! Ниже приведено изображение серии .c файлов, содержащих исходный код, определяющий определенные функции. Заголовочный файл holberton.h содержит все прототипы функций, а каталог с именем sourcecode содержит файл test.c, который я буду использовать для демонстрации связывания библиотек.

Когда я запускаю команду gcc -Wall -Wextra -Werror -pedantic -c *.c, она вводит каждый .c файл в процесс компиляции, но опция -c останавливает его после создания файлов объектного кода. Таким образом, после выполнения этой команды в одном каталоге создается набор объектных файлов с расширением .o. Все они содержат двоичные инструкции для своих конкретных задач. Я показал их ниже:

Теперь мы можем архивировать все эти объектные файлы в статическую библиотеку. Следующая команда сделает это:

ar -rc libholbertonschool.a *.o

Эта команда ar является командой архивирования, а две опции -r и -c предназначены для перемещения элементов с расширением .o в архив и для создания архива, если он не существует, соответственно. Архив библиотеки всегда должен начинаться с префикса lib и иметь расширение .a.

Таким образом, теперь у меня есть файл архива, и с параметром -t для ar я могу видеть список содержимого архива. Архивный файл теперь представляет собой серию двоичного кода, который содержит инструкции для каждой функции.

Запуск ranlib libholbertonschool.a проиндексирует содержимое этого архива, чтобы было легче найти символы.

Теперь я переместил holberton.h и файл библиотеки в каталог sourcecode. Файл test.c, который у меня находится внутри этого каталога, содержит следующий код:

#include "holberton.h"
int main(void)
{
      _puts("\"Aimer, ce n'est pas se regarder l'un l'autre, c'est regarder ensemble dans la même direction.\"\n\t - Antoine de Saint-Exupéry");
      return (0);
}

Я хочу скомпилировать это, чтобы вывести в терминал одну из моих любимых французских цитат:

«Aimer, ce n’est pas se regarder l’un l’autre, c’est regarder ensemble dans la même direction». - Антуан де Сент-Экзюпери

Когда я запускаю команду gcc test.c -o quote, я получаю следующую ошибку:

Таким образом, мне не удалось скомпилировать файл, потому что ссылка на функцию _puts() в моем тестовом файле не была определена. Компилятор не знал, где искать, чтобы связать это определение функции. Он не знал, как реализовать функцию _puts (), о которой говорилось в заголовочном файле holberton.h. Давайте попробуем указать библиотеку:

gcc test.c ./libholbertonschool.a -o quote или gcc test.c -L. -lholbertonschool -o quote должны делать то же самое.

Параметр -L. выполняет поиск библиотек в текущем рабочем каталоге, а параметр -l, связанный с holbertonschool, выполняет поиск файла библиотеки неявно (т. Е. Предполагается, что префикс lib и суффикс .a).

Оно работает! Чтобы использовать файл библиотеки, необходимо вызвать компилятор с различными файлами библиотеки, чтобы он знал, где искать, и мог правильно выполнить этап компоновки в процессе компиляции!

Пора запускать программу!

Woot! Теперь мой компьютер узнал, что, по мнению Антуана де Сент-Экзюпери, означает любовь:

«Любовь не состоит в том, чтобы смотреть друг на друга - она ​​состоит в том, чтобы смотреть вместе в одном направлении».

Резюме

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

Библиотеки помогают повысить эффективность, мобильность и продуктивность процесса разработки. Они позволяют повторно использовать уже написанный код, они связывают только то, что нужно основной программе, не больше и не меньше, они позволяют открывать гораздо меньше файлов, что ускоряет компиляцию, и они упрощают управление каталогами.

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

Итак, вот и все! Спасибо за чтение, и я надеюсь, что вам понравилось узнавать о статических библиотеках!