Chapter 9. Empacotamento avançado

Table of Contents

9.1. Historical perspective
9.2. Current trends
9.3. Note on build system
9.4. Integração contínua
9.5. Bootstrapping
9.6. Endurecimento de compilação
9.7. Compilação reproduzível
9.8. Substvar
9.9. Pacote de biblioteca
9.10. Multiarch
9.11. Divisão de um pacote binário Debian
9.12. Cenário de divisão de pacote e exemplos
9.13. Multiarch library path
9.14. Multiarch header file path
9.15. Multiarch *.pc file path
9.16. Símbolos de biblioteca
9.17. Library package name
9.18. Transição de biblioteca
9.19. binNMU seguro
9.20. Informação de depuração
9.21. -dbgsym package
9.22. debconf

Let’s describe advanced topics on Debian packaging.

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.gz : 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 deplyoed 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 standarized 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 Chapter 10, Packaging with git.

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.

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.

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:

Existem várias outras ferramentas CI em Debian para você explorar.

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.

[Tip]Tip

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.

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

Você deve ler as seguintes referências em detalhe.

O comando debmake adiciona comentários modelo ao ficheiro debian/rules como necessário para DEB_BUILD_MAINT_OPTIONS, DEB_CFLAGS_MAINT_APPEND, e DEB_LDFLAGS_MAINT_APPEND (veja Chapter 5, Simple packaging e dpkg-buildflags(1)).

Aqui estão algumas recomendações para obter um resultado de compilação reproduzível.

O ficheiro de controle nome-fonte_versão-fonte_arch.buildinfo gerado pelo dpkg-genbuildinfo(1) guarda o ambiente de compilação. Veja deb-buildinfo(5)

O ficheiro debian/control também define a dependência do pacote no qual o mecanismo de substituição de variáveis” (substvar) pode ser usada para libertar os maintainers de pacotes de tarefas de seguir a maioria dos casos de dependências simples de pacotes. Veja deb-substvars(5).

O comando debmake suporta os seguintes substvars:

  • ${misc:Depends} para todos os pacotes binário
  • ${misc:Pre-Depends} para todos os pacotes multiarch
  • ${shlibs:Depends} para todos os pacotes binário executáveis e bibliotecas
  • ${python:Depends} Para todos os pacotes Python
  • ${python3:Depends} Para todos os pacotes Python3
  • ${perl:Depends} para todos os pacotes Perl
  • ${ruby:Depends} para todos os pacotes 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.

Para outros programas que não implantam os seus próprios substvars, o substvar misc cobre as suas dependências.

Para programas de shell POSIX, não existe maneira fácil de identificar a dependência e nenhum substvar cobre a sua dependência.

Para bibliotecas e módulos requeridos via mecanismo de carga dinâmico incluindo o mecanismo GObject introspection, não existe maneira fácil de identificar a dependência e nenhum substvar cobre a sua dependência.

Empacotar software biblioteca requer que você execute muito mais trabalho que o normal. Aqui estão alguns lembretes para empacotamento de software biblioteca:

Antes de empacotar software de biblioteca partilhada, veja:

Para o estudo de fundo histórico, veja:

Suporte Multiarch para instalação de arquitectura-cruzada de pacotes binários (particularmente i386 e amd64, mas também outras combinações) nos pacotes dpkg e apt introduzidos em Debian wheezy (7, Maio 2013), obriga a que tenhamos atenção extra no empacotamento.

Você deve ler as seguintes referências em detalhe.

O multiarch é activado ao usar o valor <triplet> como i386-linux-gnu e x86_64-linux-gnu no caminho de instalação de várias bibliotecas como /usr/lib/<triplet>/, etc...

  • O valor <triplet> requerido internamente pelo script debhelper é definido implicitamente neles próprios. O maintainer não tem de se preocupar.
  • O valor <triplet> usado nos scripts alvo override_dh_* têm de ser explicitamente definidos no ficheiro debian/rules pelo maintainer. O valor <triplet> é guardado na variável $(DEB_HOST_MULTIARCH) no seguinte exemplo de trecho do debian/rules:

    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)

