Глава 10. Продвинутые темы работы над пакетом

# Глава 10. Продвинутые темы работы над пакетом

Let’s describe advanced topics on Debian packaging.

## 10.1. Historical perspective

Let me oversimplify historical perspective of Debian packaging practices focused on the non-native packaging.

Debian was started in 1990s when upstream packages were available from public FTP sites such as Sunsite. In those early days, Debian packaging used Debian source format currently known as the Debian source format «1.0»:

- The Debian source package ships a set of files for the Debian source package.

  - package_version.orig.tar.xz : symlink to or copy of the upstream released file.
  - package_version-revision.diff.gz : «One big patch» for Debian modifications.
  - package_version-revision.dsc : package description.
- Several workaround approaches such as dpatch, dbs, or cdbs were deployed to manage multiple topic patches.

The modern Debian source format «3.0 (quilt)» was invented around 2008 (see «ProjectsDebSrc3.0»):

- The Debian source package ships a set of files for the Debian source package.

  - package_version.orig.tar.?z : symlink to or copy of the upstream released file.

  - package_version-revision.debian.tar.?z : tarball of debian/ for Debian modifications.

    - The debian/source/format file contains «3.0 (quilt)».
    - Optional multiple topic patches are stored in the debian/patches/ directory.
  - package_version-revision.dsc : package description.
- The standardized approach to manage multiple topic patches using quilt(1) is deployed for the Debian source format «3.0 (quilt)».

Most Debian packages adopted the Debian source formats «3.0 (quilt)» and «3.0 (native)».

Now, the git(1) is popular with upstream and Debian developers. The git and its associated tools are important part of the modern Debian packaging workflow. This modern workflow involving git will be mentioned later in «Глава 11, Packaging with git».

## 10.2. Current trends

Current Debian packaging practices and their trends are moving target. See:

- «Debian Trends»— Hints for «De facto standard» of Debian practices

  - Build systems: dh
  - Debian source format: «3.0 (quilt)»
  - VCS: git
  - VCS Hosting: salsa
  - Rules-Requires-Root: adopted, fakeroot
  - Copyright format: DEP-5
- «debhelper-compat-upgrade-checklist(7) manpage»— Upgrade checklist for debhelper
- «DEP - Debian Enhancement Proposals»— Formal proposals to enhance Debian

You can also search entire Debian source code data by yourself, too.

- «Debian Sources»— code search tool

  - «Debian Code Search»— wiki page describing its usage
- «Debian Code Search»— another code search tool

## 10.3. Note on build system

Auto-generated files of the build system may be found in the released upstream tarball. These should be regenerated when Debian package is build. E.g.:

- «dh $@ --with autoreconf» should be used in the debian/rules if Autotools (autoconf + automake) are used.

Some modern build system may be able to download required source codes and binary files from arbitrary remote hosts to satisfy build requirements. Don’t use this download feature. The official Debian package is required to be build only with packages listed in Build-Depends: of the debian/control file.

## 10.4. Непрерывная интеграция

The dh_auto_test(1) command is a debhelper command that tries to automatically run the test suite provided by the upstream developer during the Debian package building process.

The autopkgtest(1) command can be used after the Debian package building process. It tests generated Debian binary packages in the virtual environment using the debian/tests/control RFC822-style metadata file as continuous integration (CI). See:

- Documents in the /usr/share/doc/autopkgtest/ directory
- «4. autopkgtest: Automatic testing for packages» of the «Ubuntu Packaging Guide»

Кроме того, в Debian существует ещё несколько других инструментов непрерывной интеграции.

- The Salsa offers «Раздел 11.3, «Salsa CI service»».
- The debci package: CI platform on top of the autopkgtest package
- Пакет jenkins: платформа непрерывной интеграции общего назначения

## 10.5. Предзагрузка

Debian cares about supporting new ports or flavours. The new ports or flavours require bootstrapping operation for the cross-build of the initial minimal native-building system. In order to avoid build-dependency loops during bootstrapping, the build-dependency needs to be reduced using the DEB_BUILD_PROFILES environment variable.

