Capítulo 10. Empacotamento avançado

Índice

10.1. Perspetiva histórica
10.2. Tendências actuais
10.3. Nota sobre sistema de compilação
10.4. Integração contínua
10.5. Bootstrapping
10.6. Endurecimento de compilação
10.7. Compilação reproduzível
10.8. Substvar
10.9. Pacote de biblioteca
10.10. Multiarch
10.11. Divisão de um pacote binário Debian
10.12. Cenário de divisão de pacote e exemplos
10.13. Caminho da biblioteca Multiarch
10.14. Caminho do ficheiro de cabeçalho Multiarch
10.15. Caminho do ficheiro *.pc Multiarch
10.16. Símbolos de biblioteca
10.17. Nome de pacote da biblioteca
10.18. Transição de biblioteca
10.19. binNMU seguro
10.20. Informação de depuração
10.21. Pacote -dbgsym
10.22. debconf

Vamos descrever tópicos avançados no empacotamento Debian.

Vou sobre-simplificar a perspetiva histórica das práticas de empacotamento Debian focando o empacotamento não-nativo.

Debian começou nos anos 1990 quando os pacotes de autor estavam disponíveis a partir de sites FTP públicos como o Sunsite. Nesses primeiros dias, o empacotamento Debian usada o formato fonte Debian actualmente conhecido como formato fonte Debian 1.0:

  • O pacote fonte Debian contém um conjunto de ficheiros para o pacote fonte Debian.

    • pacote_versão.orig.tar.gz : link simbólico ou cópia do ficheiro de lançamento do autor.
    • pacote_versão-revisão.diff.gz : Uma grande patch para modificações Debian.
    • pacote_versão-revisão.dsc: descrição do pacote.
  • Several workaround approaches such as dpatch, dbs, or cdbs were deployed to manage multiple topic patches.

O formato fonte Debian moderno 3.0 (quilt) foi inventado cerca de 2008 (veja ProjectsDebSrc3.0):

  • O pacote fonte Debian contém um conjunto de ficheiros para o pacote fonte Debian.

    • pacote_versão.orig.tar.?z : link simbólico ou cópia do ficheiro de lançamento do autor.
    • pacote_versão-revisão.debian.tar.?z : tarball de debian/ para modificações Debian.

      • O ficheiro debian/source/format contém 3.0 (quilt).
      • As patches de tópico múltiplo opcionais estão guardadas no directório debian/patches/.
    • pacote_versão-revisão.dsc: descrição do pacote.
  • The standardized approach to manage multiple topic patches using quilt(1) is deployed for the Debian source format 3.0 (quilt).

A maioria dos pacotes Debian adotaram os formatos fonte Debian 3.0 (quilt) e 3.0 (native).

Agora, o git(1) é popular entre autores e desenvolvedores Debian. O git e as suas ferramentas associadas são parte importante do fluxo de trabalho de empacotamento moderno de Debian. Este fluxo de trabalho moderno que envolve git será mencionado mais tarde em Capítulo 11, Empacotar com git.

As práticas de empacotamento Debian actuais e suas tendências são um alvo em movimento. Veja:

  • Tendências Debian” — Dicas para Standard de facto das práticas Debian.

    • Sistemas de compilação: dh
    • Formato fonte Debian: 3.0 (quilt)
    • VCS: git
    • Alojamento VCS: salsa
    • Rules-Requires-Root: adoptado, fakeroot
    • Formato de Copyright: DEP-5
  • debhelper-compat-upgrade-checklist(7) — Lista de verificação de actualização para o debhelper
  • DEP - Propostas de Melhoramento Debian— Propostas formais para melhorar Debian

Você pode também procurar os dados do código fonte inteiro de Debian por si mesmo.

Pode ser encontrados ficheiros auto-gerados do sistema de compilação no tarball do autor. Estes devem ser re-gerados quando o pacote Debian é compilado. Ex.:

  • dh $@ --with autoreconf deve ser usado no debian/rules se forem usados Autotools (autoconf + automake).

Alguns sistemas de compilação modernos podem ser capazes de descarregar códigos fonte e ficheiros binários requeridos a partir de máquinas remotas arbitrárias para satisfazer requerimentos de compilação. Não use esta funcionalidade de download. É requerido que o pacote Debian oficial seja compilado apenas com os pacotes listados em Build-Depends: do ficheiro debian/control.

O comando dh_auto_test(1) é um comando debhelper que tenta correr automaticamente a suite de teste fornecida pelo desenvolvedor autor durante o processo de compilação do pacote Debian.

O comando autopkgtest(1) pode ser usado após o processo de compilação do pacote Debian. Ele testa os pacotes binário Debian gerados num ambiente virtual usando o ficheiro de metadados estilo RFC822 debian/tests/control como integração contínua (CI). Veja:

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

Debian preocupa-se com suporte a novos portes ou sabores. Os novos portes ou sabores requerem a operação bootstrapping para a compilação-cruzada do sistema inicial mínimo de compilação-nativa. De modo a evitar ciclos infinitos de dependências-de-compilação durante o bootstrapping, as dependências de compilação precisam ser reduzidas usando a variável de ambiente DEB_BUILD_PROFILES.

