Índice
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.
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-revisão.debian.tar.?z : tarball de debian/ para modificações Debian.
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.
Você pode também procurar os dados do código fonte inteiro de Debian por si mesmo.
“Fontes Debian” — ferramenta de busca de código
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.:
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 |
---|---|
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.
Leia mais em “ReproducibleBuilds”.
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:
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:
“Escapar ao Inferno das Dependências” [18]
“Guia de Empacotamento de Biblioteca Debian” [19]
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.
Ubuntu wiki (autor)
Debian wiki (situação de Debian)
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> 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.
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:
pacote-binário | tipo | Architecture: | 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.
Tabela 10.1. As opções do caminho da biblioteca multiarch
Caminho clássico | caminho multiarch i386 | caminho multiarch amd64 |
---|---|---|
/lib/ | /lib/i386-linux-gnu/ | /lib/x86_64-linux-gnu/ |
/usr/lib/ | /usr/lib/i386-linux-gnu/ | /usr/lib/x86_64-linux-gnu/ |
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.
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.
Tabela 10.2. As opções do caminho do ficheiro de cabeçalho multiarch
Caminho clássico | caminho multiarch i386 | caminho multiarch amd64 |
---|---|---|
/usr/include/ | /usr/include/i386-linux-gnu/ | /usr/include/x86_64-linux-gnu/ |
/usr/include/nomepacote/ | /usr/include/i386-linux-gnu/nomepacote/ | /usr/include/x86_64-linux-gnu/nomepacote/ |
/usr/lib/i386-linux-gnu/nomepacote/ | /usr/lib/x86_64-linux-gnu/nomepacote/ |
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.
Tabela 10.3. As opções de caminho do ficheiro *.pc
Caminho clássico | caminho multiarch i386 | caminho multiarch amd64 |
---|---|---|
/usr/lib/pkgconfig/ | /usr/lib/i386-linux-gnu/pkgconfig/ | /usr/lib/x86_64-linux-gnu/pkgconfig/ |
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”.
Copie-o para ficheiro debian/pacote-binário.symbols.
Compilar o pacote binário
Se o comando dpkg-gensymbols avisar acerca de alguns novos símbolos:
Se o comando dpkg-gensymbols não avisar acerca de novos símbolos:
Para detalhes, você deve ler as seguintes referências primárias.
Você deve também verificar:
![]() | 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 |
---|---|
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:
Use o nome de pacote não-versionado -dev: libfoo-dev
Apenas uma versão do pacote fonte de biblioteca é permitida no arquivo.
Use os nomes de pacote versionados -dev: libfoo7-dev e libfoo8-dev
São permitidas em simultâneo duas versões de pacotes fonte de biblioteca no arquivo.
![]() | Dica |
---|---|
Se o esquema de codificação de dados alterar (ex. latin1 para utf-8), é preciso tomar a mesma alteração na API. |
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 |
---|---|
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
pacote “Architecture: any”: depende de pacote “Architecture: all” bar
pacote “Architecture: all”: depende de pacote “Architecture: any” baz
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 pacote debconf permite-nos configurar pacotes durante a sua instalação de 2 maneiras principais:
interactivamente a partir da interface de menu (dialog, gnome, kde, …)
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
debian/pacote-binário.template
Estes ficheiros debconf são chamados por scripts de configuração do pacote no pacote binário Debian.
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.”