Tutorial de empacotamento Debian - Parte 1
Este tutorial descreve passo-a-passo como criar pacotes de bibliotecas da linguagem de programação Perl para o sistema operacional Debian.
O Debian é um sistema operacional livre criado e mantido por um grupo independente de desenvolvedores espalhados ao redor do mundo, o projeto foi iniciado em 1993 e tem sido desenvolvido abertamente desde então, sempre seguindo o espírito livre do projeto GNU.
Porque empacotar software para o sistema Debian?
A enorme quantidade de pacotes disponíveis torna extremamente simples pesquisar, instalar, atualizar ou remover software do computador, seja desktop, servidor ou qualquer outra plataforma suportada pelo Debian. Contribuir com o empacotamento de software novo e com a manutenção de pacotes existentes é uma ótima forma de melhorar a qualidade geral deste sistema operacional universal.
Times de empacotamento do Debian
O Debian possui uma grande quantidade colaboradores com mais de 6mil pessoas trabalhando em empacotamento, tradução, testes e abertura de bugs, entre outras atividades. Muita dessas atividades são coordenadas e organizadas em times internos ao Debian, por exemplo há time cuidando dos mirrors (ou espelhos) de repositório, time cuidando de programas de estágio como Outreach e Google Summer of Code, ou times de empacotamento de software organizados por linguagens de programação, como Lisp, Erlang ou Java.
Este tutorial segue os guias e experiência do time Debian de empacotamento da linguagem de programação Perl Debian Perl Group e tudo que é dito neste tutorial é válido para pacotes Perl.
Anatomia de um pacote Debian
Um pacote Debian é composto de um conjunto de arquivos organizados no diretório
debian/
dentro do código-fonte do software sendo empacotado para o Debian.
Se utilizarmos como exemplo o código-fonte da biblioteca
Acme::Helloworld
então o pacote Debian (ou melhor, o código-fonte do pacote Debian) seria algo
semelhante com a estrutura abaixo.
libacme-helloworld-perl/ ├── Build.PL ├── Changes ├── cpanfile ├── debian/ │ ├── changelog │ ├── control │ ├── copyright │ ├── rules │ └── watch ├── lib/ │ └── Acme/ │ └── Helloworld.pm ├── LICENSE ├── MANIFEST ├── META.json ├── META.yml ├── minil.toml ├── README.md └── t/ └── 00_compile.t
Os arquivos changelog
, control
, copyright
, rules
e watch
dentro do
diretório debian/
são definições do pacote Debian libacme-helloworld-perl
,
os demais são o código-fonte do upstream Acme::Helloworld
e não tem relação
direta com o pacote.
Roteiro deste tutorial
Vamos lá! Os exemplos relatados aqui serão feitos com base na biblioteca Perl Acme::Helloworld, o tutorial é dividido nas 4 etapas abaixo.
- Configurar o ambiente de desenvolvimento
- Criar o pacote para a biblioteca Acme::Helloworld
- Construir o pacote e verificar problemas
- Testar a instalação do pacote
Configurar o ambiente de desenvolvimento
Instalar o Debian
Primeiro, antes de tudo, é necessário utilizar alguma versão do Debian, stable, testing, ou unstable e ter o Debian rodando em seu computador, ou ao menos ter Debian rodando numa máquina virtual, idealmente com a versão testing. Todos os comandos e passos deste tutorial devem ser executados num sistema Debian, caso precise de ajuda para instalar Debian em seu computador consulte a wiki Debian sobre instalação aqui.
Instalar as dependências para empacotamento Perl
Os seguintes pacotes abaixo devem ser instalados, execute o comando abaixo no terminal do Debian.
sudo apt install devscripts debhelper debian-policy git-buildpackage pkg-perl-tools
O Debian Perl Group mantém uma coleção de ferramentas para auxiliar o empacotamento de bibliotecas Perl no Debian mantidos no pacote pkg-perl-tools, essas ferramentas facilitam bastante o trabalho de empacotamento.
Instale também o apt-file
e atualize a
sua base de dados para que o dh-make-perl
possa descobrir o nome do pacote Debian
referente a uma certa
biblioteca Perl.
sudo apt install apt-file
sudo apt-file update
Assim, com o apt-file
instalado e atualizado, é possível descobrir quando um certo módulo Perl já está empacotado no
Debian, por exemplo para descobrir se o módulo Acme::Helloworld está
empacotado e qual é o nome dele execute o dh-make-perl
com os parâmetros
abaixo.
dh-make-perl locate Acme::Helloworld
A biblioteca Acme::Helloworld
não está
empacotada no Debian então o dh-make-perl
reporta o seguinte.
== dh-make-perl 0.124 ==
Parsing Contents files:
ll.lz4
md64.lz4
Acme::Helloworld is not found in any Debian package
Configurar o git
Infome ao Git quem você é para que o dh-make-perl
gere o template
inicial do pacote com as informações corretas. Substitua “you@example.com” pelo seu email
e “Your Name” pelo seu nome.
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
Configurar o dh-make-perl
Crie as variáveis de ambiente abaixo usando também o seu nome e email, isso ajuda o
dh-make-perl
a criar os arquivos do pacote no diretório debian/
com seus dados
corretamente.
export EMAIL=you@example.com
export DEBFULLNAME="Your Name"
Se preferir adicione as linhas acima no arquivo ~/.bash_profile
para que
sejam redefinidas automaticamente sempre que o computador for reiniciado.
Configurar o cpan
Se o cpan
nunca foi utilizado execute-o antes do dh-make-perl
para que
sejam criadas as configurações básicas, basta executar o comando abaixo sem
nemhum argumento e confirmar com as opções padrão em cada pergunta.
cpan
Você deve ver algo como o video seguinte ao executar o cpan
.
Criar o pacote para a biblioteca Acme::Helloworld
Se você chegou até aqui é sinal que todas as dependências foram devidamente instaladas e o seu ambiente Debian está rodando e tem tudo pronto para iniciar o empacotamento.
Vamos empacotar a biblioteca Acme::Helloworld
para exercitar o
fluxo geral de empacotamento Debian, este é um pacote de exemplo e não será
enviado aos repositórios oficiais do Debian.
Criar a versão inicial do pacote
Crie a versão inicial do pacote usando o comando dh-make-perl
com os argumentos abaixo, ele faz o
download do código-fonte do upstream e prepara os arquivos iniciais do pacote dentro do
diretório debian/
.
dh-make-perl --pkg-perl --cpan Acme::Helloworld
O dh-make-perl
criará um repositório Git local com a cópia da última versão
de Acme::Helloworld
já com os arquivos necessários para o pacote
Debian, o nome dado ao pacote será libacme-helloworld-perl
, este é o padrão
definido pela política de nomes para pacotes do Debian Perl
Group.
Você deve ver algo como similar as mensagens abaixo ao executar o dh-make-perl
.
Correções básicas no template inicial
O template inicial do pacote criado pelo dh-make-perl
é bom mas não é
ideal, muitas alterações são necessárias, geralmente é necessário
alterar ao menos os arquivos abaixo.
debian/copyright
- informacoes sobre copyright e licença do pacotedebian/control
- declaração de dependências, mantenedores, descrição, etcdebian/changelog
- histórico de atualizações e versões do pacote
Arquivo debian/copyright
Vamos começar revisando o arquivo debian/copyright
,
ao verificar o conteúdo deste arquivo é possível notar que
o comando dh-make-perl
não foi capaz de identificar o ano do copyright e
adicionou a seguinte mensagem <INSERT COPYRIGHT YEAR(S) HERE> onde deveria
haver o ano do copyright.
Files: *
Copyright: <INSERT COPYRIGHT YEAR(S) HERE>, tomcha <tomcha@tomcha.net>
License: Artistic or GPL-1+
É importante verificar o copyright de cada arquivo do projeto, isso costuma
mudar ao longo do tempo, passando entre mantenedores ou empresas e
instituições, é muito importante listar no arquivo debian/copyright
o dono do
copyright de cada arquivo do projeto, mantendo nomes e datas sempre
atualizados.
É possível utilizar ferramentas para auxiliar a identificar o copyright dos
arquivos, o grep
costuma ser uma boa opção por ser bastante simples e estar
sempre disponível, execute o comando abaixo estando dentro do diretório do pacote libacme-helloworld-perl
para pesquisar ocorrências da palavra “copyright” no código-fonte do Acme::Helloworld.
grep -i -r --exclude-dir=.git --exclude-dir=debian copyright
É possível usar o comando acima e verificar manualmente os arquivos que
chamam atenção, por exemplo o trecho abaixo copiado da saída gerada pelo grep
chama atenção por conter o ano e o nome do author da biblioteca Acme::Helloworld.
LICENSE:This software is Copyright (c) 2017 by tomcha <tomcha@tomcha.net>.
LICENSE: Copyright (C) 1989 Free Software Foundation, Inc.
LICENSE: We protect your rights with two steps: (1) copyright the software, and
LICENSE:contains a notice placed by the copyright holder saying it may be
É possível notar então que no arquivo LICENSE
o author da biblioteca declarou
na sentença This software is Copyright (c) 2017 by tomcha <tomcha@tomcha.net>
o ano 2017,
podemos então atualizar o arquivo debian/copyright
com essa informação
Files: *
Copyright: 2017, tomcha <tomcha@tomcha.net>
License: Artistic or GPL-1+
Veja abaixo o diff dessa alteração no arquivo debian/copyright
.
joenio@debian-dev-main:~/debian-dev/tutorial/libacme-helloworld-perl$ git diff
diff --git a/debian/copyright b/debian/copyright
index d37ef15..77bb7c4 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -12,7 +12,7 @@ DISCLAIMER: This copyright info was automatically extracted
with this file.
Files: *
-Copyright: <INSERT COPYRIGHT YEAR(S) HERE>, tomcha <tomcha@tomcha.net>
+Copyright: 2017, tomcha <tomcha@tomcha.net>
License: Artistic or GPL-1+
Files: debian/*
É uma boa prática fazer commits atômicos e descritivos a cada pequena alteração
feita no pacote, declare exatamente o que foi feito de forma clara e direta.
Execute o git com os argumentos abaixo para fazer o commit das mudanças no
debian/copyright
.
git commit debian/copyright -m 'd/copyright: add upstream copyright year'
A próxima alteração necessária no debian/copyright
é
remover o DISCLAIMER do copyright adicionado pelo dh-make-perl
automaticamente.
joenio@debian-dev-main:~/debian-dev/tutorial/libacme-helloworld-perl$ git diff
diff --git a/debian/copyright b/debian/copyright
index 77bb7c4..2287fab 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -2,14 +2,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://metacpan.org/release/Acme-Helloworld
Upstream-Contact: tomcha <tomcha@tomcha.net>
Upstream-Name: Acme-Helloworld
-DISCLAIMER: This copyright info was automatically extracted
- from the perl module. It may not be accurate, so you better
- check the module sources in order to ensure the module for its
- inclusion in Debian or for general legal information. Please,
- if licensing information is incorrectly generated, file a bug
- on dh-make-perl.
- NOTE: Don't forget to remove this disclaimer once you are happy
- with this file.
Files: *
Copyright: 2017, tomcha <tomcha@tomcha.net>
Novamente, faça o commit dessa alteração.
git commit debian/copyright -m 'd/copyright: remove dh-make-perl disclaimer'
Arquivo debian/control
O arquivo debian/control
é um dos principais arquivos de um pacote Debian, é
preciso estar atento especialmente à versão do debhelper-compat
, deve-se
atualizar para a versão mais recente disponível. Cada versão traz mudanças na
forma de manter os pacotes, a versão 12, por exemplo, simplificou a
manutenção do pacote permitindo remover o arquivo debian/compat
e a
dependência ao debhelper
, mantendo num único local a definição sobre qual
política Debian o pacote segue.
Então atualize, caso necessário, a versão do
debhelper-compat
declarada no arquivo debian/control
para a versão mais recente, que
no momento da escrita deste tutorial é 13
, veja exemplo abaixo.
Build-Depends: debhelper-compat (= 13),
Verifique a manpage do debhelper
na seção COMPATIBILITY LEVELS (NÍVEIS DE
COMPATIBILIDADE) para encontrar a versão mais recente estável sugerida ou
use o comando rmadison
com os argumentos abaixo.
rmadison --suite=unstable debhelper | cut -d"|" -f 2 | sed 's/\s\+//'
Ainda no arquivo debian/control
atualize o pacote para a versão mais recente
da Debian Policy, você pode verificar a versão mais recente
consultando o pacote debian-policy
instalado em seu sistema com o comando abaixo.
dpkg-query --show --showformat '${Version}\n' debian-policy
Edite o debian/control
e atualize o campo Standards-Version
com a versão 4.7.0
.
Standards-Version: 4.7.0
joenio@debian-dev-main:~/debian-dev/tutorial/libacme-helloworld-perl$ git diff
diff --git a/debian/control b/debian/control
index bf81e2d..30235c6 100644
--- a/debian/control
+++ b/debian/control
@@ -8,7 +8,7 @@ Build-Depends: debhelper-compat (= 13),
libmodule-build-tiny-perl,
perl
Build-Depends-Indep: libtest-simple-perl <!nocheck>
-Standards-Version: 4.6.2
+Standards-Version: 4.7.0
Vcs-Browser: https://salsa.debian.org/perl-team/modules/packages/libacme-helloworld-perl
Vcs-Git: https://salsa.debian.org/perl-team/modules/packages/libacme-helloworld-perl.git
Homepage: https://metacpan.org/release/Acme-Helloworld
Faça o commit dessa alteração como no exemplo abaixo.
git commit debian/control -m 'declare compliance with Debian Policy 4.7.0'
Por fim, revise e atualize a descrição do pacote,
escolher uma boa descrição para o pacote é fundamental, deve-se levar um bom tempo nisso,
tanto para a descrição curta (synopsis), quanto para a descrição longa (extended description) do pacote, ambas se encontram
no final do arquivo debian/control
no campo Description:
.
Description: output 'Hello, world'
Acme::Helloworld is a module of a different way of writing the first program
to write.
.
This description was automagically extracted from the module by dh-make-perl.
O dh-make-perl
gera automaticamente a descrição do pacote, a descrição curta
é a primeira linha após o campo Description:
e a descrição longa são as linhas abaixo dela.
Consulte a política para descrição de pacotes no manual
de políticas do Debian para mais detalhes sobre como descrever os pacotes de
forma adequada. A descrição curta deve, usualmente, iniciar com letra minúscula quando não é um nome próprio
e deve ser uma “noum phrase” (substantivo). No caso do pacote Acme::Helloworld
a descrição gerada pelo dh-make-perl
deve ser alterada para o seguinte.
Description: Perl module to print the 'Hello, world' message
The Acme::Helloworld module is the classical Helloworld example for Perl that
just outputs the message 'Hello, world' on the stantard output.
.
This module does not include any real feature, it is just an example for
learning purpose.
A descrição curta inicia com maiúscula por se tratar de um nome próprio
neste caso, a linguagem de programação é Perl e não perl, perl é o
interpretador.
Vejamos o diff do arquivo debian/control
antes de realizar o commit com a alteração feita na descrição.
joenio@debian-dev-main:~/debian-dev/tutorial/libacme-helloworld-perl$ git diff
diff --git a/debian/control b/debian/control
index 7b78712..8d0e434 100644
--- a/debian/control
+++ b/debian/control
@@ -18,8 +18,9 @@ Package: libacme-helloworld-perl
Architecture: all
Depends: ${misc:Depends},
${perl:Depends}
-Description: output 'Hello, world'
- Acme::Helloworld is a module of a different way of writing the first program
- to write.
+Description: Perl module to print the 'Hello, world' message
+ The Acme::Helloworld module is the classical Helloworld example for Perl that
+ just outputs the message 'Hello, world' on the stantard output.
.
- This description was automagically extracted from the module by dh-make-perl.
+ This module does not include any real feature, it is just an example for
+ learning purpose.
Commit as modificações feita na descrição.
git commit debian/control -m 'rephrase synopsis and extended description'
Por fim, é possível usar a ferramenta cme
para analisar o debian/control
automaticamente e identificar eventuais problemas.
cme check dpkg-control debian/control
Se a saída for semelhante ao conteúdo abaixo significa que não foi encontrado
nenhum erro ou alerta e o arquivo debian/control
está ok.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Arquivo debian/changelog
O arquivo debian/changelog
é sempre atualizado em novas versões do pacote
e contém atualizações descrevendo as alterações em cada nova versão, em
nosso pacote para o libacme-helloworld-perl
é provável que o dh-make-perl
tenha feito
um bom trabalho e não será necessário alterar este arquivo, veja abaixo exemplo
do conteúdo deste arquivo.
libacme-helloworld-perl (0.01-1) UNRELEASED; urgency=low
* Initial release.
-- Joenio Marques da Costa <joenio@joenio.me> Sat, 11 May 2024 11:51:04 +0200
Construir o pacote
Finalizada as correções mais comuns é hora construir o pacote (build), é importante
fazer o build do pacote num chroot
limpo para evitar vícios do ambiente, é possível
que
pacotes e configurações específicas do nosso dekstop interferiram no build do pacote,
usar um chroot
evita isso.
Existem diversas ferramentas para criar um ambiente Debian limpo voltado para
construção de pacotes usando chroot
, entre os mais comuns estão o
sbuild
, pbuilder
e cowbuilder
, aqui vamos usar o pbuilder
.
Primeiro crie o sistema base do chroot com a distribuição Debian Sid (unstable), vamos utilizar a ferramenta pbuilder (Personal Builder) para realizar essa tarefa.
sudo pbuilder create
Agora é possível construir o pacote usando pbuilder para isolar num chroot todo o processo de build do pacote libacme-helloworld-perl.
O git-buildpackage
oferece um wrapper para o pdbuilder
, para usar ele e
evitar alertas a respeito dos arquivos binários existentes no diretório .git
basta executar o pbuilder
da seguinte forma,
a partir do diretório do pacote.
BUILDER=pbuilder git-pbuilder
Se o pacote apresentar algum problema durante o build é necessário investigar
e corrigir os erros e alertas, caso o pacote não apresente erros rode o Lintian
para verificar se há algo fora dos padrões,
o Lintian é uma ferramenta de análise estática capaz de identificar problemas comuns,
violação de política, bugs e outros erros em pacotes Debian,
o pbuilder
não executa o Lintian automaticamente.
lintian -I
O lintian
deve relatar alguns problemas no pacote libacme-helloworld-perl
e gerar o alerta (warning) abaixo.
W: libacme-helloworld-perl: initial-upload-closes-no-bugs [usr/share/doc/libacme-helloworld-perl/changelog.Debian.gz:1]
O warning initial-upload-closes-no-bugs diz que todo novo pacote deve fazer referência a um bug do tipo ITP no Debian,
mas por hora esse alerta pode ser ignorado já que não iremos abrir um bug no Debian nem submeter o pacote
libacme-helloworld-perl
por se tratar de um exemplo.
Execute também o Lintian com as flags específicas para pacotes Perl, isto inclui algumas verificações específicas definidas pelo Debian Perl Group.
lintian -I --profile pkg-perl
Testar a instalação do pacote
Ao chegar neste ponto sem maiores problemas significa que o pacote libacme-helloworld-perl foi gerado com sucesso, é esperado que haja
um arquivo com extensão .deb
num diretório acima do diretório atual
em ../libacme-helloworld-perl_0.01-1_all.deb
.
Teste a instalação do pacote com o dpkg
usando o comando abaixo.
sudo dpkg -i ../libacme-helloworld-perl_0.01-1_all.deb
Parabéns! Você criou o seu primeiro pacote com sucesso e instalou ele no seu sistema local. Apesar de ter sido um pacote de exemplo os passos podem ser replicados em outros pacotes, no próximo tutorial veremos como empacotar e submeter um pacote aos repositórios oficiais do Debian.
Próximo passo
a imagem utilizada no cabeçalho do post foi copiada de https://www.deviantart.com/mdh3ll/art/Debian-shot-311580879