See Debian wiki: «BuildProfileSpec».

| Подсказка
If a core package foo build depends on a package bar with deep build dependency chains but bar is only used in the test target in foo, you can safely mark the bar with <!nocheck> in the Build-depends of foo to avoid build loops.

## 10.6. Усиление безопасности компилятора

The compiler hardening support spreading for Debian jessie (8.0) demands that we pay extra attention to the packaging.

Вам следует подробно изнакомиться со следующей справочной документацией:

- Debian wiki: «Hardening»
- Debian wiki: «Hardening Walkthrough»

Команда debmake добавляет шаблонные комментарии в файл debian/rules, требующиеся для DEB_BUILD_MAINT_OPTIONS, DEB_CFLAGS_MAINT_APPEND и DEB_LDFLAGS_MAINT_APPEND (см. «Глава 5, Simple packaging» и dpkg-buildflags(1)).

## 10.7. Повторяемая сборка

Here are some recommendations to attain a reproducible build result.

- Не включайте в результат временную метку на основе системного времени.
- Don’t embed the file path of the build environment.
- Use «dh $@» in the debian/rules to access the latest debhelper features.
- Export the build environment as «LC_ALL=C.UTF-8» (see «Раздел 12.1, «Сборка с использованием кодировки UTF-8»»).
- Set the timestamp used in the upstream source from the value of the debhelper-provided environment variable $SOURCE_DATE_EPOCH.

- Подробности можно найти на вики-странице «ReproducibleBuilds».

  - «Руководство ReproducibleBuilds».
  - «ReproducibleBuilds TimestampsProposal».

Reproducible builds are important for security and quality assurance. They allow independent verification that no vulnerabilities or backdoors have been introduced during the build process.

Управляющий файл имя-исходного-кода_версия-исходного-кода_архитектура.buildinfo, создаваемый dpkg-genbuildinfo(1), содержит информацию о сборочном окружении. См. deb-buildinfo(5)

## 10.8. Переменные подстановки

Кроме того, файл debian/control определяет зависимости пакета, в которых может исопльзоваться «механизм подстановки переменных» (substvar), который освобождает сопровождающих пакета от рутинной работы по отслеживанию большинства простых зависимостей пакета. См. deb-substvars(5).

The debmake command supports the following substvars:

- ${misc:Depends} для всех двоичных пакетов
- ${misc:Pre-Depends} для всех мультиархитектурных пакетов
- ${shlibs:Depends} для всех двоичных пакетов с исполняемыми файлами и пакетов библиотек
- ${python:Depends} для всех пакетов с кодом на языке Python
- ${python3:Depends} для всех пакетов с кодом на языке Python3
- ${perl:Depends} для всех пакетов с кодом на языке Perl
- ${ruby:Depends} для всех пакетов с кодом на языке Ruby

For the shared library, required libraries found simply by «objdump -p /path/to/program | grep NEEDED» are covered by the shlib substvar.

For Python and other interpreters, required modules found simply looking for lines with «import», «use», «require», etc., are covered by the corresponding substvars.

Для остальных программ, не использующих собственные переменные подстановки, зависимости обрабатываются переменной misc.

Для программ командной оболочки POSIX нет простого способа определения зависимостей, поэтому их зависимости не обрабатываются никакой переменной.

Для библиотек и модулей, требующихся через механизм динамической загрузки, включая механизм «GObject-интроспекция», нет простого способа определения зависимостей, поэтому их зависимости не обрабатываются никакой переменной.

## 10.9. Пакет библиотеки

Packaging library software requires you to perform much more work than usual. Here are some reminders for packaging library software:

- The library binary package must be named as in «Раздел 10.17, «Library package name»».
- Debian ships shared libraries such as /usr/lib/<triplet>/lib foo-0.1.so.1.0.0 (see «Раздел 10.10, «Multiarch»»).
- Debian encourages using versioned symbols in the shared library (see «Раздел 10.16, «Библиотека символов»»).
- Debian не поставляет libtool-архивы библиотек *.la.
- Debian discourages using and shipping *.a static library files.

