From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=basealt.ru; s=dkim; t=1754576426; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=geLtEb//px4+F8o1ZTn7l3JsnszyzlAzobqcFoJqq/c=; b=csPbkC6qWyYz18QIiBLLf8b7J3tYsirwI4aK6Lm4hhKtcYGfwT7PkOvX0BcLyqQ4StSQeu 1NZ8NbPWX93SjzJPiZv/VJ1gLUyqR7D/1em73+WeyD6vVs1cy6gcIRRODyCwslOeWAFDS5 12AvvhBLTDrtTl5dA07hyNBDt5E9Gez4b875u8WQ/XXxr6iodCWuEB7ANa641XpsWVcRN3 9xdDiLnV38qg57C4D1jTBkwVgAlx1CGXvB+jDfw5DK8PSBl5oTGIQR0ZGE5l8mn/HOazeH v4LLppmMaMIh++agDoc5q5vQiWWHcMgPf5AQny18Tg4HEEdjta10Mwo7Yghv3g== Message-ID: Date: Thu, 7 Aug 2025 17:20:26 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: devel@lists.altlinux.org References: <6f69d759-c000-4cd3-a66d-94fcd2245fb3@basealt.ru> Content-Language: ru From: Anton Farygin Organization: BaseALT In-Reply-To: <6f69d759-c000-4cd3-a66d-94fcd2245fb3@basealt.ru> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [devel] =?utf-8?b?0L/QtdGA0LXRgNCw0LHQvtGC0LDQvdC90YvQuSDQtNC+?= =?utf-8?b?0LrRg9C80LXQvdGCIFNoYXJlZExpYnNQb2xpY3kgKHVwZGF0ZSAxKQ==?= X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Aug 2025 14:20:31 -0000 Archived-At: List-Archive: List-Post: С Димой поработали над документом, а именно вместо определений появился раздел область действия, детально описывающий применимость данной политики. {{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 часть) === * Каждая несовместимая версия библиотеки должна быть в отдельном бинарном пакете. * Название пакета: `libfoo%abiversion` * Если имя библиотеки заканчивается на цифру, то используется подчёркивание: `libfoo_%abiversion` * В пакете не должно быть файлов с путями, не содержащими номер ABI. Если есть общие файлы (напр., 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|стабильные ветки]]. == Возможные проблемы == * Если два пакета конфликтуют по путям, они не смогут сосуществовать — тогда старую версию нужно удалить, а все зависимости — пересобрать. * Проблемы 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]]