Veja Debian wiki: BuildProfileSpec.

[Dica]Dica

Se um pacote núcleo foo tiver dependências de compilação num pacote bar com cadeias de dependência de compilação funda mas bar é apenas usado no alvo test em foo, você pode marcar seguramente o bar com <!nocheck> em Build-depends de foo para evitar ciclos na compilação.

O suporte de endurecimento de compilação lançado para Debian jessie (8.0) obriga a que prestemos atenção extra ao empacotamento.

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 Capítulo 5, Empacotamento simples e dpkg-buildflags(1)).

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

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.

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

Para a biblioteca partilhada, as bibliotecas requeridas encontradas simplesmente por objdump -p /caminho/para/programa | grep NEEDED são cobertas pelo substvar shlib.

Para Python e outros interpretes, os modules requeridos encontrados simplesmente procurando por linhas com import, use, require, etc., são cobertos pelos substvars correspondentes.

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:

Um método intuitivo e flexível de criar o ficheiro modelo inicial debian/control definindo a divisão dos pacotes binário Debian com a opção -b. Veja Secção 16.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

A política Debian requer que se cumpra com Filesystem Hierarchy Standard (FHS), versão 3.0”, com as excepções anotadas em Estrutura de Sistema de Ficheiros.

A excepção mais notável é o uso de /usr/lib/<triplet>/ em vez de /usr/lib<qual>/ (ex., /lib32/ e /lib64/) para suportar uma biblioteca multiarch.


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.

  • Se ./configure for usado no alvo override_dh_auto_configure em debian/rules, certifique-se de o substituir por dh_auto_configure -- enquanto redefine o alvo do caminho de instalação de /usr/lib/ para /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>/. [20]

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:

  • Extrair o ficheiro DEBIAN/symbols antigo do pacote binário imediatamente anterior com o comando dpkg-deb -e.

    • 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:

      • Extrair o ficheiro DEBIAN/symbols actualizado com o comando dpkg-deb -e.
      • 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 O sistema de símbolos” do Manual de Política Debian
  • manual do dh_makeshlibs(1)
  • manual do dpkg-gensymbols(1)
  • manual do dpkg-shlibdeps(1)
  • manual do deb-symbols(5)

Você deve também verificar:

[Dica]Dica

Para bibliotecas C++ e outros casos onde acompanhar os símbolos é problemático, então siga 8.6.4 O sistema shlibs do Manual de Política Debian. Por favor certifique-se de apagar o ficheiro vazio debian/pacotebinário.symbols gerado pelo comando debmake. Para este caso, é usado o ficheiro DEBIAN/shlibs.

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.

[Atenção]Atenção

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:

[Dica]Dica

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

Veja Secção 10.9, “Pacote de biblioteca”.

Quando você empacota uma nova versão de pacote biblioteca que afecta outros pacotes, você tem de preencher um relatório de bug de transição contra o pseudo pacote release.debian.org usando o comando reportbug com o ficheiro ben e esperar a aprovação do seu envio pela Equipa de Lançamento.

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

[Cuidado]Cuidado

Por favor certifique-se de renomear pacotes binários como em Secção 10.17, “Nome de pacote da biblioteca”.

Um binNMU” é um envio apenas-binário não-maintainer executado para transições de biblioteca etc. Num envio binNMU, apenas os pacotes Architecture: any são recompilados com um número de versão em sufixo (ex. a versão 2.3.4-3 irá tornar-se 2.3.4-3+b1). Os pacotes Architecture: all não são compilados.

A dependência definida no ficheiro debian/control entre pacotes binário do mesmo pacote fonte deve ser segura para o binNMU. Isto precisa de atenção se existirem ambos pacotes Architecture: any e Architecture: all envolvidos nisto.

  • pacote Architecture: any: depende de pacote Architecture: any foo

    • Depends: foo (= ${binary:Version})
  • pacote Architecture: any: depende de pacote Architecture: all bar

    • Depends: bar (= ${source:Version})
  • pacote Architecture: all: depende de pacote Architecture: any baz

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

O pacote Debian é compilado com a informação de depuração mas empacotado no pacote binário após despir a informação de depuração como requerido por Capítulo 10 - Ficheiros” do Manual de Política Debian.

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.
  • interactivamente a partir da interface de menu (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.

Estes ficheiros debconf são chamados por scripts de configuração do pacote no pacote binário Debian.

  • DEBIAN/pacote-binário.preinst
  • DEBIAN/pacote-binário.prerm
  • DEBIAN/pacote-binário.postinst
  • DEBIAN/pacote-binário.postrm

Veja dh_installdebconf(1), debconf(7), debconf-devel(7) e 3.9.1 Perguntando nos scripts do maintainer” no Manual de Políticas Debian.



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

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

[20] Este caminho é compatível com. Standard de Hierarquia de Sistema de Ficheiros: /usr/lib : Bibliotecas para programação e pacotes declara As aplicações podem usar um único sub-directório sob /usr/lib. Se uma aplicação usar um sub-directório, todos os dados independentes-de-arquitectura exclusivamente usados pela aplicação têm de ser colocados dentro desse sub-directório.