Joenio Marques da Costa

Debian shot wallpaper por mdh3ll

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 pacote
  • debian/control - declaração de dependências, mantenedores, descrição, etc
  • debian/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