Как версионируются и совмещаются библиотеки из разных репозиториев

Давайте на примере btrfs-progs 4.19.1 и ffmpeg рассмотрим особенности сборки, версионирования пакетов и библиотек в дистрибутивах с продвинутой пакетной системой, то есть Deb или RPM, но не pacman или порты BSD (emerge из Gentoo имеет совсем иные принципы решения этих задач).

deb src: https://gitlab.com/nixtux-packaging/btrfs-progs/tree/master/btrfs-progs-4.19.1/debian
RPM src: https://abf.io/import/btrfs-progs
RPM binary: https://abf.io/build_lists/2957703

В приведенных примерах принцип упаковки и разделения на подпакеты идентичен.
Есть исходный пакет btrfs-progs, то есть исходные коды, расположенные по адресу https://github.com/kdave/btrfs-progs

Как можете наглядно видеть по ссылке «RPM binary: https://abf.io/build_lists/2957703» из одного исходного пакета собраны следующие бинарные, у каждого из которых стоит одинаковое значение %EVRD, то есть эпоха, версия, релиз и дистрибутив (в Альте %EVR вместо %EVRD в Росе):
— btrfs-progs
— libbtrfs0
— libbtrfsutil1

В Debian сделано абсолютно так же, т.к. политика упаковки библиотек в Debian по результирующим пакетам совпадает с Росой (http://wiki.rosalab.ru/ru/index.php/Libraries_policy) и Альтом (https://www.altlinux.org/Shared_Libs_Policy)

В пакете btrfs-progs лежат исполняемые файлы /bin/*:

$ dpkg -L btrfs-progs | grep ^/bin
/bin/btrfs-select-super
/bin/btrfs
/bin/btrfs-image
/bin/btrfs-find-root
/bin/fsck.btrfs
/bin/mkfs.btrfs
/bin/btrfstune
/bin/btrfs-map-logical
/bin/btrfsck

В пакетах с приставкой lib лежат только библиотеки.
В пакете libbtrfs0 лежит библиотека libbtrfs.so.0
Видите, что мажорная версия библиотеки 0 имеется в названии пакета? Это важно, т.к. позволяет в систему поставить одновременно libbtrfs.so.0 (libbtrfs0), libbtrfs.so.1 (libbtrfs1) и т.д.

Есть пакет libbtrfs-devel, обратите внимание, уже без мажорной версии библиотеки в названии. В нем, помимо заголовочных и др. файлов из /usr/include/, находится символическая ссылка libbtrfs.so -> libbtrfs.so.0
Это позволяет при сборке программы линковщику искать не libbtrfs.so.0, а просто libbtrfs.so, а вот результирующий бинарный файл будет слинкован именно с libbtrfs.so.0, а не libbtrfs.so.

И в RPM, и в deb (dh_shlibs) есть механизм автоматического подбора runtime зависимостей. Автоугадава зависимостей смотрит на бинарные файлы, получившиеся в пакете, видит, что они слинкованы с libbtrfs.so.0, поэтому автоугадав смотрит, в каком пакете находится libbtrfs.so.0, а это пакет libbtrfs0, и результирующий бинарный пакет автоматически без участия человека начинает зависеть от пакета с нужными библиотеками.

В примере выше libbtrfs-devel автоматически зависит от libbtrfs0.

Рассмотрим ситуацию, когда нужно опакетить более новую версию библиотеки на примере, как это делается в PPA для Ubuntu. Хороший пример — ffmpeg, https://launchpad.net/~jonathonf/+archive/ubuntu/ffmpeg-4. Механизм аналогичен созданию дополнительного репозитория для ОС «Эльбрус-Д».

В PPA собирается исходный пакет (deb-src) ffmpeg более новой версии, чем в основном репозитории Ubuntu.

В Ubuntu 18.04 в репозитории находится ffmpeg 3.4.4, из исходников которого собираются библиотеки libavcodec.so.57, libavformat.so.57. Соответственно, devel пакет libavcodec-dev содержит симлинк libavcodec.so -> libavcodec.so.57 и зависит от пакета libavcodec57.

Все пакеты в репозитории Ubuntu 18.04 собраны именно с этой версией ffmpeg:

$ readelf -a /usr/bin/mpv | grep NEEDED | awk '{print $NF}' | tr -d '[]' | grep -E 'codec|format'
libavcodec.so.57
libavformat.so.57

Как видно выше, плеер mpv слинкован с libavcodec.so.57, поэтому при сборке пакета автоугадав dh_shlibs автоматически прописал зависимость от libavcodec57. В debian/control пакета mpv нет такой зависимости (https://salsa.debian.org/multimedia-team/mpv/blob/debian/master/debian/control), а вот в debian/control результирующего бинарного пакета такая зависимость есть, и прописана она автоматом, не человеком.

По ссылке https://launchpad.net/~jonathonf/+archive/ubuntu/ffmpeg-4/+packages?field.name_filter=&field.status_filter=published&field.series_filter=bionic можно посмотреть, какие бинарные пакеты получились их исходного пакета ffmpeg.

Видите, что там уже не 57, а 58, однако пакеты libavcodec57 и libavcodec58 не конфликтуют между собой, что позволяет подключить репозиторий с боле новой версией ffmpeg, не ломая зависимости и работу пакетов из остальных репозиториев, ведь libavcodec57 будет доступен из основного репозитория, а libavcodec58 из дополнительного.

Однако пакет libavcodec-dev будет и в основном, и в дополнительном репозитории, в дополнительном будет более новой версии, поэтому по умолчанию будет браться именно он, то есть пакеты, собранные на машине с подключенным жоп. репозиторием станут автоматически зависеть от libavcodec58, которого нет в основном репозитории.

Есть несколько способов это разрулить:
— в своем репозитории libavcodec-dev переименовать в libavcodec58-dev и не указываться «Provides: libavcodec-dev»
— или создать файл /etc/apt/prederences.d/*, в котором в соответствии с apt_preferences(5) для всех или только -dev пакетов своего дополнительного репозитория сделать приоритет от 1 до 100, например, 1; пакеты с таким приоритетом будут устаналиваться, толкьо если их нет в репозиториях с более высоким приоритетом, а если libavcodec-dev есть в основном репозитории с приоритетом 500 более старой версии, чем в дополнительном репозитории с приоритетом 1, установится все равно более старая версия из основного репозитория; узнать подробности про пакет можно командой apt policy libavcodec-dev
— не класть -dev пакеты в дополнительный репозиторий

Первый способ (версия в -dev пакете) применен для libboost в самом Debian: https://packages.debian.org/search?keywords=libboost&searchon=names&suite=unstable&section=all
Это тот редкий случай, когда собрано несколько версий библиотеки параллельно.

Таким образом, пакетная система debian позволяет легко создать дополнительный репозиторий и собрать с ним ПО, не нарушая целостность основного репозитория, в т.ч. сохраняя в нем прежние версии сборочных зависимостей (-dev пакетов).

Отправить ответ

avatar
  Subscribe  
Сообщать по почте