• Должен существовать механизм для поиска файла библиотеки по ее имени во время выполнения программы и последующей его загрузки в память, если он не был загружен до этого.
Внедрение имени библиотеки в исполняемый файл происходит автоматически при компоновке разделяемой библиотеки с программой:
$ gcc — g — Wall — o prog prog.c libfoo.so
Теперь, если запустить данную программу, можно будет увидеть следующее сообщение об ошибке:
$ ./prog
./prog: error in loading shared libraries: libfoo.so: cannot
open shared object file: No such file or directory
Это подводит нас ко второму обязательному шагу —
Путь /lib/ld-linux.so.2 представляет собой обычную символьную ссылку на исполняемый файл динамического компоновщика. Имя данного файла имеет вид ld-version.so, где version — это версия библиотеки glibc, установленной в системе (например, ld-2.11.so). Путь к динамическому компоновщику может варьироваться в зависимости от архитектуры. Например, на платформе IA-64 символьная ссылка на него выглядит как /lib/ld-linux-ia64.so.2.
Динамический компоновщик анализирует список динамических зависимостей программы и находит соответствующие библиотечные файлы, используя набор заранее заданных правил. Часть этих правил основывается на списке стандартных каталогов, в которых обычно хранятся разделяемые библиотеки (к примеру, /lib и /usr/lib). Причина сообщения об ошибке, приведенного выше, заключается в том, что библиотека находится в текущем каталоге, которая не учитывается динамическим компоновщиком при выполнении поиска.
Некоторые архитектуры (такие как zSeries, PowerPC64 и x86-64) поддерживают выполнение как 32-, так и 64-разрядных программ. В таких системах 32-разрядные библиотеки находятся в подкаталогх */lib, а их 64-разрядные версии — в подкаталогх */lib64.
Переменная среды LD_LIBRARY_PATH
Для оповещения динамического компоновщика о том, что разделяемая библиотека находится в нестандартном месте, можно воспользоваться переменной среды LD_LIBRARY_PATH, указав соответствующий каталог в качестве одного из элементов списка, разделенного двоеточиями. Для разделения каталогов можно также использовать точку с запятой, но, чтобы избежать интерпретации данного символа командной оболочкой, список в этом случае следует обрамить кавычками. Если переменная LD_LIBRARY_PATH определена, компоновщик начинает поиск разделяемой библиотеки с тех каталогов, которые в ней перечислены, и только потом переходит к стандартным библиотечным путям (позже вы увидите, что реальное приложение никогда не должно полагаться на эту переменную, но на данном этапе она облегчает работу с разделяемыми библиотеками). Следовательно, можно запустить программу с помощью следующей команды:
$ LD_LIBRARY_PATH=. /prog
Called mod1-x1
Called mod2-x2
Синтаксис командной оболочки (bash, ksh и sh), использованный выше, позволяет определить переменную среды в рамках выполнения программы prog. Это определение сообщает динамическому компоновщику о том, что поиск разделяемых библиотек нужно проводить в текущем каталоге (то есть в.).
Пустое значение в списке LD_LIBRARY_PATH (то, что указано посередине в dirx::diry) эквивалентно. — текущему каталогу (но имейте в виду: присваивание пустого значения всей переменной LD_LIBRARY_PATH имеет совсем другой результат). Мы не используем этот синтаксис (стандарт SUSv3 не рекомендует применять его в переменной среды PATH).
Сравнение статической и динамической компоновки
Обычно термин
41.4.4. Разделяемые библиотеки и имя soname