ALT Linux Team development discussions
 help / color / mirror / Atom feed
From: Anton Farygin <rider@basealt.ru>
To: devel@lists.altlinux.org
Subject: Re: [devel] переработанный документ SharedLibsPolicy (update 2)
Date: Thu, 28 Aug 2025 11:33:38 +0300
Message-ID: <4fb1ca0e-22d3-410a-9f53-46e7812de209@basealt.ru> (raw)
In-Reply-To: <6f69d759-c000-4cd3-a66d-94fcd2245fb3@basealt.ru>

Перечитал всё обсуждение и внёс изменения.

в исправления немного косметики в разделе Возможные проблемы, но 
основное изменение в разделе про упаковку runtime части библиотек - 
переформулирована фраза про файлы, плюс добавлено правило, явным образом 
запрещающее миграцию библиотеки с одним и тем же soname из одного 
бинарного пакета в другой (что бы исключить проблемы с обновлениями, 
описанные в ссылке из этого документа 
http://lists.altlinux.org/pipermail/devel/2009-May/171113.html

Посмотрите пожалуйста, устраивает ли новая формулировка или  она 
всё-также тяжела для понимания.


{{DraftPolicy
|responsible=PavlovKonstantin, AntonFarygin, IgorVlasenko
|metabug=repocop тесты library-pkgnames, lib-contains-devel-so
}}

== Shared Libs Policy ==

=== Цель ===

Позволить пакетам с библиотеками с разными несовместимыми ABI-версиями 
сосуществовать в системе. Это снижает риски поломок при обновлении, 
упрощает сопровождение и позволяет проводить обновления более гибко.

'''Кратко''':
''Нельзя класть новую библиотеку с новым soname в тот же бинарный пакет, 
где была старая.''

=== Область действия ===

Данная политика распространяется на:

* '''Публичные разделяемые библиотеки''' — `.so.*`-файлы (например, 
`libfoo.so.1`, `libbar.so.2.3`, а также `libbaz-3.1.so`), 
устанавливаемые в стандартные пути для динамического линковщика и 
предназначенные для использования несколькими независимыми программами. 
Это определение включает в себя библиотеки с альтернативными схемами 
именования, в которых ABI-версия зашита непосредственно в имя файла 
(например, `libname-X.Y.so`);
* '''Пакеты разработки (`-devel`)''', содержащие файлы для компоновки 
(`libfoo.so`), заголовочные файлы (`.h`) и другие материалы, необходимые 
для сборки программ, использующих библиотеку;
* '''Общие (`-common`) пакеты''', включающие файлы, не зависящие от ABI, 
— такие как конфигурационные файлы, ресурсы (иконки, XML, PNG, словари и 
т.п.), базы данных, скрипты, справочные материалы.

Политика '''не распространяется''' на:

* `.so`-файлы, загружаемые конкретным приложением как плагины (например, 
через `dlopen`);
* статические библиотеки (`.a`), если они используются отдельно и не 
влияют на ABI-совместимость;
* библиотеки, являющиеся частью одного монолитного пакета и не 
предназначенные для переиспользования другими программами (например, 
`libinternal.so`, установленная в нестандартный путь и используемая 
только одним приложением);
* библиотеки, собранные как часть одного приложения, устанавливаемые в 
стандартный путь (например, `/usr/lib64`), но не предназначенные для 
использования другими программами и не имеющие `-devel` пакета 
(например, `libmyappsupport.so.0`, используемая исключительно `myapp`).

'''Примеры:'''
* Под действие политики попадает `libfoo.so.1`, установленный в 
`/usr/lib64/`, используемый несколькими приложениями.
* Под действие политики также попадает `libfoo-devel`, содержащий 
`libfoo.so` и заголовки.
* Под действие политики также попадает `libfoo-common`, если в нём 
находятся ресурсы, применимые ко всем версиям ABI.
* Под действие политики также попадает `libbaz-3.1.so`, если она 
используется как разделяемая библиотека.
* Не попадает `libplugin_mytask.so`, загружаемый только одним 
приложением как модуль (plugin).
* Не попадает `libinternal.so`, устанавливаемый в `/opt/myapp/lib/` и 
используемый исключительно программой `myapp`.
* Не попадает `libmyappsupport.so.0`, установленный в `/usr/lib64`, но 
используемый только приложением `myapp`, если отсутствует 
`libmyappsupport-devel`.

Дополнительную информацию о принципах работы разделяемых библиотек в 
GNU/Linux-среде можно найти в [Program Library 
HOWTO](https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html).

=== Упаковка библиотек (runtime часть) ===

* Пакеты библиотек должны размещать файлы так (через уникальные имена и 
отдельные каталоги), чтобы разные ABI-версии можно было установить в 
систему одновременно
* Каждая несовместимая версия библиотеки должна быть в отдельном 
бинарном пакете.
* Название пакета: `libfoo%abiversion`
* Если имя библиотеки заканчивается на цифру, то используется 
подчёркивание: `libfoo_%abiversion`
* Библиотека с одним и тем же ABI не должна переходить из одного пакета 
в другой. Исключение допускается только при приведении пакета к 
требованиям SharedLibsPolicy. Это очень сложный процесс и идеально 
делать такое изменение при смене soname бибиотеки.


Если есть общие файлы (напр., man-страницы, примеры), их нужно вынести в 
`libfoo-common`.
*Общий (-common) пакет должен быть только один — он используется всеми 
ABI-версиями библиотеки.
*-common пакет не должен включать файлы, которые зависят от ABI.
*Старый (Legacy) ABI-специфичный пакет не должен иметь жёсткой 
версионированной зависимости (Requires: с конкретной версией) от 
libfoo-common.

Пример: [https://packages.altlinux.org/sisyphus/srpms/libxmlb/specfiles/ 
libxmlb]

=== Имя исходного пакета ===

* Имя **исходного пакета (SRPM)** желательно сохранять таким же, как у 
апстрима — это упрощает отслеживание обновлений, использование 
автоматических инструментов (`repology.or`, `repocop`) и повышает 
предсказуемость.

* Однако, при обновлении библиотеки с '''ломкой ABI''', когда требуется 
сохранить в репозитории старую версию библиотеки:
   * исходный пакет со старой версией нужно **сохранять под отдельным 
именем** (например, `libfoo1`, `libfoo0`, `libfoo3.2`);
   * новый ABI собирается уже из SRPM с апстримным именем (`libfoo`), а 
старый SRPM остаётся в репозитории под переименованным именем.

* Таким образом, в репозитории могут одновременно присутствовать 
несколько SRPM, каждый из которых собирает свою версию ABI:
   - `libfoo` → собирает `libfoo2`, `libfoo-devel`, ...
   - `libfoo1` → собирает `libfoo1`

* Для бэкпортов:
   * имя SRPM должно соответствовать новому ABI;
   * старые SRPM не модифицируются;
   * оба SRPM должны собирать бинарные пакеты, которые могут быть 
установлены параллельно (если это возможно).

* Как только в репозитории **не останется ни одного пакета**, 
использующего старую версию ABI:
   * соответствующий SRPM (и его бинарные пакеты) должен быть **удалён**;
   * это уменьшает нагрузку на инфраструктуру и снижает риски путаницы;
   * наличие библиотеки в `System/Legacy libraries` не освобождает от 
этого требования — она должна быть удалена, если не используется ни 
одним другим пакетом.

* Для автоматизации отслеживания можно использовать:
   * `apt-cache rdepends libfoo1`
   * скрипты из `repocop` и `srpm-uploader`
   * веб-интерфейса [https://packages.altlinux.org 
packages.altlinux.org] → вкладка пакета '''Аналитика''' → '''Зависящие 
пакеты'''

=== development-файлы ===

* Заголовочные файлы и `.so`-файл без версии (используемый для линковки) 
должны быть вынесены в отдельный `-devel` пакет.

* По умолчанию `-devel` пакет должен быть только **один** — и он должен 
относиться к самой новой версии библиотеки:
   - `libfoo-devel`
   - или, если есть несколько версий ABI в системе: 
`libfoo%abiversion-devel`

* Поддержка нескольких `-devel` пакетов (например, `libfoo1-devel` и 
`libfoo2-devel`) допускается **только в исключительных случаях**, когда:
   - большое количество клиентов ещё не может быть пересобрано под новую 
библиотеку;
   - либо API существенно отличается, и одновременная поддержка 
действительно необходима.

* В случае одновременного существования нескольких `-devel` пакетов, они 
должны иметь явные `Conflicts:` друг с другом, чтобы исключить их 
совместную установку.

Для `.a` файлов:

* Если вместе с `.so`: `libfoo-devel-static` или 
`libfoo%abiversion-devel-static`
* Если только `.a`: просто `libfoo-devel`

Файлы, не предназначенные для линковки, а работающие как плагины 
(`dlopen`), не попадают под полиси. Пример: `libtcnative-1.so` из 
`tomcat-native`.

Об исключениях стоит сообщать в багзиллу: 
`altlinux-policy-shared-lib-contains-devel-so`

=== Пример упаковки разных ABI ===

Пакет с разными версиями ABI должен содержать только одну из них. Если 
библиотека имеет несколько .so с разными ABI — каждую версию упаковывают 
в отдельный пакет.

Пример: [https://packages.altlinux.org/sisyphus/srpms/ffmpeg/ ffmpeg]

== Как выбирать %abiversion ==

Если библиотека использует `soversion` — используем его как %abiversion.

Если `soversion` отсутствует или нестабилен — используем:

* возрастающее число: `libfoo0`, `libfoo1`
* major-версию: `libqt3`, `libqt4`
* major.minor: `libdb4.0`, `libdb4.1`
* часть soname: `libcurl4`, `libflac8`

== Что делать при ломке ABI ==

Допустим, soname изменился с N на M:

# Переименовать бинарный пакет `libfoo` → `libfooM` (или `libfooN` → 
`libfooM`)
# Проверить совместимость при установке:
   hsh-install libfoo libfooM

== Поддержка клиентов библиотеки ==

Рекомендуется иметь только один `-devel` пакет — для самой новой версии.

Если новая версия несовместима и вызывает ошибки сборки у многих пакетов 
— допустимо иметь 2 `-devel` пакета с `Conflicts` друг на друга. 
Зависимые пакеты разделяются по версии сборки.

Для `libfooM-devel` желательно прописывать:
   Provides: libfoo-devel = %EVR

== Старые версии библиотек ==

* Старые библиотеки помещаются в группу `System/Legacy libraries`.
* Они удаляются, если не используются другими пакетами.
* Такие пакеты не проходят в [[Branches|стабильные ветки]].

== Возможные проблемы ==

* Если разные пакеты с ABI-версиями библиотек устанавливают файлы в один 
и тот же путь, они будут мешать друг другу (конфликтовать при 
обновлении). В такой ситуации нужно:
#Удалить старую версию;
#Исправить новую версию так, чтобы она соответствовала SharedLibsPolicy;
#Пересобрать все пакеты, которые зависят от этой библиотеки.

* Проблемы apt при переименовании пакетов: 
[http://lists.altlinux.org/pipermail/devel/2009-May/171113.html пример]
* В одной программе могут оказаться разные версии одной библиотеки через 
цепочку зависимостей (libX → libZ1, libY → libZ2) — возможны трудные для 
отладки ошибки.

== Ссылки ==
* [[Shared Libs Policy Comments|Комментарий к Shared Libs Policy с 
пошаговой инструкцией]]
* [https://www.debian.org/doc/debian-policy/ch-sharedlibs.html 
https://www.debian.org/doc/debian-policy/ch-sharedlibs.html]
* [[API or ABI changing|Смена API/ABI]]
* [[Shared Libs Policy and updates|Данное полиси и обновления]]
* [[Shared Library Symbol Versioning HOWTO]]



      parent reply	other threads:[~2025-08-28  8:33 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-07 11:46 [devel] переработанный документ SharedLibsPolicy Anton Farygin
2025-08-07 12:57 ` Dmitry V. Levin
2025-08-07 13:09   ` Anton Farygin
2025-08-08 20:19   ` Vitaly Chikunov
2025-08-16  7:10   ` [devel] " Sergey
2025-08-07 14:20 ` [devel] переработанный документ SharedLibsPolicy (update 1) Anton Farygin
2025-08-08  7:25     ` Anton Farygin
2025-08-14 10:33   ` Ivan A. Melnikov
2025-08-14 19:31     ` Vitaly Chikunov
2025-08-16  7:15       ` [devel] " Sergey
2025-08-18  9:13       ` [devel] " Anton Farygin
2025-08-18  9:41         ` Dmitry V. Levin
2025-08-18 10:25           ` Ivan A. Melnikov
2025-08-20  6:35             ` [devel] " Sergey V Turchin
2025-08-15  6:21     ` [devel] " Vitaly Chikunov
2025-08-15  6:35       ` Ivan A. Melnikov
2025-08-15  6:37         ` Anton Midyukov
2025-08-15  7:40         ` Vitaly Chikunov
2025-08-15  8:27           ` Vitaly Chikunov
2025-08-18  9:16         ` Anton Farygin
2025-08-16  7:19       ` [devel] " Sergey
2025-08-16  7:17     ` Sergey
2025-08-28  8:33 ` Anton Farygin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4fb1ca0e-22d3-410a-9f53-46e7812de209@basealt.ru \
    --to=rider@basealt.ru \
    --cc=devel@lists.altlinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

ALT Linux Team development discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
		devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
	public-inbox-index devel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git