Теперь, чтобы проверить наличие символьных ссылок для soname, выведем список файлов из каталога /usr/lib, в именах которых содержится название libdemo:
# cd /usr/lib
# ls — l libdemo* | awk '{print $1, $$9, $10, $11}'
lrwxrwxrwx libdemo.so.1 — > libdemo.so.1.0.1
— rwxr-xr-x libdemo.so.1.0.1
lrwxrwxrwx libdemo.so.2 — > libdemo.so.2.0.0
— rwxr-xr-x libdemo.so.2.0.0
Нам все еще нужно создать символьную ссылку для компоновочного имени. Воспользуемся для этого следующей командой:
# ln — s libdemo.so.2 libdemo.so
Однако, если установить новую новую минорную версию нашей библиотеки, 2.x, то программа ldconfig обновит и компоновочное имя, поскольку оно указывает на последнюю версию soname. В этом можно убедиться на следующем примере:
# mv libdemo.so.2.0.1 /usr/lib
# ldconfig — v | grep libdemo
libdemo.so.1 — > libdemo.so.1.0.1
libdemo.so.2 — > libdemo.so.2.0.1 (changed)
При сборке и использовании приватной библиотеки (такой, которая не устанавливается в стандартные каталоги) программа ldconfig может помочь создать символьную ссылку на имя soname — достаточно указать параметр — n. Это заставит ldconfig обрабатывать только каталоги, заданные в командной строке, и предотвратит обновление файла с кэшем. В следующем примере мы воспользуемся программой ldconfig для обработки библиотек в текущем каталоге:
$ gcc — g — c — fPIC — Wall mod1.c mod2.c mod3.c
$ gcc — g — shared — Wl, — soname,libdemo.so.1 — o libdemo.so.1.0.1 \
mod1.o mod2.o mod3.o
$ /sbin/ldconfig — nv.
.:
libdemo.so.1 — > libdemo.so.1.0.1
$ ls — l libdemo.so* | awk '{print $1, $9, $10, $11}'
lrwxrwxrwx libdemo.so.1 — > libdemo.so.1.0.1
— rwxr-xr-x libdemo.so.1.0.1
При вызове программы ldconfig мы указали полный путь к ней, так как наша учетная запись не имеет повышенных привилегий и в ее переменной среды PATH не содержится каталог /sbin.
Со временем в код разделяемой библиотеки приходится вносить изменения. Результатом этого будет новая версия библиотеки, которая либо
Вносимые изменения совместимы с имеющейся версией библиотеки, если выполняются
• Семантика каждой публичной функции и переменной в библиотеке остается неизменной. Иными словами, каждая функция сохраняет тот же список аргументов и возвращает то же значение, не меняя своего влияния на глобальные переменные и возвращаемые аргументы. Таким образом, изменения, относящиеся к улучшению производительности или устранению ошибок (что приводит к более строгому следованию заявленному поведению) могут считаться совместимыми.
• Из публичного программного интерфейса библиотеки не была удалена ни одна функция или переменная. Хотя добавление новых публичных функций и переменных не нарушает совместимость.
• Структуры, которые выделяются внутри всех функций и возвращаются ими, остаются неизменными. Аналогично не меняются структуры библиотеки, доступные для применения извне. Исключение из правила состоит в том, что в ряде обстоятельств в конец структуры могут быть добавлены новые элементы, хотя и это может оказаться источником непредвиденного поведения, если, например, вызывающая программа попытается выделить массив данного типа. Чтобы обойти описанные ограничения, разработчики библиотек иногда делают размер экспортируемых структур большим, чем того требует текущая версия библиотеки, добавляя несколько запасных полей «для будущего использования».
Если ни одно из этих условий не нарушается, новое имя библиотеки может быть сформировано путем инкрементации минорной версии. В противном случае необходимо создавать новый мажорный идентификатор.
Одно из преимуществ разделяемых библиотек заключается в том, что их новые мажорные или минорные версии можно устанавливать даже во время работы программ, которые используют текущую версию. Для этого достаточно создать новую ревизию библиотеки, установить ее в подходящий каталог и в случае необходимости обновить символьные ссылки на soname и компоновочное имя (или, как это принято, дать возможность программе ldconfig сделать всю работу за нас). Для выпуска новой минорной версии (то есть выполнения совместимого обновления) разделяемой библиотеки /usr/lib/libdemo.1.0.1 потребовалось бы сделать следующее:
$ su
Password:
# gcc — g — c — fPIC — Wall mod1.c mod2.c mod3.c