<html><head></head><body style="zoom: 0%;"><div dir="auto">Неплохо было бы, наверное, сразу определить исключения и почему они есть.</div>
<div class="gmail_quote" >На 7 авг. 2025 г., в 17:20, Anton Farygin &lt;<a href="mailto:rider@basealt.ru" target="_blank">rider@basealt.ru</a>&gt; написал:п<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="blue">С Димой поработали над документом, а именно вместо определений появился <br>раздел область действия, детально описывающий применимость данной политики.<br><br><br>{{DraftPolicy<br>|responsible=PavlovKonstantin, AntonFarygin, IgorVlasenko<br>|metabug=repocop тесты library-pkgnames, lib-contains-devel-so<br>}}<br><br>== Shared Libs Policy ==<br><br>=== Цель ===<br><br>Позволить библиотекам с разными несовместимыми ABI-версиями <br>сосуществовать в системе. Это снижает риски поломок при обновлении, <br>упрощает сопровождение и позволяет проводить обновления более гибко.<br><br>'''Кратко''':<br>''Нельзя класть новую библиотеку с новым soname в тот же бинарный пакет, <br>где была старая.''<br><br>=== Область действия ===<br><br>Данная политика распространяется на:<br><br>* '''Публичные разделяемые библиотеки''' — `.so.*`-файлы (например, <br>`<a href="http://libfoo.so">libfoo.so</a>.1`, `<a href="http://libbar.so">libbar.so</a>.2.3`, а также `<a href="http://libbaz-3.1.so">libbaz-3.1.so</a>`), <br>устанавливаемые в стандартные пути для динамического линковщика и <br>предназначенные для использования несколькими независимыми программами. <br>Это определение включает в себя библиотеки с альтернативными схемами <br>именования, в которых ABI-версия зашита непосредственно в имя файла <br>(например, `<a href="http://libname-X.Y.so">libname-X.Y.so</a>`);<br>* '''Пакеты разработки (`-devel`)''', содержащие файлы для компоновки <br>(`<a href="http://libfoo.so">libfoo.so</a>`), заголовочные файлы (`.h`) и другие материалы, необходимые <br>для сборки программ, использующих библиотеку;<br>* '''Общие (`-common`) пакеты''', включающие файлы, не зависящие от ABI, <br>— такие как конфигурационные файлы, ресурсы (иконки, XML, PNG, словари и <br>т.п.), базы данных, скрипты, справочные материалы.<br><br>Политика '''не распространяется''' на:<br><br>* `.so`-файлы, загружаемые конкретным приложением как плагины (например, <br>через `dlopen`);<br>* статические библиотеки (`.a`), если они используются отдельно и не <br>влияют на ABI-совместимость;<br>* библиотеки, являющиеся частью одного монолитного пакета и не <br>предназначенные для переиспользования другими программами (например, <br>`<a href="http://libinternal.so">libinternal.so</a>`, установленная в нестандартный путь и используемая <br>только одним приложением);<br>* библиотеки, собранные как часть одного приложения, устанавливаемые в <br>стандартный путь (например, `/usr/lib64`), но не предназначенные для <br>использования другими программами и не имеющие `-devel` пакета <br>(например, `<a href="http://libmyappsupport.so">libmyappsupport.so</a>.0`, используемая исключительно `myapp`).<br><br>'''Примеры:'''<br>* Под действие политики попадает `<a href="http://libfoo.so">libfoo.so</a>.1`, установленный в <br>`/usr/lib64/`, используемый несколькими приложениями.<br>* Под действие политики также попадает `libfoo-devel`, содержащий <br>`<a href="http://libfoo.so">libfoo.so</a>` и заголовки.<br>* Под действие политики также попадает `libfoo-common`, если в нём <br>находятся ресурсы, применимые ко всем версиям ABI.<br>* Под действие политики также попадает `<a href="http://libbaz-3.1.so">libbaz-3.1.so</a>`, если она <br>используется как разделяемая библиотека.<br>* Не попадает `libplugin_<a href="http://mytask.so">mytask.so</a>`, загружаемый только одним <br>приложением как модуль (plugin).<br>* Не попадает `<a href="http://libinternal.so">libinternal.so</a>`, устанавливаемый в `/opt/myapp/lib/` и <br>используемый исключительно программой `myapp`.<br>* Не попадает `<a href="http://libmyappsupport.so">libmyappsupport.so</a>.0`, установленный в `/usr/lib64`, но <br>используемый только приложением `myapp`, если отсутствует <br>`libmyappsupport-devel`.<br><br>Дополнительную информацию о принципах работы разделяемых библиотек в <br>GNU/Linux-среде можно найти в [Program Library <br>HOWTO](<a href="https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html">https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html</a>).<br><br>=== Упаковка библиотек (runtime часть) ===<br><br>* Каждая несовместимая версия библиотеки должна быть в отдельном <br>бинарном пакете.<br>* Название пакета: `libfoo%abiversion`<br>* Если имя библиотеки заканчивается на цифру, то используется <br>подчёркивание: `libfoo_%abiversion`<br>* В пакете не должно быть файлов с путями, не содержащими номер ABI.<br><br>Если есть общие файлы (напр., man-страницы, примеры), их нужно вынести в <br>`libfoo-common`.<br>*Общий (-common) пакет должен быть только один — он используется всеми <br>ABI-версиями библиотеки.<br>*-common пакет не должен включать файлы, которые зависят от ABI.<br>*Старый (Legacy) ABI-специфичный пакет не должен иметь жёсткой <br>версионированной зависимости (Requires: с конкретной версией) от <br>libfoo-common.<br><br>Пример: [<a href="https://packages.altlinux.org/sisyphus/srpms/libxmlb/specfiles">https://packages.altlinux.org/sisyphus/srpms/libxmlb/specfiles</a>/ <br>libxmlb]<br><br>=== Имя исходного пакета ===<br><br>* Имя **исходного пакета (SRPM)** желательно сохранять таким же, как у <br>апстрима — это упрощает отслеживание обновлений, использование <br>автоматических инструментов (`repology.or`, `repocop`) и повышает <br>предсказуемость.<br><br>* Однако, при обновлении библиотеки с '''ломкой ABI''', когда требуется <br>сохранить в репозитории старую версию библиотеки:<br> &nbsp; * исходный пакет со старой версией нужно **сохранять под отдельным <br>именем** (например, `libfoo1`, `libfoo0`, `libfoo3.2`);<br> &nbsp; * новый ABI собирается уже из SRPM с апстримным именем (`libfoo`), а <br>старый SRPM остаётся в репозитории под переименованным именем.<br><br>* Таким образом, в репозитории могут одновременно присутствовать <br>несколько SRPM, каждый из которых собирает свою версию ABI:<br> &nbsp; - `libfoo` → собирает `libfoo2`, `libfoo-devel`, ...<br> &nbsp; - `libfoo1` → собирает `libfoo1`<br><br>* Для бэкпортов:<br> &nbsp; * имя SRPM должно соответствовать новому ABI;<br> &nbsp; * старые SRPM не модифицируются;<br> &nbsp; * оба SRPM должны собирать бинарные пакеты, которые могут быть <br>установлены параллельно (если это возможно).<br><br>* Как только в репозитории **не останется ни одного пакета**, <br>использующего старую версию ABI:<br> &nbsp; * соответствующий SRPM (и его бинарные пакеты) должен быть **удалён**;<br> &nbsp; * это уменьшает нагрузку на инфраструктуру и снижает риски путаницы;<br> &nbsp; * наличие библиотеки в `System/Legacy libraries` не освобождает от <br>этого требования — она должна быть удалена, если не используется ни <br>одним другим пакетом.<br><br>* Для автоматизации отслеживания можно использовать:<br> &nbsp; * `apt-cache rdepends libfoo1`<br> &nbsp; * скрипты из `repocop` и `srpm-uploader`<br> &nbsp; * веб-интерфейса [<a href="https://packages.altlinux.org">https://packages.altlinux.org</a> <br><a href="http://packages.altlinux.org">packages.altlinux.org</a>] → вкладка пакета '''Аналитика''' → '''Зависящие <br>пакеты'''<br><br>=== development-файлы ===<br><br>* Заголовочные файлы и `.so`-файл без версии (используемый для линковки) <br>должны быть вынесены в отдельный `-devel` пакет.<br><br>* По умолчанию `-devel` пакет должен быть только **один** — и он должен <br>относиться к самой новой версии библиотеки:<br> &nbsp; - `libfoo-devel`<br> &nbsp; - или, если есть несколько версий ABI в системе: <br>`libfoo%abiversion-devel`<br><br>* Поддержка нескольких `-devel` пакетов (например, `libfoo1-devel` и <br>`libfoo2-devel`) допускается **только в исключительных случаях**, когда:<br> &nbsp; - большое количество клиентов ещё не может быть пересобрано под новую <br>библиотеку;<br> &nbsp; - либо API существенно отличается, и одновременная поддержка <br>действительно необходима.<br><br>* В случае одновременного существования нескольких `-devel` пакетов, они <br>должны иметь явные `Conflicts:` друг с другом, чтобы исключить их <br>совместную установку.<br><br>Для `.a` файлов:<br><br>* Если вместе с `.so`: `libfoo-devel-static` или <br>`libfoo%abiversion-devel-static`<br>* Если только `.a`: просто `libfoo-devel`<br><br>Файлы, не предназначенные для линковки, а работающие как плагины <br>(`dlopen`), не попадают под полиси. Пример: `<a href="http://libtcnative-1.so">libtcnative-1.so</a>` из <br>`tomcat-native`.<br><br>Об исключениях стоит сообщать в багзиллу: <br>`altlinux-policy-shared-lib-contains-devel-so`<br><br>=== Пример упаковки разных ABI ===<br><br>Пакет с разными версиями ABI должен содержать только одну из них. Если <br>библиотека имеет несколько .so с разными ABI — каждую версию упаковывают <br>в отдельный пакет.<br><br>Пример: [<a href="https://packages.altlinux.org/sisyphus/srpms/ffmpeg">https://packages.altlinux.org/sisyphus/srpms/ffmpeg</a>/ ffmpeg]<br><br>== Как выбирать %abiversion ==<br><br>Если библиотека использует `soversion` — используем его как %abiversion.<br><br>Если `soversion` отсутствует или нестабилен — используем:<br><br>* возрастающее число: `libfoo0`, `libfoo1`<br>* major-версию: `libqt3`, `libqt4`<br>* major.minor: `libdb4.0`, `libdb4.1`<br>* часть soname: `libcurl4`, `libflac8`<br><br>== Что делать при ломке ABI ==<br><br>Допустим, soname изменился с N на M:<br><br># Переименовать бинарный пакет `libfoo` → `libfooM` (или `libfooN` → <br>`libfooM`)<br># Проверить совместимость при установке:<br> &nbsp; hsh-install libfoo libfooM<br><br>== Поддержка клиентов библиотеки ==<br><br>Рекомендуется иметь только один `-devel` пакет — для самой новой версии.<br><br>Если новая версия несовместима и вызывает ошибки сборки у многих пакетов <br>— допустимо иметь 2 `-devel` пакета с `Conflicts` друг на друга. <br>Зависимые пакеты разделяются по версии сборки.<br><br>Для `libfooM-devel` желательно прописывать:<br> &nbsp; Provides: libfoo-devel = %EVR<br><br>== Старые версии библиотек ==<br><br>* Старые библиотеки помещаются в группу `System/Legacy libraries`.<br>* Они удаляются, если не используются другими пакетами.<br>* Такие пакеты не проходят в [[Branches|стабильные ветки]].<br><br>== Возможные проблемы ==<br><br>* Если два пакета конфликтуют по путям, они не смогут сосуществовать — <br>тогда старую версию нужно удалить, а все зависимости — пересобрать.<br>* Проблемы apt при переименовании пакетов: <br>[<a href="http://lists.altlinux.org/pipermail/devel/2009-May/171113.html">http://lists.altlinux.org/pipermail/devel/2009-May/171113.html</a> пример]<br>* В одной программе могут оказаться разные версии одной библиотеки через <br>цепочку зависимостей (libX → libZ1, libY → libZ2) — возможны трудные для <br>отладки ошибки.<br><br>== Ссылки ==<br>* [[Shared Libs Policy Comments|Комментарий к Shared Libs Policy с <br>пошаговой инструкцией]]<br>* [<a href="https://www.debian.org/doc/debian-policy/ch-sharedlibs.html">https://www.debian.org/doc/debian-policy/ch-sharedlibs.html</a> <br><a href="https://www.debian.org/doc/debian-policy/ch-sharedlibs.html">https://www.debian.org/doc/debian-policy/ch-sharedlibs.html</a>]<br>* [[API or ABI changing|Смена API/ABI]]<br>* [[Shared Libs Policy and updates|Данное полиси и обновления]]<br>* [[Shared Library Symbol Versioning HOWTO]]<br><hr><br>Devel mailing list<br>Devel@lists.altlinux.org<br><a href="https://lists.altlinux.org/mailman/listinfo/devel">https://lists.altlinux.org/mailman/listinfo/devel</a></pre></blockquote></div></body></html>