Veja:

Para sistemas de compilação bem comportados, a divisão de um pacote binário Debian em pacotes menores pode ser realizada como se segue.

  • Criar entradas em pacote binário para todos os pacotes binário no ficheiro debian/control.
  • Listar todos os caminhos de ficheiro (relativos a debian/tmp) nos ficheiros debian/pacotebinário.install correspondentes.

Por favor verifique os exemplos neste guia:

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 Section 15.2, “debmake -b.

Aqui estão alguns cenários de divisão de pacote multiarch típicos para os seguintes exemplos de fonte de autor usando o comando debmake:

  • uma fonte de biblioteca libfoo-1.0.tar.gz
  • uma fonte de ferramenta bar-1.0.tar.gz escrita numa linguagem compilada
  • uma fonte de ferramenta baz-1.0.tar.gz escrita numa linguagem interpretada.
pacote-bináriotipoArchitecture:Multi-Arch:Conteúdo do pacote

libfoo1

lib*

any

same

a biblioteca partilhada, co-instalável

libfoo-dev

dev*

any

same

os ficheiros de cabeçalho da biblioteca partilhada etc., co-instaláveis

libfoo-tools

bin*

any

foreign

os programas de suporte de tempo-de-execução, não co-instaláveis

libfoo-doc

doc*

all

foreign

os ficheiros de documentação da biblioteca partilhada

bar

bin*

any

foreign

os ficheiros do programa compilado, não co-instaláveis

bar-doc

doc*

all

foreign

os ficheiros de documentação para o programa

baz

script

all

foreign

os ficheiros de programa interpretados

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.


Para pacotes baseados em Autotools sob o pacote debhelper (compat>=9), esta definição de caminho é cuidada automaticamente pelo comando dh_auto_configure.