Before packaging shared library software, see:

- «Chapter 8 - Shared libraries» of the «Debian Policy Manual»
- «10.2 Libraries» of the «Debian Policy Manual»
- «6.7.2. Libraries» of the «Debian Developer’s Reference»

Для получения исторических сведений обратитесь к следующей документации:

- «Спасение из ада зависимостей» [18]

  - This encourages having versioned symbols in the shared library.

- «Debian Library Packaging guide» [19]

  - Please read the discussion thread following its announcement, too.

## 10.10. Multiarch

Multiarch support for cross-architecture installation of binary packages (particularly i386 and amd64, but also other combinations) in the dpkg and apt packages introduced in Debian wheezy (7.0, May 2013), demands that we pay extra attention to packaging.

Вам следует подробно изнакомиться со следующей справочной документацией:

- Ubuntu вики (основная ветка разработки)

  - «MultiarchSpec»

- Debian вики (ситуация в Debian)

  - «Поддержка мультиархитектурности в Debian»
  - «Multiarch/Implementation»

Мультиархитектурность включается с помощью значения <тройки> вида i386-linux-gnu или x86_64-linux-gnu в пути установки разделяемых библиотек вида /usr/lib/<тройка>/ и т. д.

- Значение <тройки>, внутренне необходимое для сценариев debhelper, устанавливается самими сценариями неявно. Сопровождающему не нужно об этом беспокоиться.

- The <triplet> value used in override_dh_* target scripts must be explicitly set in the debian/rules file by the maintainer. The <triplet> value is stored in the $(DEB_HOST_MULTIARCH) variable in the following debian/rules snippet example:

      DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
      ...
      override_dh_install:
      	mkdir -p package1/lib/$(DEB_HOST_MULTIARCH)
      	cp -dR tmp/lib/. package1/lib/$(DEB_HOST_MULTIARCH)

См.:

- «Раздел 9.3, «Variables for debian/rules»»
- «Раздел 16.2, «debmake -b»»
- «Раздел 10.12, «Сценарии и примеры разделения пакета»»
- «dpkg-architecture(1) manpage»

## 10.11. Split of a Debian binary package

For well behaving build systems, the split of a Debian binary package into small ones can be realized as follows.

- Создайте записи с определениями метаданных двоичных пакетах в файле debian/control для всех двоичных пакетов.
- Укажите все пути к файлам (относительно каталга debian/tmp) в соответствующих файлах debian/двоичныйпакет.install.

С примерами можно ознакомиться в настоящем руководстве:

- «Раздел 14.11, «Autotools (multi-binary package)»» (на основе Autotools)
- «Раздел 14.12, «CMake (multi-binary package)»» (на основе CMake)

An intuitive and flexible method to create the initial template debian/control file defining the split of the Debian binary packages is accommodated with the -b option. See «Раздел 16.2, «debmake -b»».

## 10.12. Сценарии и примеры разделения пакета

Ниже приводится несколько типичных сценариев разделения мультиархитектурного пакета для следующих примеров исходного кода основной ветки разработки, в которых используется команда debmake:

- a library source libfoo-1.0.tar.xz
- a tool source bar-1.0.tar.xz written in a compiled language
- a tool source baz-1.0.tar.xz written in an interpreted language

двоичныйпакет | тип | Architecture: | Multi-Arch: | Содержимое пакета
--- | --- | --- | --- | ---
lib foo1 | lib* | any | same | разделяемая бибиотека, возможна совместная установка
lib foo-dev | dev* | any | same | заголовочные файлы разделяемой библиотеки и проч., возможна совместная установка
lib foo-tools | bin* | any | foreign | программы с поддержкой времени исполнения, совместная установка невозможна
lib foo-doc | doc* | all | foreign | файлы документации разделяемой библиотеки
bar | bin* | any | foreign | скомпилированный файлы программы, совместная устанвка невозможна
bar-doc | doc* | all | foreign | файлы документации программы
baz | script | all | foreign | файлы интерпретируемой программы

