Почему библиотеки используются в компьютерном программировании?

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

Как работают библиотеки?

Библиотеки находятся на диске и «вызываются» различными приложениями для использования при необходимости. Создание, компиляция и использование статических и динамических библиотек обсуждаются ниже.

Как создаются библиотеки?

Для этого объяснения мы рассмотрим библиотеки, используемые в операционной системе gnu/Linux.

Создание статических библиотек: (.a)

1) Создайте объектный код:

Например, если мы хотим создать статическую библиотеку, содержащую function_a.c и function_b.c, мы можем сначала создать объектный файл myobjectfile.o:

gcc –Wall –Werror –Wextra –pedantic –c function_a.c function_b.c –o myobjectfile.o

2) Создайте библиотеку:

Затем создайте «архив» или статическую библиотеку с помощью программы ar:

ar rcs libmylibrary.a myobjectfile.o

Обратите внимание, что имена библиотек должны начинаться с lib.

Создание динамически связанных библиотек «общих объектов»: (.so)

1) Создайте объектный код:

Например, если мы хотим создать динамически подключаемую библиотеку «общих объектов», содержащую function_a.c и function_b.c, мы можем сначала создать объектный файл myobjectfile.o:

gcc -Wall -Werror -Wextra -pedantic -fPIC -c function_a.c function_b.c -o myobjectfile.o

В отличие от создания статической библиотеки, обратите внимание на использование параметра gcc –fPIC. Это директива gcc для вывода pposition iнезависимого code, что требуется для разделяемых библиотек.

2) Создайте библиотеку (и, при желании, версию по умолчанию, используя символическую ссылку)

gcc -shared -Wl,-soname,libmylibrary.so.1 -o libmylibrary.so.1.0 myobjectfile.o

Используемые флаги компиляции:

-o
Вывод операции; в этом случае имя общего объекта для вывода будет libmylibrary.so.1.0

-shared
Это директива gcc для вывода «общего» объекта, который впоследствии может быть связан с другими объектами для формирования исполняемого файла.

-Wl,-soname,libmylibrary.so.1
Это директива gcc, которая устанавливает soname, управление версиями связанных библиотек и взаимосвязь между lmylibrary.so, libmylibrary.so.1, libmylibrary.so.1.0 и будущими версиями libmylibrary.so.

В качестве альтернативы вы можете каскадировать символические ссылки:

ln -sf libmylibrary.so.1.0 libmylibrary.so.1
ln -sf libmylibrary.so.1 libmylibrary.so

Ссылка на libmylibrary.so позволяет работать соглашению об именах для флага компиляции -lmylibrary.
Ссылка на libmylibrary.so.1 позволяет работать привязке во время выполнения. См. зависимость ниже.

Как использовать библиотеки в Linux

Как правило, библиотечные компоненты вызываются различными приложениями для использования по мере необходимости.

Использование стандартной библиотеки C

Стандартная библиотека C в gnu/Linux состоит из отдельных компонентов, загружаемых в библиотечный кэш при запуске. Чтобы использовать конкретный компонент стандартной библиотеки C, мы просто вызываем соответствующий файл заголовка (.h) с помощью оператора include #include <component.h> в нашем программном файле, а затем вызываем любую функцию, на которую ссылается этот заголовок.

Использование других статических библиотек

Считайте, что мы создали статическую библиотеку следующим образом:

ar rcs libmylibrary.a myobjectfile.o

Мы можем перечислить файлы в библиотеке:

ar -t libmylibrary.a

И скомпилируйте с нашей программой main.c, если библиотека находится в текущем каталоге:

gcc –Wall –Werror — Wextra –pedantic -o executable-name main.c libmylibrary.a

Или, альтернативно, и если библиотека находится в другом месте:

gcc –Wall –Werror — Wextra –pedantic –o executable-name main.c –L/path/to/library-directory –libmylibrary

Использование динамически связанных библиотек «общих объектов»: (.so)

Установка

Динамические библиотеки, которые мы создаем, должны быть установлены. Мы можем установить библиотеки несколькими способами:

а) Размещение файла библиотеки в «доверенном» каталоге по умолчанию:

/lib
/usr/lib
/usr/local/lib
sudo mv libmylibrary.so /usr/lib/

б) Ссылка на библиотеку в файле конфигурации /etc/ld.so.conf или на одну из ее зависимостей. Как правило, это дополнительные каталоги, создаваемые поставщиками программного обеспечения при установке программ.

Мы должны перезагрузить библиотечный кеш (/etc/ld.so.cache) с помощью команды: sudo ldconfig, чтобы обновить библиотечный кеш после внесения изменений в «доверенный» каталог по умолчанию, файл /etc/ld.so.conf или его зависимости.

c) Явное добавление библиотеки и пути к команде компилятора/компоновщика gcc с помощью: -lmylibrary -L/path/to/lib

г) Временное добавление или замена библиотеки путем установки переменной среды LD_LIBRARY_PATH. Эта переменная, обычно не устанавливаемая по умолчанию, представляет собой набор каталогов, разделенных двоеточиями, в которых библиотеки следует искать в первую очередь перед стандартным набором каталогов:

export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH

Если библиотека находится в текущем каталоге, как это может быть во время разработки:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

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

gcc –Wall –Werror — Wextra –pedantic -I/path/to/include-files -L/path/to/libraries main.c –lmylibrary -o executablename

or

gcc –Wall –Werror — Wextra –pedantic –L. main.c –lmylibrary –o executablename

Обратите внимание, что имя библиотеки, которое мы вывели выше, было libmylibrary.so.1.0 для библиотеки libmylibrary.so, но мы использовали lmylibrary в приведенных выше компиляциях. Такое расположение разрешено путем установления soname и соответствующих символических ссылок (см. выше). Это также позволяет контролировать версии библиотек.

Полезные команды

ldd: Список зависимостей

Зависимости общей библиотеки исполняемого файла можно просмотреть с помощью команды списка зависимостей: ldd name-of-executable:

ldd executablename

nm: команда «nm» выводит список символов, содержащихся в объектных файлах:

nm myobjectfile.o
nm mylibrary.a
nm — dynamic libmylibrary.so.1.0

В чем разница между статическими и динамическими библиотеками?

Статические библиотеки (.a) – это библиотеки объектного кода, которые связаны с компилируемым приложением и становятся его частью.

Динамически подключаемые общие библиотеки (.so) можно использовать двумя способами:

  • Динамически компонуется во время выполнения, но поддерживается статически. Библиотеки должны быть доступны как во время компиляции/компоновки, так и во время выполнения программы. Библиотеки не становятся частью скомпилированного приложения.
  • Динамически загружается и выгружается и связывается во время выполнения с использованием системных функций загрузчика динамической компоновки.

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

Преимущества статически связанных библиотек

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

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

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

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

Динамические библиотеки занимают меньше места на диске и в памяти. Их можно хранить только в одном месте, а не дублировать среди скомпилированных исполняемых файлов. Динамические библиотеки также загружаются в память только один раз; все программы, которым необходимо использовать библиотеку, используют одну и ту же копию.

Динамическая библиотека может быть обновлена ​​или восстановлена, и изменение будет распространяться на все затронутые исполняемые файлы, в то время как программу со статически связанными библиотеками необходимо будет перекомпилировать/повторно связать.

Динамические библиотеки обеспечивают надежные системы контроля версий и управления пакетами.