Para outros pacote com sistemas de compilação não-suportados, você tem de ajustar manualmente o caminho de instalação como se segue.

  • 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)/.
  • Substitua todas as ocorrências de /usr/lib/ por /usr/lib/*/ nos ficheiros debian/foo.install.

Todos os ficheiros instalados em simultâneo como o pacote multiarch para o mesmo caminho de ficheiro devem ter exatamente o mesmo conteúdo de ficheiro. Você tem de ter cuidado com as diferenças geradas pela ordem de bytes de dados e pelo algoritmo de compressão.

Os ficheiros de biblioteca partilhada nos caminhos predefinidos /usr/lib/ e /usr/lib/<triplet>/ são carregados automaticamente.

Para ficheiros de biblioteca partilhada noutro caminho, a opção GCC -l tem de ser definida pelo comando pkg-config para fazer com que elas carreguem de maneira apropriada.

GCC inclui ambos /usr/include/ e /usr/include/<triplet>/ por predefinição no sistema Debian multiarch.

Se o ficheiro cabeçalho não estiver nesses caminhos, a opção GCC -I tem de ser definida pelo comando pkg-config para fazer "#include <foo.h>" funcionar de maneira apropriada.


O uso do caminho /usr/lib/<triplet>/nomepacote/ para os ficheiros biblioteca permite ao maintainer o autor usar o mesmo script de instalação para o sistema multi-arch com /usr/lib/<triplet> e o sistema bi-arch com /usr/lib<qual>/. [19]

O uso de caminho de ficheiro que contém nomepacote permite ter mais de 2 bibliotecas de desenvolvimento instaladas simultaneamente num sistema.

O programa pkg-config é usado para obter informação acerca de bibliotecas instaladas no sistema. Ele guarda os seus parâmetros de configuração no ficheiro *.pc e é usado para definir as opções -I e -l para o GCC.


O suporte de símbolos em dpkg introduzido em Debian lenny (5.0, Maio 2009) ajuda-nos a gerir a compatibilidade ABI com versões anteriores do pacote biblioteca com o pacote com o mesmo nome. O ficheiro DEBIAN/symbols no pacote binário fornece a versão mínima associada a cada símbolo.

Um método sobre-simplificado para o empacotamento de biblioteca é como se segue:

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

    • Alternativamente, o comando mc pode ser usado para extrair o ficheiro DEBIAN/symbols.
  • Copie-o para ficheiro debian/pacote-binário.symbols.

    • Se este for o primeiro pacote, use antes um ficheiro de conteúdo vazio.
  • Compilar o pacote binário

    • Se o comando dpkg-gensymbols avisar acerca de alguns novos símbolos:

      • Extract the updated DEBIAN/symbols file with the dpkg-deb -e command.
      • Corte a revisão Debian tal como -1 nele.
      • Copie-o para ficheiro debian/pacote-binário.symbols.
      • Re-compilação do pacote binário.
    • Se o comando dpkg-gensymbols não avisar acerca de novos símbolos:

      • Você terminou com o empacotamento de biblioteca.

Para detalhes, você deve ler as seguintes referências primárias.

  • 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

Você deve também verificar:

[Tip]Tip

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.

Vamos considerar que o tarball fonte do autor da biblioteca libfoo é actualizada de libfoo-7.0.tar.gz para libfoo-8.0.tar.gz com um novo SONAME de versão maior que afecta outros pacotes.

O pacote biblioteca binário tem de ser renomeado de libfoo7 para libfoo8 para manter o sistema da suite unstable a funcionar para todos os pacotes dependentes após o envio do pacote baseado em libfoo-8.0.tar.gz.

[Warning]Warning

Se o pacote biblioteca binário não for renomeado, muitos pacotes dependentes na suite unstable ficam quebrados logo após o envio da biblioteca mesmo que seja requisitado um envio binNMU. O binNMU pode não acontecer imediatamente após o envio devido a várias razões.

O pacote -dev tem de seguir uma das seguintes regras de nomeação:

[Tip]Tip

Se o esquema de codificação de dados alterar (ex. latin1 para utf-8), é preciso tomar a mesma alteração na API.

Veja Section 9.9, “Pacote de biblioteca”.

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.

Lançamento de equipa tem o seguidor de transição. Veja Transições.

[Caution]Caution

Por favor certifique-se de renomear pacotes binários como em Section 9.17, “Library package name”.

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~)

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.

Veja

A informação de depuração é automaticamente empacotada separadamente como o pacote de depuração usando o comando dh_strip com o seu comportamento predefinido. O nome de tal pacote de depuração normalmente tem o sufixo -dbgsym.

  • O ficheiro debian/rules não deve conter explicitamente dh_strip.
  • Define o Build-Depends para debhelper-compat (>=13) enquanto remove Build-Depends para debhelper em debian/control.

O pacote debconf permite-nos configurar pacotes durante a sua instalação de 2 maneiras principais:

  • não-interactivamente a partir de pré-preenchimento do debian-installer.
  • interactively from the menu interface (dialog, gnome, kde, …​)

    • a instalação do pacote: invocado pelo comando dpkg
    • o pacote instalado: invocado pelo comando dpkg-reconfigure

Todas as interações do utilizador para a instalação do pacote tem de ser lidada por este sistema debconf usando os seguintes ficheiros.

  • debian/pacote-binário.config

    • Este é o script config do debconf usado para perguntar quaisquer questões necessárias para configurar o pacote.
  • debian/pacote-binário.template

    • Este é o ficheiro de modelos debconf usado para perguntar quaisquer questões necessárias para configurar o pacote.

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.



[17] Este documento foi escrito antes da introdução do ficheiro symbols.

[18] A forte preferência é usar nomes de pacotes -dev versionados SONAME sobre o nome de pacote -dev singular em Capítulo 6. Desenvolvimento de pacotes (-DEV), o que não parece ser partilhado pelo anterior ftp-master (Steve Langasek). Este documento foi escrito antes da introdução do sistema multiarch e do ficheiro symbols.

[19] 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.