## 10.13. Multiarch library path

Debian policy requires to comply with the «Filesystem Hierarchy Standard (FHS), version 3.0», with the exceptions noted in «File System Structure».

The most notable exception is the use of /usr/lib/<triplet>/ instead of /usr/lib<qual>/ (e.g., /lib32/ and /lib64/) to support a multiarch library.

Таблица 10.1. Опции путя мультиархитектурных библиотек

Классический путь | Мультиархитектурный путь для i386 | Мультиархитектуный путь для amd64
--- | --- | ---
/lib/ | /lib/i386-linux-gnu/ | /lib/x86_64-linux-gnu/
/usr/lib/ | /usr/lib/i386-linux-gnu/ | /usr/lib/x86_64-linux-gnu/

Для пакетов на основе Autotools, в которых используется пакет debhelper с (compat>=9), установка этого пути выполняется автоматически с помощью команды dh_auto_configure.

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

- If «./configure» is used in the override_dh_auto_configure target in debian/rules, make sure to replace it with «dh_auto_configure --» while re-targeting the install path from /usr/lib/ to /usr/lib/$(DEB_HOST_MULTIARCH)/.
- Замените все пути с /usr/lib/ на /usr/lib/*/ в файлах debian/foo.install.

All files installed simultaneously as the multiarch package to the same file path should have exactly the same file content. You must be careful with differences generated by the data byte order and by the compression algorithm.

Файлы разделяемых библиотек, расположенные в каталогах по умолчанию, /usr/lib/ и /usr/lib/<тройка>/, загружаются автоматически.

For shared library files in another path, the GCC option -l must be set by the pkg-config command to make them load properly.

## 10.14. Multiarch header file path

В мультиархитектурной системе Debian GCC по умолчанию включает и /usr/include/, и /usr/include/<тройка>/.

If the header file is not in those paths, the GCC option -I must be set by the pkg-config command to make "#include <foo.h>" work properly.

Таблица 10.2. Опции пути мультиархитектурного заголовочного файла

Классический путь | Мультиархитектурный путь для i386 | Мультиархитектуный путь для amd64
--- | --- | ---
/usr/include/ | /usr/include/i386-linux-gnu/ | /usr/include/x86_64-linux-gnu/
/usr/include/имяпакета/ | /usr/include/i386-linux-gnu/имяпакета/ | /usr/include/x86_64-linux-gnu/имяпакета/
| /usr/lib/i386-linux-gnu/имяпакета/ | /usr/lib/x86_64-linux-gnu/имяпакета/

The use of the /usr/lib/<triplet>/packagename/ path for the library files allows the upstream maintainer to use the same install script for the multiatch system with /usr/lib/<triplet> and the biarch system with /usr/lib<qual>/. [20]

The use of the file path containing packagename enables having more than 2 development libraries simultaneously installed on a system.

## 10.15. Multiarch *.pc file path

Программа pkg-config используется для получения информации об установленных в системе библиотеках. Она сохраняет свои параметры настройки в файле *.pc и используется для установки опций -I и -l для GCC.

Таблица 10.3. Опции пути к файлу *.pc

Классический путь | Мультиархитектурный путь для i386 | Мультиархитектуный путь для amd64
--- | --- | ---
/usr/lib/pkgconfig/ | /usr/lib/i386-linux-gnu/pkgconfig/ | /usr/lib/x86_64-linux-gnu/pkgconfig/

## 10.16. Библиотека символов

The symbols support in dpkg introduced in Debian lenny (5.0, May 2009) helps us to manage the backward ABI compatibility of the library package with the same package name. The DEBIAN/symbols file in the binary package provides the minimal version associated with each symbol.

An oversimplified method for the library packaging is as follows.

- Extract the old DEBIAN/symbols file of the immediate previous binary package with the «dpkg-deb -e» command.

  - Либо можно использовать команду mc для распаковки файла DEBIAN/symbols.

- Скопируйте его в файл debian/двоичныйпакет.symbols.

  - Если это первый пакет, то используйте пустой файл.

- Соберите двоичный пакет.

  - If the dpkg-gensymbols command warns about some new symbols:

    - Extract the updated DEBIAN/symbols file with the «dpkg-deb -e» command.
    - Удалите номер редакции версии Debian, например, -1, из файла.
    - Скопируйте его в файл debian/двоичныйпакет.symbols.
    - Повторно соберите двоичный пакет.

  - If the dpkg-gensymbols command does not warn about new symbols:

    - Работа с библиотекой завершена.

Подробные сведения можно получить, обратившись к следующей справочной информации:

- «8.6.3 The symbols system» of the «Debian Policy Manual»
- «dh_makeshlibs(1) manapage»
- «dpkg-gensymbols(1) manapage»
- «dpkg-shlibdeps(1) manapage»
- «deb-symbols(5) manapage»

Также следует ознакомиться со следующей документацией:

- Debian wiki: «UsingSymbolsFiles»
- Debian wiki: «Projects/ImprovedDpkgShlibdeps»
- Debian kde team: «Working with symbols files»
- «Раздел 14.11, «Autotools (multi-binary package)»»
- «Раздел 14.12, «CMake (multi-binary package)»»

| Подсказка
For C++ libraries and other cases where the tracking of symbols is problematic, follow «8.6.4 The shlibs system» of the «Debian Policy Manual», instead. Please make sure to erase the empty debian/binarypackage.symbols file generated by the debmake command. For this case, the DEBIAN/shlibs file is used.

## 10.17. Library package name

Let’s consider that the upstream source tarball of the lib foo library is updated from lib foo-7.0.tar.xz to lib foo-8.0.tar.xz with a new SONAME major version which affects other packages.

The binary library package must be renamed from lib foo7 to lib foo8 to keep the unstable suite system working for all dependent packages after the upload of the package based on the lib foo-8.0.tar.xz.

| Предупреждение
If the binary library package isn’t renamed, many dependent packages in the unstable suite become broken just after the library upload even if a binNMU upload is requested. The binNMU may not happen immediately after the upload due to several reasons.

Пакет -dev должен соответствовать следующим правилам именования:

- Используйте имя пакета -dev без номера версии: lib foo-dev

  - This is the typical one for leaf library packages.

  - В архиве может находится только одна версия пакета с исходным кодом библиотеки.

    - The associated library package needs to be renamed from lib foo7 to lib foo8 to prevent dependency breakage in the unstable suite during the library transition.
  - This approach should be used if the simple binNMU resolves the library dependency quickly for all affected packages. (ABI change by dropping the deprecated API while keeping the active API unchanged.)
  - This approach may still be a good idea if manual code updates, etc. can be coordinated and manageable within limited packages. (API change)

- Используйте имена пакетов -dev с указанием версии: lib foo7-dev и lib foo8-dev

  - This is typical for many major library packages.

  - В архиве могут находится две версии пакетов с исходным кодом библиотеки.

    - Все зависимые пакет должны зависить от lib foo-dev.
    - Пусть и lib foo7-dev, и lib foo8-dev предоставляют lib foo-dev.
    - The source package needs to be renamed as lib foo7-7.0.tar.xz and lib foo8-8.0.tar.xz respectively from lib foo-?.0.tar.xz.
    - В зависимости от пакета путь установки файлов, включающий lib foo7 и lib foo8, соответственно, для заголовочных файлов и проч., следует выбирать так, чтобы их можно было установить одновременно.
  - По возможности не используйте слишком жёсткий подход.
  - This approach should be used if the update of multiple dependent packages require manual code updates, etc. (API change) Otherwise, the affected packages become RC buggy with FTBFS (Fails To Build From Source).

| Подсказка
If the data encoding scheme changes (e.g., latin1 to utf-8), the same care as the API change needs to be taken.

См. «Раздел 10.9, «Пакет библиотеки»».

## 10.18. Смена библиотек

When you package a new library package version which affects other packages, you must file a transition bug report against the release.debian.org pseudo package using the reportbug command with the ben file and wait for the approval for its upload from the Release Team.

У команды подготовки выпуска имеется «система отслеживания переходов». См. «Transitions».

| Внимание
Please make sure to rename binary packages as in «Раздел 10.17, «Library package name»».

## 10.19. Безопасная binNMU-загрузка

A «binNMU» is a binary-only non-maintainer upload performed for library transitions etc. In a binNMU upload, only the «Architecture: any» packages are rebuilt with a suffixed version number (e.g. version 2.3.4-3 will become 2.3.4-3+b1). The «Architecture: all» packages are not built.

The dependency defined in the debian/control file among binary packages from the same source package should be safe for the binNMU. This needs attention if there are both «Architecture: any» and «Architecture: all» packages involved in it.

- «Architecture: any» package: depends on «Architecture: any» foo package

  - Depends: foo (= ${binary:Version})

- «Architecture: any» package: depends on «Architecture: all» bar package

  - Depends: bar (= ${source:Version})

- «Architecture: all» package: depends on «Architecture: any» baz package

  - Depends: baz (>= ${source:Version}), baz (<< ${source:Version}.0~)

## 10.20. Отладочная информация

The Debian package is built with the debugging information but packaged into the binary package after stripping the debugging information as required by «Chapter 10 - Files» of the «Debian Policy Manual».

См.

- «6.7.9. Best practices for debug packages» of the «Debian Developer’s Reference».
- «18.2 Debugging Information in Separate Files» of the «Debugging with gdb»
- «dh_strip(1) manapage»
- «strip(1) manapage»
- «readelf(1) manapage»
- «objcopy(1) manapage»
- Debian wiki: «DebugPackage»
- Debian wiki: «AutomaticDebugPackages»
- Сообщение в списке рассылки debian-devel: «Информация о статусе автоматических отладочных пакетов» (2015-08-15)

## 10.21. -dbgsym package

The debugging information is automatically packaged separately as the debug package using the dh_strip command with its default behavior. The name of such a debug package normally has the -dbgsym suffix.

- The debian/rules file shouldn’t explicitly contain dh_strip.
- Set the Build-Depends to debhelper-compat (>=14) while removing Build-Depends to debhelper in debian/control.

## 10.22. debconf

Пакет debconf позволяет нам настраивать пакеты в ходе их установки двуями основными способами:

- неинтерактивно из предпосевных настроек программы установки Debian.

- interactively from the menu interface (dialog, gnome, kde, …​)

  - установка пакета: вызывается командой dpkg
  - установленный пакет: вызывается командой dpkg-reconfigure

Всё взаимодействие с пользователем в ходе установки пакета должны обрабатыватся системой debconf с помощью следующих файлов.

- debian/binarypackage.config

  - Этот config-сценарий debconf используется для того, чтобы задавать любые вопросы, необходимые для настройки пакета.

- debian/двоичныйпакет.template

  - Этот templates-файл debconf используется для того, чтобы задавать любые вопросы, наобходимые для настройки пакета.

These debconf files are called by package configuration scripts in the binary Debian package

- DEBIAN/binarypackage.preinst
- DEBIAN/binarypackage.prerm
- DEBIAN/binarypackage.postinst
- DEBIAN/binarypackage.postrm

See dh_installdebconf(1), debconf(7), debconf-devel(7) and «3.9.1 Prompting in maintainer scripts» in the «Debian Policy Manual».

[18] Этот документ был написан до появления файла symbols.

[19] The strong preference is to use the SONAME versioned -dev package names over the single -dev package name in «Chapter 6. Development (-DEV) packages», which does not seem to be shared by the former ftp-master (Steve Langasek). This document was written before the introduction of the multiarch system and the symbols file.

[20] This path is compliant with the FHS. «Filesystem Hierarchy Standard: /usr/lib : Libraries for programming and packages» states «Applications may use a single subdirectory under /usr/lib. If an application uses a subdirectory, all architecture-dependent data exclusively used by the application must be placed within that subdirectory.»

Глава 9. More on packaging |  | Глава 11. Packaging with git