Абракадабра! Сегодня обсудим «сосо́чки» и их версионность.

Как ты знаешь, в Linux есть файлы с расширением .so. Это и есть «сосо́чки». А ты думал?

Если такие файлы бездумно удалять или подменять из других дистрибутивов, велика вероятность, что всё встанет раком.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос

У меня была история в начале карьеры, когда я бездумно удалил файлы на сервере, и корпоративная 1С приказала долго жить. Удалил по причине — чистил место. Бэкапов, естественно, я не сделал.

Лошара чо, так я получил новое достижение — седой волос на жопе.

Сосо́чки — это разделяемые библиотеки, то бишь shared libraries. Короче, если ты немного программист, то знаешь, что эти библиотеки содержат набор неких функций.

Допустим, написал ты свой бинарник, а все функции для бинарника вынес в отдельный файл bashdays.so. Теперь бинарник будет ходить в этот «сосочек» и читать оттуда нужные ему функции.

А зачем так усложнять? Всё просто, ты выносишь протестированные функции в отдельный файл. А потом можешь их использовать совершенно из другого бинарника.

Грубо говоря, у тебя есть 10 софтин и один «сосо́чек». Все эти 10 софтин ходят в сосочек и забирают нужное. Оптимизация? Ещё какая!

Ну так вот. К «сосо́чкам» применяется версионность. То есть у тебя может быть несколько таких библиотек с разными функциями:

libbashdays.so.1.0.0
libbashdays.so.1.1.0
libbashdays.so.1.1.1

Версионность нужна для совместимости. Она позволяет сохранить работоспособность программ при обновлениях.

Ну ты понял. Условный apache использует libbashdays.so.1.0.0, а условный nginx, который был обновлён, уже хочет версию 1.1.1. Чтобы не сломать apache, нужно иметь 2 версии «сосо́чка».

Разделяемая библиотека должна состоять из трёх имён:

  • имя библиотеки;
  • метка soname;
  • компоновочное имя.

Имя библиотеки — в формате lib<name>.so.<major>.<minor>.<patch>.

  • Major — правки приводят к несовместимости;
  • Minor — добавление функционала;
  • Patch — багфиксы, оптимизации.

Метка Shared Object Name, или soname, представляет идентификатор, который позволяет системе динамической загрузки (dynamic linker) определить, какая версия библиотеки должна быть загружена для выполнения программ.

Если софтина скомпилирована с использованием libbashdays.so.1.0.0, она будет искать libbashdays.so с soname 1 при запуске.

Это значит, что она может работать как с libbashdays.so.1.0.0, так и с libbashdays.so.1.1.0, поскольку у них одинаковый soname. Однако она не будет работать с libbashdays.so.2.0.0, так как у этой версии другой soname.

Создаём libbashdays.so.1.0.0 с меткой libbashdays.so.1:

gcc -shared -Wl,-soname=libbashdays.so.1 -o libbashdays.so.1.0.0 module.o

Компоновочное имя связывает приложение и библиотеку.

gcc -g -Wall -o bashdays main.o libbashdays.so

В исполняемый файл bashdays будет записан soname с привязкой к libbashdays.so.

Чтобы корректно подключать зависимости, создаётся пара символических ссылок.

libbashdays.so -> libbashdays.so.1
libbashdays.so.1 -> libbashdays.1.0.0
libbashdays.1.0.0

Старайся, чтобы компоновочное имя ссылалось на метку soname. На случай, если пользователь-дебил удалит старую версию минорного обновления и симлинка поломается.

Так. После всех этих танцев с бубном ссылка на soname должна указывать на самую последнюю её версию. Тогда приложение будет работать с самой актуальной версией библиотеки.

libbashdays.so.1 -> libbashdays.so.1.0.1

Ну и при обновлениях мажорных версий, используя утилиту ldconfig, автоматически будет создана ссылка, которая свяжет имя библиотеки и метку soname. Приложение будет работать с последней совместимой версией.

ldconfig -v | grep libbashdays
libbashdays.so.2 -> libbashdays.so.2.0.0 (changed)

$ ldd bashdays
libbashdays.so.1 => ./libbashdays.so.1 (0x0000ffff6f680000)
libc.so.6 => /lib/libc.so.6 (0x0000ffff7ff50000)
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Пиздец муть? Аще! Если ты далёк от этих «сосо́чков», не забивай себе голову. Для общего развития пойдёт, теперь ты знаешь, как это говнище устроено.

Изучай. Увидимся!