2.3.2. Совместно используемые библиотеки
Второе важное отличие состоит в том, что совместно используемая библиотека — это не просто коллекция объектных файлов, из которых компоновщик выбирает требуемый для разрешения ссылки. В данном случае все объектные файлы, входящие в библиотеку, объединяются в единый объектный файл. Благодаря этому программы, компонующиеся вместе с библиотекой, всегда имеют доступ ко всему ее содержимому, а не только к одной конкретной части.
Чтобы создать совместно используемую библиотеку, нужно сначала скомпилировать составляющие ее объектные файлы с указанием опции -fPIC
% gcc -с -fPIC test1.c
Опция -fPIC
test1
.o станет частью совместно используемой библиотеки.Аббревиатура PIC (Position-Independent Code) в названии опции расшифровывается как "позиционно-независимый код". Функции в совместно используемой библиотеке могут загружаться по разным адресам разными программами, поэтому код библиотеки не должен зависеть от адреса (или позиции), по которому она загружена. Все это никак не касается программистов, просто нужно не забывать указывать флаг -fPIC
Затем следует объединить объектные файлы в библиотеку:
% gcc -shared -fPIC -о libtest.so test1.o test2.o
Опция -shared
.so
. Подобно статическому архиву, имя библиотеки всегда начинается с префикса lib
, указывающего на то. что файл является библиотекой.Компоновка совместно используемой библиотеки аналогична компоновке архива. Например, следующая команда подключает к программе файл libtest.so
% gcc -о app арр.о -L. ltest
Предположим, имеются оба файла: libtest.а
libtest.so
. Каким образом компоновщик принимает решение? Он просматривает каждый заданный каталог (сначала те, что указаны в опции -L
, затем стандартные) и, как только обнаруживает хотя бы один из файлов, тут же прекращает поиск. Если в найденном каталоге присутствует только один из файлов, он и выбирается. В противном случае выбор делается в пользу совместно используемой библиотеки, если явно не указано обратное. Отдать приоритет статическому архиву позволяет опция -static
. Например, следующая команда подключит к программе архив libtest.a
, даже если присутствует библиотека libtest.so
:% gcc -static -о app арр.о -L. -ltest
Команда ldd
ldd
сообщает о наличии дополнительной библиотеки: ld-linux.so
. Она является частью механизма динамической компоновки в Linux.Когда к программе подключается совместно используемая библиотека, компоновщик помещает в исполняемый файл ссылку на нее, но в этой ссылке указан не полный путь к библиотеке, а только имя файла. При запуске программы система сама находит библиотеку и загружает ее. По умолчанию система просматривает лишь каталоги /lib
/usr/lib
. Если библиотека находится в другом каталоге, она не будет найдена и система откажется загружать программу.Одно из решений заключается в компоновке программы с указанием флага -Wl,-rpath
% gcc -о app арр.о -L. -ltest -Wl,-rpath,/usr/local/lib