Управление библиотеками
Практически все программы требуют для своей сборки или работы наличия в системе файлов библиотек. Библиотеки представляют собой файлы со спе- циальной структурой, содержащие скомпилированный бинарный код (так называемый объектный код), предназначенный для подключения к машин- ному коду, содержащемуся в исполняемых файлах программ. Процесс под- ключения кода в библиотеках к коду самой программы называется компонов- кой (linking).
В зависимости от типа компоновки различают библиотеки разных видов:
r статические библиотеки (static library);
r разделяемые библиотеки (shared library).
По соглашению файлы статических библиотек заканчиваются суффиксом .a (archive), а файлы разделяемых библиотек — .so (shared object).
Статические библиотеки представляют собой наборы объектных файлов, объединенных вместе с помощью утилиты ar. Скомпилированный код, нахо- дящийся в библиотеке, может быть использован в коде программ. Это позволя- ет избавиться от необходимости многократного повторного написания кода.
Так как требуемый код из статических библиотек помещается на стадии ком- поновки в результирующий программный код, находящийся в исполняемом файле, то для выполнения таких программ никаких библиотек уже не требу- ется. То есть библиотека используется только на стадии сборки программы, но не на стадии исполнения, что является существенным преимуществом та- ких программ.
Статически собранные программы удобны для применения в случае аварий- ного восстановления системы и во всех остальных случаях, когда доступ к требуемым библиотекам затруднен или невозможен. Однако размер стати- чески собранной программы обычно значительно превышает размер этой же программы, собранной с использованием разделяемых библиотек.
Идея разделяемой библиотеки состоит в том, что один и тот же код, находя- щийся в файле библиотеки, используется при исполнении разных программ. То есть код из библиотеки не помещается в код программ на стадии компо- новки, он вызывается из файла библиотеки по мере его необходимости. Тем не менее, код, находящийся в библиотеке, жестко связан с кодом программы.
Использование разделяемых библиотек существенно экономит дисковое про- странство, т. к. множество программ используют код библиотек совместно. При запуске компилятора gcc по умолчанию производится сборка программ с помощью разделяемых библиотек.
В качестве примера соберем несложную программу, выводящую на терминал строку "Privet!". Код ее на языке С приводится в примере 18.8.
Пример 18.8. Простая программа на C |
$ cat simple.c
#include <stdio.h>
int main()
{
printf("%s\n", "Privet!"); return 0;
}
Данная программа использует библиотечную функцию форматированной печати printf(), которая выводит на терминал строку, указанную ей в каче- стве второго аргумента. Первый аргумент — строка форматирования. Функ- ция printf() описана в заголовочном файле stdio.h.
Соберем эту программу с использованием разделяемых библиотек (при-
мер 18.9).
Пример 18.9. Компиляция программы |
$ gcc -o simple.dynamic simple.c
$ file simple.dynamic
simple.dynamic: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared libs), not stripped
В результате выполнения этой команды будет создан исполняемый файл simple.dynamic из исходного кода в файле simple.c. Вывод команды file подтверждает то, что программа собрана с поддержкой разделяемых биб- лиотек.
При статической сборке используют опцию -static компилятора gcc (при-
мер 18.10).
Пример 18.10. Сборка статически скомпонованной программы |
$ gcc -static simple.c -o simple.static
$ file simple.static
simple.static: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.4, statically linked, not stripped
Сравним теперь размеры полученных файлов (пример 18.11).
Пример 18.11. Размеры динамически и статически скомпонованных программ |
$ ls -l simple.?*
-rwxr-xr-x 1 user user 6793 Dec 28 23:08 simple.dynamic
-rwxr-xr-x 1 user user 485882 Dec 28 23:08 simple.static
$ ./simple.static Privet!
$ ./simple.dynamic Privet!
Легко заметить, что размеры полученных файлов значительно отличаются, несмотря на то, что программы делают одно и то же.
Как определить, с какими разделяемыми библиотеками собран файл? Ответ на этот вопрос предоставляет команда ldd (пример 18.12).
Пример 18.12. Зависимости от разделяемых библиотек |
$ ldd simple.dynamic
linux-gate.so.1 => (0xffffe000) libc.so.6 => /lib/libc.so.6 (0xb767b000)
/lib/ld-linux.so.2 (0xb7813000)
Итак, программа примера зависит лишь от библиотеки libc.so.6. Это основная библиотека стандартных функций C, имеющая шестой номер версии. При сборке программ эта библиотека подключается автоматически, поэтому в примере она нигде не была указана в опциях компилятора.
По соглашению все имена библиотек начинаются с префикса lib. Когда команда ldd выводит список зависимостей от библиотек, указывается не имя библиотеки, а имя файла символической ссылки на библиотеку (при- мер 18.13).
Пример 18.13. Имена разделяемых библиотек |
$ ls -l /lib/librt.so.1
lrwxrwxrwx 1 root root 14 Nov 8 03:27 /lib/librt.so.1 -> librt-2.10.1.so
Символические ссылки, указывающие на файлы разделяемых библиотек, на- зываются SO-name (или soname) и имеют особый смысл. С помощью этих символических ссылок облегчается задача обновления библиотек. В испол- няемом файле указано, от какой библиотеки с известным SO-name он зави- сит. Символическая же ссылка с таким именем может указывать на библио- теки с различными версиями. Так, в рассматриваемом случае SO-name librt.so.1 может указывать на предыдущую версию библиотеки librt-2.10.1.so. Таким образом, имеется возможность обновления библиотек без внесения изменений в исполняемые файлы.
При сборке программ с библиотеками в опциях компилятора (для gcc оп- ция -l) не указывают префикс имен библиотек lib. Так, для библиотеки librt.so.1 в опциях компилятора имя будет просто rt.
Исполняемые файлы, собранные с поддержкой разделяемых библиотек, тре- буют очень быстрого обращения к коду в файлах этих библиотек. Для этого
имеется специальная база данных — хешированный файл /etc/ld.so.cache.
Этот файл бинарный. Он генерируется с помощью команды ldconfig.
При установке новых библиотек команда ldconfig обычно вызывается авто- матически. При этом индексируются библиотеки, находящиеся в стандарт- ных местах файловой системы: /lib, /usr/lib и /usr/local/lib, а также в катало- гах, указанных в файле /etc/ld.so.conf (пример 18.14).
Пример 18.14. Файл /etc/ld.so.conf |
$ cat /etc/ld.so.conf
/usr/local/lib
/usr/lib/opengl/xfree/lib
/usr/X11R6/lib
/usr/qt/3/lib
/opt/kde3/lib
Дата добавления: 2015-06-12; просмотров: 923;