View in Telegram
Компоновка с динамическими библиотеками [1] Перед применением библиотеки необходимо выполнить 2 дополнительных шага, которые не требуются для работы со статическими аналогами: 1. Поскольку исполняемый файл не содержит копии необходимых объектных модулей, он должен иметь возможность определять, какая разделяемая библиотека требуется для работы. Для этого, на этапе статической компоновки, в ELF файл программы внедряется метка DT_NEEDED с именем библиотеки. Если говорить чуть более точно, то в поле DT_NEEDED записывается полный путь до библиотеки. Если зависимость находится в неизвестном компоновщику каталоге, то лучше указать дорогу через флаг -L, иначе потом может возникнуть вопрос "Почему зависимость находится корректно при ее локальном размещении?" - потому что ее полый путь записан в поле NEEDED.
$ gcc -Wall -o prog main.o -L=./libs/ -ldemo

// Выводим содержимое динамической секции ELF файла
$ readelf -d ./prog
    
Dynamic section at offset 0xd88 contains 28 entries:
   Tag        Type                         Name/Value
    0x0000000000000001 (NEEDED)             Shared library: [libdemo.so]
    0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
2. Должен существовать механизм, который, во время выполнения программы, находит библиотеку по имени и выгружает ее в память, если она не была загружена ранее. Данная процедура выполняется динамическим компоновщиком и необходима для разрешения имени библиотеки на этапе выполнения. Компоновщик, сам по себе, является разделяемой библиотекой “/lib/ld-linux.so.2” и используется всеми исполняемыми файлами формата ELF, которые содержат динамические зависимости. На самом деле, Id-linux.so.2 представляет собой обычную символическую ссылку на библиотеку динамического компоновщика “Id-<version>.so” (например, ld-2.11. so), где version - это версия glibc, которая установлена в системе. Если на данном этапе попробовать запустить программу, выведется следующее сообщение об ошибке:
$ ./prog

./prog: error in loading shared libraries: libdemo.so: 
    cannot open shared object file: No such file or directory
Это возвращает нас ко второму пункту. Дело в том, что динамический компоновщик анализирует список рантайм зависимостей программы и находит соответствующие библиотечные файлы, используя набор заранее заданных правил. Часть этих правил основывается на списке стандартных каталогов, в которых обычно хранятся разделяемые библиотеки (lib и /usr/lib). Причина ошибки выше заключается в том, что библиотека находится в текущем каталоге, который не учитывается при поиске. Для оповещения динамического компоновщика о том, что разделяемая библиотека находится в нестандартном месте, можно воспользоваться переменной среды LD_LIBRARY_PATH, указав соответствующий каталог в качестве значения. Если переменная определена, компоновщик начинает поиск разделяемой библиотеки с тех каталогов, которые в ней перечислены, и только потом переходит к стандартным библиотечным путям. Следовательно, можно запустить программу с помощью следующей команды:
$ LD_LIBRARY_PATH=./libs ./prog
Love Center
Love Center
Find friends or serious relationships easily