Chapter 13. Mais Exemplos

Table of Contents

13.1. Modelos Cherry-pick
13.2. Nenhum Makefile (shell, CLI)
13.3. Makefile (shell, CLI)
13.4. pyproject.toml (Python3, CLI)
13.5. Makefile (shell, GUI)
13.6. pyproject.toml (Python3, GUI)
13.7. Makefile (pacote singular-binário)
13.8. Makefile.in + configure (pacote singular-binário)
13.9. Autotools (pacote singular-binário)
13.10. CMake (pacote singular-binário)
13.11. Autotools (pacote multi-binário)
13.12. CMake (pacote multi-binário)
13.13. Internacionalização
13.14. Detalhes

There is an old Latin saying: fabricando fit faber (practice makes perfect).

É altamente recomendado praticar e experimentar com todos os aspectos de empacotamento Debian com pacotes simples. Este capítulo fornece-lhe muitos casos de autor para você praticar.

Isto deve também servir como exemplos de introdução a muitos tópicos de programação.

Por favor note que Debian leva algumas coisas a sério:

O exemplo de empacotamento típico apresentado em Chapter 5, Simple packaging é o pré-requisito para este capítulo.

Alguns detalhes foram deixados vagos intencionalmente nas secções seguintes. Por favor tente ler a documentação pertinente e pratique para os descobrir você próprio.

[Tip]Tip

The best source of a packaging example is the current Debian archive itself. Please use the Debian Code Search service to find pertinent examples.

Aqui está um exemplo de criar um pacote Debian simples a partir de uma fonte de conteúdo zero num directório vazio.

Isto é uma boa plataforma para obter todos os ficheiros modelo sem criar confusão na árvore fonte do autor em que está a trabalhar.

Vamos assumir que este directório vazio seja debhello-0.1.

 $ mkdir debhello-0.1
 $ tree
.
└── debhello-0.1

2 directories, 0 files

Let’s generate the maximum amount of template files.

Let’s also use the -p debhello -t -u 0.1 -r 1 options to make the missing upstream tarball with default -x3 and T options.

 $ cd /path/to/debhello-0.1
 $ debmake -p debhello -t -u 0.1 -r 1
I: set parameters
 ...

Vamos inspecionar os ficheiros modelo gerados.

 $ cd /path/to
 $ tree
.
├── debhello-0.1
│   └── debian
│       ├── README.Debian
│       ├── README.source
│       ├── changelog
│       ├── clean
│       ├── control
│       ├── copyright
│       ├── debhello.bug-control.ex
│       ├── debhello.bug-presubj.ex
│       ├── debhello.bug-script.ex
│       ├── debhello.conffiles.ex
│       ├── debhello.cron.d.ex
│       ├── debhello.cron.daily.ex
│       ├── debhello.cron.hourly.ex
│       ├── debhello.cron.monthly.ex
│       ├── debhello.cron.weekly.ex
│       ├── debhello.default.ex
│       ├── debhello.emacsen-install.ex
│       ├── debhello.emacsen-remove.ex
│       ├── debhello.emacsen-startup.ex
│       ├── debhello.lintian-overrides.ex
│       ├── debhello.service.ex
│       ├── debhello.tmpfile.ex
│       ├── dirs
│       ├── gbp.conf
│       ├── install
│       ├── links
│       ├── maintscript.ex
│       ├── manpage.1.ex
│       ├── manpage.asciidoc.ex
│       ├── manpage.md.ex
│       ├── manpage.sgml.ex
│       ├── manpage.xml.ex
│       ├── patches
│       │   └── series
│       ├── postinst.ex
│       ├── postrm.ex
│       ├── preinst.ex
│       ├── prerm.ex
│       ├── rules
│       ├── salsa-ci.yml
│       ├── source
│       │   ├── format
│       │   ├── lintian-overrides.ex
│       │   ├── local-options.ex
│       │   ├── local-patch-header.ex
│       │   ├── options.ex
│       │   └── patch-header.ex
│       ├── tests
│       │   └── control
│       ├── upstream
│       │   └── metadata
│       └── watch
├── debhello-0.1.tar.gz
└── debhello_0.1.orig.tar.gz -> debhello-0.1.tar.gz

7 directories, 50 files

Agora você pode copiar qualquer destes ficheiros modelo gerados no directório debhello-0.1/debian/ para o seu pacote como necessário enquanto os renomeia se necessário.

Aqui está um exemplo de criar um pacote Debian simples a partir de um programa CLI de shell POSIX sem o seu sistema de compilação.

Vamos assumir que o tarball do autor seja debhello-0.2.tar.gz.

Este tipo de fonte não tem meios automatizados e os ficheiros têm de ser instalados manualmente.

Por exemplo:

 $ tar -xzmf debhello-0.2.tar.gz
 $ cd debhello-0.2
 $ sudo cp scripts/hello /bin/hello
 ...

Vamos obter esta fonte como ficheiro tar a partir de um sítio remoto e fazer dela o pacote Debian.

Download debhello-0.2.tar.gz

 $ wget http://www.example.org/download/debhello-0.2.tar.gz
 ...
 $ tar -xzmf debhello-0.2.tar.gz
 $ tree
.
├── debhello-0.2
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
└── debhello-0.2.tar.gz

5 directories, 6 files

Aqui, o script de shell POSIX hello é um muito simples.

hello (v=0.2). 

 $ cat debhello-0.2/scripts/hello
#!/bin/sh -e
echo "Hello from the shell!"
echo ""
echo -n "Type Enter to exit this program: "
read X

Aqui, hello.desktop suporta a Especificação de Entrada Desktop”.

hello.desktop (v=0.2). 

 $ cat debhello-0.2/data/hello.desktop
[Desktop Entry]
Name=Hello
Name[fr]=Bonjour
Comment=Greetings
Comment[fr]=Salutations
Type=Application
Keywords=hello
Exec=hello
Terminal=true
Icon=hello.png
Categories=Utility;

Aqui, hello.png é o ficheiro de ícone gráfico.

Vamos empacotar isto com o comando debmake. Aqui, a opção -b':sh' é usada para especificar que o pacote binário gerado é um script de shell.

 $ cd /path/to/debhello-0.2
 $ debmake -b':sh' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="0.2", rev="1"
I: *** start packaging in "debhello-0.2". ***
I: provide debhello_0.2.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-0.2.tar.gz debhello_0.2.orig.tar.gz
I: pwd = "/path/to/debhello-0.2"
I: parse binary package settings: :sh
I: binary package=debhello Type=script / Arch=all M-A=foreign
I: analyze the source tree
I: build_type = Unknown
I: scan source for copyright+license text and file extensions
I:  25 %, ext = md
 ...

Vamos inspecionar os ficheiros modelo notáveis gerados.

A árvore fonte após a execução debmake básica. (v=0.2). 

 $ cd /path/to
 $ tree
.
├── debhello-0.2
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── debian
│   │   ├── README.Debian
│   │   ├── README.source
│   │   ├── changelog
│   │   ├── clean
│   │   ├── control
│   │   ├── copyright
│   │   ├── dirs
│   │   ├── gbp.conf
│   │   ├── install
│   │   ├── links
│   │   ├── patches
│   │   │   └── series
│   │   ├── rules
│   │   ├── salsa-ci.yml
│   │   ├── source
│   │   │   ├── format
│   │   │   ├── local-options.ex
│   │   │   └── local-patch-header.ex
│   │   ├── tests
│   │   │   └── control
│   │   ├── upstream
│   │   │   └── metadata
│   │   └── watch
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
├── debhello-0.2.tar.gz
└── debhello_0.2.orig.tar.gz -> debhello-0.2.tar.gz

10 directories, 26 files

debian/rules (ficheiro modelo, v=0.2): 

 $ cd /path/to/debhello-0.2
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1

%:
        dh $@

Isto é essencialmente o ficheiro debian/rules standard com o comando dh. Como isto é o pacote script, este ficheiro modelo debian/rules não tem conteúdos relacionados com bandeira de compilação.

debian/control (ficheiro modelo, v=0.2): 

 $ cat debian/control
Source: debhello
Section: unknown
Priority: optional
Maintainer: "Osamu Aoki" <osamu@debian.org>
Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: <insert the upstream URL, if relevant>
Rules-Requires-Root: no
#Vcs-Git: https://salsa.debian.org/debian/debhello.git
#Vcs-Browser: https://salsa.debian.org/debian/debhello

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Description: auto-generated package by debmake
 This Debian binary package was auto-generated by the
 debmake(1) command provided by the debmake package.

Since this is the shell script package, the debmake command sets Architecture: all and Multi-Arch: foreign. Also, it sets required substvar parameters as Depends: ${misc:Depends}. These are explained in Chapter 6, Basics for packaging.

Como esta fonte de autor não tem o Makefile de autor, essa funcionalidade tem de ser fornecida pelo maintainer. Esta fonte de autor contém apenas um ficheiro script e ficheiros de dados e nenhuns ficheiros de fonte C; o processo build pode ser saltado mas o processo install precisa de ser implementado. Para este caso, isto é conseguido de forma limpa ao adicionar os ficheiros debian/install e debian/manpages sem se complicar o ficheiro debian/rules.

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=0.2): 

 $ cd /path/to/debhello-0.2
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1

%:
        dh $@

debian/control (versão do maintainer, v=0.2): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Description: Simple packaging example for debmake
 This Debian binary package is an example package.
 (This is an example only)

[Warning]Warning

If you leave Section: unknown in the template debian/control file unchanged, the lintian error may cause a build failure.

debian/install (versão do maintainer, v=0.2): 

 $ vim debian/install
 ... hack, hack, hack, ...
 $ cat debian/install
data/hello.desktop usr/share/applications
data/hello.png usr/share/pixmaps
scripts/hello usr/bin

debian/manpages (versão do maintainer, v=0.2): 

 $ vim debian/manpages
 ... hack, hack, hack, ...
 $ cat debian/manpages
man/hello.1

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

Ficheiros modelo sob debian/. (v=0.2): 

 $ rm -f debian/clean debian/dirs debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ rm -rf debian/patches
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── gbp.conf
├── install
├── manpages
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 13 files

Você pode criar um pacote Debian não-nativo usando o comando debuild (ou os seus equivalentes) nesta árvore fonte. O texto resultante do comando é muito detalhado e explica o que ele faz como se segue.

 $ cd /path/to/debhello-0.2
 $ debuild
 dpkg-buildpackage -us -uc -ui -i
dpkg-buildpackage: info: source package debhello
dpkg-buildpackage: info: source version 0.2-1
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: source changed by Osamu Aoki <osamu@debian.org>
 dpkg-source -i --before-build .
dpkg-buildpackage: info: host architecture amd64
 debian/rules clean
dh clean
   dh_clean
        rm -f debian/debhelper-build-stamp
 ...
 debian/rules binary
dh binary
   dh_update_autotools_config
   dh_autoreconf
   create-stamp debian/debhelper-build-stamp
   dh_prep
        rm -f -- debian/debhello.substvars
        rm -fr -- debian/.debhelper/generated/debhello/ debian/debhello/ debi...
   dh_auto_install --destdir=debian/debhello/
 ...
Finished running lintian.

Vamos inspecionar o resultado.

Os ficheiros gerados de debhello versão 0.2 pelo comando debuild

 $ cd /path/to
 $ tree -FL 1
./
├── debhello-0.2/
├── debhello-0.2.tar.gz
├── debhello_0.2-1.debian.tar.xz
├── debhello_0.2-1.dsc
├── debhello_0.2-1_all.deb
├── debhello_0.2-1_amd64.build
├── debhello_0.2-1_amd64.buildinfo
├── debhello_0.2-1_amd64.changes
└── debhello_0.2.orig.tar.gz -> debhello-0.2.tar.gz

2 directories, 8 files

Você vê todos os ficheiros gerados.

  • O ficheiro debhello_0.2.orig.tar.gz é um link simbólico para o tarball do autor.
  • O ficheiro debhello_0.2-1.debian.tar.xz contém os conteúdos gerados pelo maintainer.
  • O ficheiro debhello_0.2-1.dsc é um ficheiro de meta-dados para o pacote fonte Debian.
  • O ficheiro debhello_0.2-1_all.deb é o pacote binário Debian.
  • O ficheiro debhello_0.2-1_amd64.build é o ficheiro de relatório de compilação.
  • O ficheiro debhello_0.2-1_amd64.buildinfo é o ficheiro de meta-dados gerado pelo dpkg-genbuildinfo(1).
  • O ficheiro debhello_0.2-1_amd64.changes é o ficheiro de meta-dados para o pacote binário Debian.

O ficheiro debhello_0.2-1.debian.tar.xz contém as alterações Debian à fonte do autor como se segue:

O conteúdo de arquivo comprimido de debhello_0.2-1.debian.tar.xz

 $ tar -tzf debhello-0.2.tar.gz
debhello-0.2/
debhello-0.2/data/
debhello-0.2/data/hello.desktop
debhello-0.2/data/hello.png
debhello-0.2/man/
debhello-0.2/man/hello.1
debhello-0.2/scripts/
debhello-0.2/scripts/hello
debhello-0.2/README.md
 $ tar --xz -tf debhello_0.2-1.debian.tar.xz
debian/
debian/README.Debian
debian/changelog
debian/control
debian/copyright
debian/gbp.conf
debian/install
debian/manpages
debian/rules
debian/salsa-ci.yml
debian/source/
debian/source/format
debian/tests/
debian/tests/control
debian/upstream/
debian/upstream/metadata
debian/watch

O ficheiro debhello_0.2-1_amd64.deb contém os ficheiros a serem instalados como se segue.

O conteúdo de pacote binário de debhello_0.2-1_all.deb

 $ dpkg -c debhello_0.2-1_all.deb
drwxr-xr-x root/root ...  ./
drwxr-xr-x root/root ...  ./usr/
drwxr-xr-x root/root ...  ./usr/bin/
-rwxr-xr-x root/root ...  ./usr/bin/hello
drwxr-xr-x root/root ...  ./usr/share/
drwxr-xr-x root/root ...  ./usr/share/applications/
-rw-r--r-- root/root ...  ./usr/share/applications/hello.desktop
drwxr-xr-x root/root ...  ./usr/share/doc/
drwxr-xr-x root/root ...  ./usr/share/doc/debhello/
-rw-r--r-- root/root ...  ./usr/share/doc/debhello/README.Debian
-rw-r--r-- root/root ...  ./usr/share/doc/debhello/changelog.Debian.gz
-rw-r--r-- root/root ...  ./usr/share/doc/debhello/copyright
drwxr-xr-x root/root ...  ./usr/share/man/
drwxr-xr-x root/root ...  ./usr/share/man/man1/
-rw-r--r-- root/root ...  ./usr/share/man/man1/hello.1.gz
drwxr-xr-x root/root ...  ./usr/share/pixmaps/
-rw-r--r-- root/root ...  ./usr/share/pixmaps/hello.png

Aqui está a lista de dependências gerada de debhello_0.2-1_all.deb.

A lista de dependências gerada de debhello_0.2-1_all.deb

 $ dpkg -f debhello_0.2-1_all.deb pre-depends \
            depends recommends conflicts breaks

(Nenhum pacote de dependência extra requerido pois este é um programa de shell POSIX.)

[Note]Note

If you wish to replace upstream provided PNG file data/hello.png with maintainer provided one debian/hello.png, editing debian/install isn’t enough. When you add debian/hello.png, you need to add a line include-binaries to debian/source/options since PNG is a binary file. See dpkg-source(1).

Aqui está um exemplo de criar um pacote Debian simples a partir de um programa CLI de shell POSIX usando o Makefile como seu sistema de compilação.

Vamos assumir que o tarball de autor seja debhello-1.0.tar.gz.

Este tipo de fonte destina-se a ser instalado como ficheiro não-sistema como:

 $ tar -xzmf debhello-1.0.tar.gz
 $ cd debhello-1.0
 $ make install

Debian packaging requires changing this make install process to install files to the target system image location instead of the normal location under /usr/local.

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.0.tar.gz

 $ wget http://www.example.org/download/debhello-1.0.tar.gz
 ...
 $ tar -xzmf debhello-1.0.tar.gz
 $ tree
.
├── debhello-1.0
│   ├── Makefile
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
└── debhello-1.0.tar.gz

5 directories, 7 files

Aqui, o Makefile usa $(DESTDIR) e $(prefix) apropriadamente. Todos os outros ficheiros são o mesmo que em Section 13.2, “Nenhum Makefile (shell, CLI)”” e a maioria das atividades de empacotamento são as mesmas.

Makefile (v=1.0). 

 $ cat debhello-1.0/Makefile
prefix = /usr/local

all:
        : # do nothing

install:
        install -D scripts/hello \
                $(DESTDIR)$(prefix)/bin/hello
        install -m 644 -D data/hello.desktop \
                $(DESTDIR)$(prefix)/share/applications/hello.desktop
        install -m 644 -D data/hello.png \
                $(DESTDIR)$(prefix)/share/pixmaps/hello.png
        install -m 644 -D man/hello.1 \
                $(DESTDIR)$(prefix)/share/man/man1/hello.1

clean:
        : # do nothing

distclean: clean

uninstall:
        -rm -f $(DESTDIR)$(prefix)/bin/hello
        -rm -f $(DESTDIR)$(prefix)/share/applications/hello.desktop
        -rm -f $(DESTDIR)$(prefix)/share/pixmaps/hello.png
        -rm -f $(DESTDIR)$(prefix)/share/man/man1/hello.1

.PHONY: all install clean distclean uninstall

Vamos empacotar isto com o comando debmake. Aqui, a opção -b':sh' é usada para especificar que o pacote binário gerado é um script de shell.

 $ cd /path/to/debhello-1.0
 $ debmake -b':sh' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.0", rev="1"
I: *** start packaging in "debhello-1.0". ***
I: provide debhello_1.0.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.0.tar.gz debhello_1.0.orig.tar.gz
I: pwd = "/path/to/debhello-1.0"
I: parse binary package settings: :sh
I: binary package=debhello Type=script / Arch=all M-A=foreign
I: analyze the source tree
I: build_type = make
I: scan source for copyright+license text and file extensions
I:  25 %, ext = md
 ...

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=1.0): 

 $ cd /path/to/debhello-1.0
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1

%:
        dh $@

#override_dh_auto_install:
#       dh_auto_install -- prefix=/usr

#override_dh_install:
#       dh_install --list-missing -X.pyc -X.pyo

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=1.0): 

 $ cd /path/to/debhello-1.0
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1

%:
        dh $@

override_dh_auto_install:
        dh_auto_install -- prefix=/usr

Como esta fonte de autor tem o Makefile de autor apropriado, não é preciso criar os ficheiros debian/install e debian/manpages.

O ficheiro debian/control é exactamente o mesmo que aquele em Section 13.2, “Nenhum Makefile (shell, CLI)”.

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

Ficheiros modelo sob debian/. (v=1.0): 

 $ rm -f debian/clean debian/dirs debian/install debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ rm -rf debian/patches
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── gbp.conf
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 11 files

O resto das atividades de empacotamento são praticamente o mesmo que em Section 13.2, “Nenhum Makefile (shell, CLI)”.

Here is an example of creating a simple Debian package from a Python3 CLI program using pyproject.toml.

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.1.tar.gz

 $ wget http://www.example.org/download/debhello-1.1.tar.gz
 ...
 $ tar -xzmf debhello-1.1.tar.gz
 $ tree
.
├── debhello-1.1
│   ├── LICENSE
│   ├── MANIFEST.in
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── manpages
│   │   └── hello.1
│   ├── pyproject.toml
│   └── src
│       └── debhello
│           ├── __init__.py
│           └── main.py
└── debhello-1.1.tar.gz

6 directories, 10 files

Aqui, o conteúdo desta árvore fonte debhello como se segue.

pyproject.toml (v=1.1) — PEP 517 configuration. 

 $ cat debhello-1.1/pyproject.toml
[build-system]
requires = ["setuptools >= 61.0"]  # REQUIRED if [build-system] table is used...
build-backend = "setuptools.build_meta"  # If not defined, then legacy behavi...

[project]
name = "debhello"
version = "1.1.0"
description = "Hello Python (CLI)"
readme = {file = "README.md", content-type = "text/markdown"}
requires-python = ">=3.12"
license = {file = "LICENSE.txt"}
keywords = ["debhello"]
authors = [
  {name = "Osamu Aoki", email = "osamu@debian.org" },
]
maintainers = [
  {name = "Osamu Aoki", email = "osamu@debian.org" },
]
classifiers = [
  "Development Status :: 5 - Production/Stable",
  "Intended Audience :: Developers",
        "Topic :: System :: Archiving :: Packaging",
  "License :: OSI Approved :: MIT License",
  "Programming Language :: Python :: 3",
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: 3 :: Only",
  # Others
  "Operating System :: POSIX :: Linux",
  "Natural Language :: English",
]
[project.urls]
"Homepage" = "https://salsa.debian.org/debian/debmake"
"Bug Reports" = "https://salsa.debian.org/debian/debmake/issues"
"Source" = "https://salsa.debian.org/debian/debmake"
[project.scripts]
hello = "debhello.main:main"
[tool.setuptools]
package-dir = {"" = "src"}
packages = ["debhello"]
include-package-data = true

MANIFEST.in (v=1.1) — for tar-ball. 

 $ cat debhello-1.1/MANIFEST.in
include data/*
include manpages/*

src/debhello/__init__.py (v=1.1). 

 $ cat debhello-1.1/src/debhello/__init__.py
"""
debhello program (CLI)
"""

src/debhello/main.py (v=1.1) — command entry point. 

 $ cat debhello-1.1/src/debhello/main.py
"""
debhello program
"""

import sys

__version__ = '1.1.0'

def main():  # needed for console script
    print(' ========== Hello Python3 ==========')
    print('argv = {}'.format(sys.argv))
    print('version = {}'.format(debhello.__version__))
    return

if __name__ == "__main__":
    sys.exit(main())

Vamos empacotar isto usando o comando debmake. Aqui, a opção -b':py3' é usada para especificar o pacote binário gerado que contém o script Python3 e os ficheiros do módulo.

 $ cd /path/to/debhello-1.1
 $ debmake -b':py3' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.1", rev="1"
I: *** start packaging in "debhello-1.1". ***
I: provide debhello_1.1.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.1.tar.gz debhello_1.1.orig.tar.gz
I: pwd = "/path/to/debhello-1.1"
I: parse binary package settings: :py3
I: binary package=debhello Type=python3 / Arch=all M-A=foreign
I: analyze the source tree
W: setuptools build system.
I: build_type = Python (pyproject.toml: PEP-518, PEP-621, PEP-660)
I: scan source for copyright+license text and file extensions
 ...

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=1.1): 

 $ cd /path/to/debhello-1.1
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1

%:
        dh $@ --with python3 --buildsystem=pybuild

Isto é essencialmente o ficheiro debian/rules standard com o comando dh.

The use of the --with python3 option invokes dh_python3 to calculate Python dependencies, add maintainer scripts to byte compiled files, etc. See dh_python3(1).

The use of the --buildsystem=pybuild option invokes various build systems for requested Python versions in order to build modules and extensions. See pybuild(1).

debian/control (ficheiro modelo, v=1.1): 

 $ cat debian/control
Source: debhello
Section: unknown
Priority: optional
Maintainer: "Osamu Aoki" <osamu@debian.org>
Build-Depends: debhelper-compat (= 13),
               dh-python,
               pybuild-plugin-pyproject,
               python3-all,
               python3-setuptools
Standards-Version: 4.6.2
Homepage: <insert the upstream URL, if relevant>
Rules-Requires-Root: no
#Vcs-Git: https://salsa.debian.org/debian/debhello.git
#Vcs-Browser: https://salsa.debian.org/debian/debhello
#X-Python3-Version: >= 3.7

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}, ${python3:Depends}
Description: auto-generated package by debmake
 This Debian binary package was auto-generated by the
 debmake(1) command provided by the debmake package.

Since this is the Python3 package, the debmake command sets Architecture: all and Multi-Arch: foreign. Also, it sets required substvar parameters as Depends: ${python3:Depends}, ${misc:Depends}. These are explained in Chapter 6, Basics for packaging.

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=1.1): 

 $ cd /path/to/debhello-1.1
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export PYBUILD_NAME=debhello
export PYBUILD_VERBOSE=1
export DH_VERBOSE=1

%:
        dh $@ --with python3 --buildsystem=pybuild

debian/control (versão do maintainer, v=1.1): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper-compat (= 13),
               pybuild-plugin-pyproject,
               python3-all
Standards-Version: 4.6.2
Rules-Requires-Root: no
Vcs-Browser: https://salsa.debian.org/debian/debmake-doc
Vcs-Git: https://salsa.debian.org/debian/debmake-doc.git
Homepage: https://salsa.debian.org/debian/debmake-doc

Package: debhello
Architecture: all
Depends: ${misc:Depends}, ${python3:Depends}
Description: Simple packaging example for debmake
 This is an example package to demonstrate Debian packaging using
 the debmake command.
 .
 The generated Debian package uses the dh command offered by the
 debhelper package and the dpkg source format `3.0 (quilt)'.

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

This debhello command comes with the upstream-provided manpage and desktop file but the upstream pyproject.toml doesn’t install them. So you need to update debian/install and debian/manpages as follows:

debian/install (versão do maintainer, v=1.1): 

 $ vim debian/copyright
 ... hack, hack, hack, ...
 $ cat debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: debhello
Upstream-Contact: Osamu Aoki <osamu@debian.org>
Source: https://salsa.debian.org/debian/debmake-doc

Files:     *
Copyright: 2015-2024 Osamu Aoki <osamu@debian.org>
License:   Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

debian/manpages (versão do maintainer, v=1.1): 

 $ vim debian/install
 ... hack, hack, hack, ...
 $ cat debian/install
data/hello.desktop usr/share/applications
data/hello.png usr/share/pixmaps

O resto das atividades de empacotamento são praticamente o mesmo que em Section 13.3, “Makefile (shell, CLI)”.

Ficheiros modelo sob debian/. (v=1.1): 

 $ rm -f debian/clean debian/dirs debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ rm -rf debian/patches
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── gbp.conf
├── install
├── manpages
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 13 files

Aqui está a lista de dependências gerada de debhello_1.1-1_all.deb.

A lista de dependências gerada de debhello_1.1-1_all.deb

 $ dpkg -f debhello_1.1-1_all.deb pre-depends \
            depends recommends conflicts breaks
Depends: python3:any

Aqui está um exemplo de criar um pacote Debian simples a partir de um programa GUI de shell POSIX usando o Makefile como seu sistema de compilação.

Esta fonte de autor é baseada no Section 13.3, “Makefile (shell, CLI)”” com suporte GUI avançado.

Vamos assumir que o tarball de autor seja debhello-1.2.tar.gz.

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.2.tar.gz

 $ wget http://www.example.org/download/debhello-1.2.tar.gz
 ...
 $ tar -xzmf debhello-1.2.tar.gz
 $ tree
.
├── debhello-1.2
│   ├── Makefile
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
└── debhello-1.2.tar.gz

5 directories, 7 files

Aqui, o hello foi reescrito para usar o comando zenity para tornar isto num programa GUI GTK+.

hello (v=1.2). 

 $ cat debhello-1.2/scripts/hello
#!/bin/sh -e
zenity --info --title "hello" --text "Hello from the shell!"

Aqui, o ficheiro desktop foi atualizado para ser Terminal=false como um programa GUI.

hello.desktop (v=1.2). 

 $ cat debhello-1.2/data/hello.desktop
[Desktop Entry]
Name=Hello
Name[fr]=Bonjour
Comment=Greetings
Comment[fr]=Salutations
Type=Application
Keywords=hello
Exec=hello
Terminal=false
Icon=hello.png
Categories=Utility;

Todos os outros ficheiros são o mesmo que em Section 13.3, “Makefile (shell, CLI)”.

Let’s package this with the debmake command. Here, the -b':sh' option is used to specify that the generated binary package is a shell script.

 $ cd /path/to/debhello-1.2
 $ debmake -b':sh' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.2", rev="1"
I: *** start packaging in "debhello-1.2". ***
I: provide debhello_1.2.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.2.tar.gz debhello_1.2.orig.tar.gz
I: pwd = "/path/to/debhello-1.2"
I: parse binary package settings: :sh
I: binary package=debhello Type=script / Arch=all M-A=foreign
I: analyze the source tree
I: build_type = make
I: scan source for copyright+license text and file extensions
I:  25 %, ext = md
 ...

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/control (ficheiro modelo, v=1.2): 

 $ cat debian/control
Source: debhello
Section: unknown
Priority: optional
Maintainer: "Osamu Aoki" <osamu@debian.org>
Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: <insert the upstream URL, if relevant>
Rules-Requires-Root: no
#Vcs-Git: https://salsa.debian.org/debian/debhello.git
#Vcs-Browser: https://salsa.debian.org/debian/debhello

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Description: auto-generated package by debmake
 This Debian binary package was auto-generated by the
 debmake(1) command provided by the debmake package.

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/control (versão do maintainer, v=1.2): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: zenity, ${misc:Depends}
Description: Simple packaging example for debmake
 This Debian binary package is an example package.
 (This is an example only)

Por favor note a dependência adicionada manualmente zenity.

O ficheiro debian/rules é exatamente o mesmo que aquele em Section 13.3, “Makefile (shell, CLI)”.

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

Ficheiros modelo sob debian/. (v=1.2): 

 $ rm -f debian/clean debian/dirs debian/install debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ rm -rf debian/patches
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── gbp.conf
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 11 files

O resto das atividades de empacotamento são praticamente o mesmo que em Section 13.3, “Makefile (shell, CLI)”.

Aqui está a lista de dependências gerada de debhello_1.2-1_all.deb.

A lista de dependências gerada de debhello_1.2-1_all.deb

 $ dpkg -f debhello_1.2-1_all.deb pre-depends \
            depends recommends conflicts breaks
Depends: zenity

Here is an example of creating a simple Debian package from a Python3 GUI program using pyproject.toml.

Vamos assumir que o tarball do autor seja debhello-1.3.tar.gz.

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.3.tar.gz

 $ wget http://www.example.org/download/debhello-1.3.tar.gz
 ...
 $ tar -xzmf debhello-1.3.tar.gz
 $ tree
.
├── debhello-1.3
│   ├── LICENSE
│   ├── MANIFEST.in
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── manpages
│   │   └── hello.1
│   ├── pyproject.toml
│   └── src
│       └── debhello
│           ├── __init__.py
│           └── main.py
└── debhello-1.3.tar.gz

6 directories, 10 files

Aqui, o conteúdo desta árvore fonte debhello como se segue.

pyproject.toml (v=1.3) — PEP 517 configuration. 

 $ cat debhello-1.3/pyproject.toml
[build-system]
requires = ["setuptools >= 61.0"]  # REQUIRED if [build-system] table is used...
build-backend = "setuptools.build_meta"  # If not defined, then legacy behavi...

[project]
name = "debhello"
version = "1.3.0"
description = "Hello Python (GUI)"
readme = {file = "README.md", content-type = "text/markdown"}
requires-python = ">=3.12"
license = {file = "LICENSE.txt"}
keywords = ["debhello"]
authors = [
  {name = "Osamu Aoki", email = "osamu@debian.org" },
]
maintainers = [
  {name = "Osamu Aoki", email = "osamu@debian.org" },
]
classifiers = [
  "Development Status :: 5 - Production/Stable",
  "Intended Audience :: Developers",
        "Topic :: System :: Archiving :: Packaging",
  "License :: OSI Approved :: MIT License",
  "Programming Language :: Python :: 3",
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: 3 :: Only",
  # Others
  "Operating System :: POSIX :: Linux",
  "Natural Language :: English",
]
[project.urls]
"Homepage" = "https://salsa.debian.org/debian/debmake"
"Bug Reports" = "https://salsa.debian.org/debian/debmake/issues"
"Source" = "https://salsa.debian.org/debian/debmake"
[project.scripts]
hello = "debhello.main:main"
[tool.setuptools]
package-dir = {"" = "src"}
packages = ["debhello"]
include-package-data = true

MANIFEST.in (v=1.3) — for tar-ball. 

 $ cat debhello-1.3/MANIFEST.in
include data/*
include manpages/*

src/debhello/__init__.py (v=1.3). 

 $ cat debhello-1.3/src/debhello/__init__.py
"""
debhello program (GUI)
"""

src/debhello/main.py (v=1.3) — command entry point. 

 $ cat debhello-1.3/src/debhello/main.py
#!/usr/bin/python3
from gi.repository import Gtk

__version__ = '1.3.0'

class TopWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        self.title = "Hello World!"
        self.counter = 0
        self.border_width = 10
        self.set_default_size(400, 100)
        self.set_position(Gtk.WindowPosition.CENTER)
        self.button = Gtk.Button(label="Click me!")
        self.button.connect("clicked", self.on_button_clicked)
        self.add(self.button)
        self.connect("delete-event", self.on_window_destroy)

    def on_window_destroy(self, *args):
        Gtk.main_quit(*args)

    def on_button_clicked(self, widget):
        self.counter += 1
        widget.set_label("Hello, World!\nClick count = %i" % self.counter)

def main():
    window = TopWindow()
    window.show_all()
    Gtk.main()

if __name__ == '__main__':
    main()

Vamos empacotar isto com o comando debmake. Aqui, a opção -b':py3' é usada para especificar que o pacote binário gerado que contém o script Python3 e os ficheiros do módulo.

 $ cd /path/to/debhello-1.3
 $ debmake -b':py3' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.3", rev="1"
I: *** start packaging in "debhello-1.3". ***
I: provide debhello_1.3.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.3.tar.gz debhello_1.3.orig.tar.gz
I: pwd = "/path/to/debhello-1.3"
I: parse binary package settings: :py3
I: binary package=debhello Type=python3 / Arch=all M-A=foreign
I: analyze the source tree
W: setuptools build system.
I: build_type = Python (pyproject.toml: PEP-518, PEP-621, PEP-660)
I: scan source for copyright+license text and file extensions
 ...

The result is practically the same as in Section 13.4, “pyproject.toml (Python3, CLI)”.

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=1.3): 

 $ cd /path/to/debhello-1.3
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export PYBUILD_NAME=debhello
export PYBUILD_VERBOSE=1
export DH_VERBOSE=1

%:
        dh $@ --with python3 --buildsystem=pybuild

debian/control (versão do maintainer, v=1.3): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper-compat (= 13),
               pybuild-plugin-pyproject,
               python3-all
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: gir1.2-gtk-3.0, python3-gi, ${misc:Depends}, ${python3:Depends}
Description: Simple packaging example for debmake
 This Debian binary package is an example package.
 (This is an example only)

Por favor note as dependências adicionadas manualmente python3-gi e gir1.2-gtk-3.0.

The rest of the packaging activities are practically the same as in <pyproject>>.

Aqui está a lista de dependências gerada de debhello_1.3-1_all.deb.

A lista de dependências gerada de debhello_1.3-1_all.deb

 $ dpkg -f debhello_1.3-1_all.deb pre-depends \
            depends recommends conflicts breaks
Depends: gir1.2-gtk-3.0, python3-gi, python3:any

Aqui está um exemplo de criar um pacote Debian simples a partir de um programa fonte C simples usando o Makefile como seu sistema de compilação.

Este é um exemplo de fonte de autor avançada para Chapter 5, Simple packaging”. Isto vem com o manual, o ficheiro desktop, e o ícone de desktop. Isto também de liga a uma biblioteca externa libm para ser um exemplo mais prático.

Vamos assumir que o tarball de autor seja debhello-1.4.tar.gz.

Este tipo de fonte destina-se a ser instalado como ficheiro não-sistema como:

 $ tar -xzmf debhello-1.4.tar.gz
 $ cd debhello-1.4
 $ make
 $ make install

Debian packaging requires changing this make install process to install files into the target system image location instead of the normal location under /usr/local.

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.4.tar.gz

 $ wget http://www.example.org/download/debhello-1.4.tar.gz
 ...
 $ tar -xzmf debhello-1.4.tar.gz
 $ tree
.
├── debhello-1.4
│   ├── LICENSE
│   ├── Makefile
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── src
│       ├── config.h
│       └── hello.c
└── debhello-1.4.tar.gz

5 directories, 9 files

Aqui, os conteúdos desta fonte são como se segue.

src/hello.c (v=1.4): 

 $ cat debhello-1.4/src/hello.c
#include "config.h"
#include <math.h>
#include <stdio.h>
int
main()
{
        printf("Hello, I am " PACKAGE_AUTHOR "!\n");
        printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0));
        return 0;
}

src/config.h (v=1.4): 

 $ cat debhello-1.4/Makefile
prefix = /usr/local

all: src/hello

src/hello: src/hello.c
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ -lm

install: src/hello
        install -D src/hello \
                $(DESTDIR)$(prefix)/bin/hello
        install -m 644 -D data/hello.desktop \
                $(DESTDIR)$(prefix)/share/applications/hello.desktop
        install -m 644 -D data/hello.png \
                $(DESTDIR)$(prefix)/share/pixmaps/hello.png
        install -m 644 -D man/hello.1 \
                $(DESTDIR)$(prefix)/share/man/man1/hello.1

clean:
        -rm -f src/hello

distclean: clean

uninstall:
        -rm -f $(DESTDIR)$(prefix)/bin/hello
        -rm -f $(DESTDIR)$(prefix)/share/applications/hello.desktop
        -rm -f $(DESTDIR)$(prefix)/share/pixmaps/hello.png
        -rm -f $(DESTDIR)$(prefix)/share/man/man1/hello.1

.PHONY: all install clean distclean uninstall

Makefile (v=1.4): 

 $ cat debhello-1.4/src/config.h
#define PACKAGE_AUTHOR "Osamu Aoki"

Por favor note que este Makefile tem o alvo install apropriado para o manual, o ficheiro desktop, e o ícone desktop.

Vamos empacotar isto com o comando debmake.

 $ cd /path/to/debhello-1.4
 $ debmake -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.4", rev="1"
I: *** start packaging in "debhello-1.4". ***
I: provide debhello_1.4.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.4.tar.gz debhello_1.4.orig.tar.gz
I: pwd = "/path/to/debhello-1.4"
I: parse binary package settings:
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: analyze the source tree
I: build_type = make
I: scan source for copyright+license text and file extensions
I:  33 %, ext = c
 ...

O resultado é praticamente o mesmo que em Section 5.6, “Step 2: Generate template files with debmake.

Vamos tornar este pacote Debian, que é praticamente o mesmo que em Section 5.7, “Passo 3: Modificação dos ficheiros modelo”, melhor senso o maintainer.

If the DEB_BUILD_MAINT_OPTIONS environment variable is not exported in debian/rules, lintian warns W: debhello: hardening-no-relro usr/bin/hello for the linking of libm.

O ficheiro debian/control faz exatamente o mesmo que aquele em Section 5.7, “Passo 3: Modificação dos ficheiros modelo”, pois a biblioteca libm está sempre disponível como parte de libc6 (Priority: required).

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

Ficheiros modelo sob debian/. (v=1.4): 

 $ rm -f debian/clean debian/dirs debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ rm -rf debian/patches
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── gbp.conf
├── install
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 12 files

O resto das atividades de empacotamento são praticamente o mesmo que em Section 5.8, “Step 4: Building package with debuild.

Aqui está a lista de dependências gerada de todos os pacotes binários.

A lista de dependências gerada de todos os pacotes binários (v=1.4): 

 $ dpkg -f debhello-dbgsym_1.4-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: debhello (= 1.4-1)
 $ dpkg -f debhello_1.4-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libc6 (>= 2.34)

Aqui está um exemplo de criar um pacote Debian simples a partir de um programa fonte C simples usando Makefile.in e configure como seu sistema de compilação.

Este é um exemplo de fonte de autor avançado para Section 13.7, “Makefile (pacote singular-binário)””. Isto também liga a uma biblioteca externa, libm, e esta fonte é configurável usando argumentos ao script configure. o qual gera os ficheiros Makefile e src/config.h.

Vamos assumir que o tarball do autor seja debhello-1.5.tar.gz.

Este tipo de fonte destina-se a ser instalado como um ficheiro não-sistema, por exemplo, como:

 $ tar -xzmf debhello-1.5.tar.gz
 $ cd debhello-1.5
 $ ./configure --with-math
 $ make
 $ make install

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.5.tar.gz

 $ wget http://www.example.org/download/debhello-1.5.tar.gz
 ...
 $ tar -xzmf debhello-1.5.tar.gz
 $ tree
.
├── debhello-1.5
│   ├── LICENSE
│   ├── Makefile.in
│   ├── README.md
│   ├── configure
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── src
│       └── hello.c
└── debhello-1.5.tar.gz

5 directories, 9 files

Aqui, os conteúdos desta fonte são como se segue.

src/hello.c (v=1.5): 

 $ cat debhello-1.5/src/hello.c
#include "config.h"
#ifdef WITH_MATH
#  include <math.h>
#endif
#include <stdio.h>
int
main()
{
        printf("Hello, I am " PACKAGE_AUTHOR "!\n");
#ifdef WITH_MATH
        printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0));
#else
        printf("I can't do MATH!\n");
#endif
        return 0;
}

Makefile.in (v=1.5): 

 $ cat debhello-1.5/Makefile.in
prefix = @prefix@

all: src/hello

src/hello: src/hello.c
        $(CC) @VERBOSE@ \
                $(CPPFLAGS) \
                $(CFLAGS) \
                $(LDFLAGS) \
                -o $@ $^ \
                @LINKLIB@

install: src/hello
        install -D src/hello \
                $(DESTDIR)$(prefix)/bin/hello
        install -m 644 -D data/hello.desktop \
                $(DESTDIR)$(prefix)/share/applications/hello.desktop
        install -m 644 -D data/hello.png \
                $(DESTDIR)$(prefix)/share/pixmaps/hello.png
        install -m 644 -D man/hello.1 \
                $(DESTDIR)$(prefix)/share/man/man1/hello.1

clean:
        -rm -f src/hello

distclean: clean

uninstall:
        -rm -f $(DESTDIR)$(prefix)/bin/hello
        -rm -f $(DESTDIR)$(prefix)/share/applications/hello.desktop
        -rm -f $(DESTDIR)$(prefix)/share/pixmaps/hello.png
        -rm -f $(DESTDIR)$(prefix)/share/man/man1/hello.1

.PHONY: all install clean distclean uninstall

configure (v=1.5): 

 $ cat debhello-1.5/configure
#!/bin/sh -e
# default values
PREFIX="/usr/local"
VERBOSE=""
WITH_MATH="0"
LINKLIB=""
PACKAGE_AUTHOR="John Doe"

# parse arguments
while [ "${1}" != "" ]; do
  VAR="${1%=*}" # Drop suffix =*
  VAL="${1#*=}" # Drop prefix *=
  case "${VAR}" in
  --prefix)
    PREFIX="${VAL}"
    ;;
  --verbose|-v)
    VERBOSE="-v"
    ;;
  --with-math)
    WITH_MATH="1"
    LINKLIB="-lm"
    ;;
  --author)
    PACKAGE_AUTHOR="${VAL}"
    ;;
  *)
    echo "W: Unknown argument: ${1}"
  esac
  shift
done

# setup configured Makefile and src/config.h
sed -e "s,@prefix@,${PREFIX}," \
    -e "s,@VERBOSE@,${VERBOSE}," \
    -e "s,@LINKLIB@,${LINKLIB}," \
    <Makefile.in >Makefile
if [ "${WITH_MATH}" = 1 ]; then
echo "#define WITH_MATH" >src/config.h
else
echo "/* not defined: WITH_MATH */" >src/config.h
fi
echo "#define PACKAGE_AUTHOR \"${PACKAGE_AUTHOR}\"" >>src/config.h

Please note that the configure command replaces strings with @…​@ in Makefile.in to produce Makefile and creates src/config.h.

Vamos empacotar isto com o comando debmake.

 $ cd /path/to/debhello-1.5
 $ debmake -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.5", rev="1"
I: *** start packaging in "debhello-1.5". ***
I: provide debhello_1.5.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.5.tar.gz debhello_1.5.orig.tar.gz
I: pwd = "/path/to/debhello-1.5"
I: parse binary package settings:
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: analyze the source tree
I: build_type = configure
I: scan source for copyright+license text and file extensions
I:  17 %, ext = in
 ...

O resultado é semelhante a Section 5.6, “Step 2: Generate template files with debmake mas não exactamente o mesmo.

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=1.5): 

 $ cd /path/to/debhello-1.5
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1

%:
        dh $@

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=1.5): 

 $ cd /path/to/debhello-1.5
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

%:
        dh $@

override_dh_auto_configure:
        dh_auto_configure -- \
                --with-math \
                --author="Osamu Aoki"

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

O resto das atividades de empacotamento são praticamente o mesmo que em Section 5.8, “Step 4: Building package with debuild.

Here is an example of creating a simple Debian package from a simple C source program using Autotools = Autoconf and Automake (Makefile.am and configure.ac) as its build system.

Esta fonte geralmente vem também com os ficheiros de autor auto-gerados Makefile.in e configure . Esta fonte pode ser empacotada usando estes ficheiros como em Section 13.8, “Makefile.in + configure (pacote singular-binário)”” com a ajuda do pacote autotools-dev.

The better alternative is to regenerate these files using the latest Autoconf and Automake packages if the upstream provided Makefile.am and configure.ac are compatible with the latest version. This is advantageous for porting to new CPU architectures, etc. This can be automated by using the --with autoreconf option for the dh command.

Vamos assumir que o tarball do autor seja debhello-1.6.tar.gz.

Este tipo de fonte destina-se a ser instalado como um ficheiro não-sistema, por exemplo, como:

 $ tar -xzmf debhello-1.6.tar.gz
 $ cd debhello-1.6
 $ autoreconf -ivf # optional
 $ ./configure --with-math
 $ make
 $ make install

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.6.tar.gz

 $ wget http://www.example.org/download/debhello-1.6.tar.gz
 ...
 $ tar -xzmf debhello-1.6.tar.gz
 $ tree
.
├── debhello-1.6
│   ├── LICENSE
│   ├── Makefile.am
│   ├── README.md
│   ├── configure.ac
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   ├── Makefile.am
│   │   └── hello.1
│   └── src
│       ├── Makefile.am
│       └── hello.c
└── debhello-1.6.tar.gz

5 directories, 11 files

Aqui, os conteúdos desta fonte são como se segue.

src/hello.c (v=1.6): 

 $ cat debhello-1.6/src/hello.c
#include "config.h"
#ifdef WITH_MATH
#  include <math.h>
#endif
#include <stdio.h>
int
main()
{
        printf("Hello, I am " PACKAGE_AUTHOR "!\n");
#ifdef WITH_MATH
        printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0));
#else
        printf("I can't do MATH!\n");
#endif
        return 0;
}

Makefile.am (v=1.6): 

 $ cat debhello-1.6/Makefile.am
SUBDIRS = src man
 $ cat debhello-1.6/man/Makefile.am
dist_man_MANS = hello.1
 $ cat debhello-1.6/src/Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = hello.c

configure.ac (v=1.6): 

 $ cat debhello-1.6/configure.ac
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([debhello],[2.1],[foo@example.org])
AC_CONFIG_SRCDIR([src/hello.c])
AC_CONFIG_HEADERS([config.h])
echo "Standard customization chores"
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign])
# Add #define PACKAGE_AUTHOR ... in config.h with a comment
AC_DEFINE(PACKAGE_AUTHOR, ["Osamu Aoki"], [Define PACKAGE_AUTHOR])
echo "Add --with-math option functionality to ./configure"
AC_ARG_WITH([math],
  [AS_HELP_STRING([--with-math],
    [compile with math library  @<:@default=yes@:>@])],
  [],
  [with_math="yes"]
  )
echo "==== withval   := \"$withval\""
echo "==== with_math := \"$with_math\""
# m4sh if-else construct
AS_IF([test "x$with_math" != "xno"],[
  echo "==== Check include: math.h"
  AC_CHECK_HEADER(math.h,[],[
    AC_MSG_ERROR([Couldn't find math.h.] )
  ])
  echo "==== Check library: libm"
  AC_SEARCH_LIBS(atan, [m])
  #AC_CHECK_LIB(m, atan)
  echo "==== Build with LIBS := \"$LIBS\""
  AC_DEFINE(WITH_MATH, [1], [Build with the math library])
],[
  echo "==== Skip building with math.h."
  AH_TEMPLATE(WITH_MATH, [Build without the math library])
])
# Checks for programs.
AC_PROG_CC
AC_CONFIG_FILES([Makefile
                 man/Makefile
                 src/Makefile])
AC_OUTPUT

[Tip]Tip

Without foreign strictness level specified in AM_INIT_AUTOMAKE() as above, automake defaults to gnu strictness level requiring several files in the top-level directory. See 3.2 Strictness in the automake document.

Vamos empacotar isto com o comando debmake.

 $ cd /path/to/debhello-1.6
 $ debmake -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.6", rev="1"
I: *** start packaging in "debhello-1.6". ***
I: provide debhello_1.6.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.6.tar.gz debhello_1.6.orig.tar.gz
I: pwd = "/path/to/debhello-1.6"
I: parse binary package settings:
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: analyze the source tree
I: build_type = Autotools with autoreconf
I: scan source for copyright+license text and file extensions
I:  33 %, ext = am
 ...

O resultado é semelhante a Section 13.8, “Makefile.in + configure (pacote singular-binário)” mas não exactamente o mesmo.

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=1.6): 

 $ cd /path/to/debhello-1.6
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1

%:
        dh $@ --with autoreconf

#override_dh_install:
#       dh_install --list-missing -X.la -X.pyc -X.pyo

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=1.6): 

 $ cd /path/to/debhello-1.6
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

%:
        dh $@ --with autoreconf

override_dh_auto_configure:
        dh_auto_configure -- \
                --with-math

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

O resto das atividades de empacotamento são praticamente o mesmo que em Section 5.8, “Step 4: Building package with debuild.

Here is an example of creating a simple Debian package from a simple C source program using CMake (CMakeLists.txt and some files such as config.h.in) as its build system.

The cmake command generates the Makefile file based on the CMakeLists.txt file and its -D option. It also configures the file as specified in its configure_file(…​) by replacing strings with @…​@ and changing the #cmakedefine …​ line.

Vamos assumir que o tarball do autor seja debhello-1.7.tar.gz.

Este tipo de fonte destina-se a ser instalado como um ficheiro não-sistema, por exemplo, como:

 $ tar -xzmf debhello-1.7.tar.gz
 $ cd debhello-1.7
 $ mkdir obj-x86_64-linux-gnu # for out-of-tree build
 $ cd obj-x86_64-linux-gnu
 $ cmake ..
 $ make
 $ make install

Vamos obter a fonte e criar o pacote Debian.

Download debhello-1.7.tar.gz

 $ wget http://www.example.org/download/debhello-1.7.tar.gz
 ...
 $ tar -xzmf debhello-1.7.tar.gz
 $ tree
.
├── debhello-1.7
│   ├── CMakeLists.txt
│   ├── LICENSE
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   ├── CMakeLists.txt
│   │   └── hello.1
│   └── src
│       ├── CMakeLists.txt
│       ├── config.h.in
│       └── hello.c
└── debhello-1.7.tar.gz

5 directories, 11 files

Aqui, os conteúdos desta fonte são como se segue.

src/hello.c (v=1.7): 

 $ cat debhello-1.7/src/hello.c
#include "config.h"
#ifdef WITH_MATH
#  include <math.h>
#endif
#include <stdio.h>
int
main()
{
        printf("Hello, I am " PACKAGE_AUTHOR "!\n");
#ifdef WITH_MATH
        printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0));
#else
        printf("I can't do MATH!\n");
#endif
        return 0;
}

src/config.h.in (v=1.7): 

 $ cat debhello-1.7/src/config.h.in
/* name of the package author */
#define PACKAGE_AUTHOR "@PACKAGE_AUTHOR@"
/* math library support */
#cmakedefine WITH_MATH

CMakeLists.txt (v=1.7): 

 $ cat debhello-1.7/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(debhello)
set(PACKAGE_AUTHOR "Osamu Aoki")
add_subdirectory(src)
add_subdirectory(man)
 $ cat debhello-1.7/man/CMakeLists.txt
install(
  FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello.1
  DESTINATION share/man/man1
)
 $ cat debhello-1.7/src/CMakeLists.txt
# Always define HAVE_CONFIG_H
add_definitions(-DHAVE_CONFIG_H)
# Interactively define WITH_MATH
option(WITH_MATH "Build with math support" OFF)
#variable_watch(WITH_MATH)
# Generate config.h from config.h.in
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
  "${CMAKE_CURRENT_BINARY_DIR}/config.h"
)
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
add_executable(hello hello.c)
install(TARGETS hello
  RUNTIME DESTINATION bin
)

Vamos empacotar isto com o comando debmake.

 $ cd /path/to/debhello-1.7
 $ debmake -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="1.7", rev="1"
I: *** start packaging in "debhello-1.7". ***
I: provide debhello_1.7.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-1.7.tar.gz debhello_1.7.orig.tar.gz
I: pwd = "/path/to/debhello-1.7"
I: parse binary package settings:
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: analyze the source tree
I: build_type = Cmake
I: scan source for copyright+license text and file extensions
I:  33 %, ext = text
 ...

O resultado é semelhante a Section 13.8, “Makefile.in + configure (pacote singular-binário)”” mas não exactamente o mesmo.

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=1.7): 

 $ cd /path/to/debhello-1.7
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1

%:
        dh $@

#override_dh_auto_configure:
#       dh_auto_configure -- \
#             -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_TARGET_MULTIARCH)"

debian/control (ficheiro modelo, v=1.7): 

 $ cat debian/control
Source: debhello
Section: unknown
Priority: optional
Maintainer: "Osamu Aoki" <osamu@debian.org>
Build-Depends: cmake, debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: <insert the upstream URL, if relevant>
Rules-Requires-Root: no
#Vcs-Git: https://salsa.debian.org/debian/debhello.git
#Vcs-Browser: https://salsa.debian.org/debian/debhello

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: auto-generated package by debmake
 This Debian binary package was auto-generated by the
 debmake(1) command provided by the debmake package.

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=1.7): 

 $ cd /path/to/debhello-1.7
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

%:
        dh $@

override_dh_auto_configure:
        dh_auto_configure -- -DWITH-MATH=1

debian/control (versão do maintainer, v=1.7): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: cmake, debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: Simple packaging example for debmake
 This Debian binary package is an example package.
 (This is an example only)

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

O resto das atividades de empacotamento são praticamente o mesmo que em Section 13.8, “Makefile.in + configure (pacote singular-binário)”.

Here is an example of creating a set of Debian binary packages including the executable package, the shared library package, the development file package, and the debug symbol package from a simple C source program using Autotools = Autoconf and Automake (which use Makefile.am and configure.ac as their input files) as its build system.

Vamos empacotar isto do mesmo modo que em Section 13.9, “Autotools (pacote singular-binário)””.

Vamos assumir que o tarball do autor seja debhello-2.0.tar.gz.

Este tipo de fonte destina-se a ser instalado como um ficheiro não-sistema, por exemplo, como:

 $ tar -xzmf debhello-2.0.tar.gz
 $ cd debhello-2.0
 $ autoreconf -ivf # optional
 $ ./configure --with-math
 $ make
 $ make install

Vamos obter a fonte e criar o pacote Debian.

Download debhello-2.0.tar.gz

 $ wget http://www.example.org/download/debhello-2.0.tar.gz
 ...
 $ tar -xzmf debhello-2.0.tar.gz
 $ tree
.
├── debhello-2.0
│   ├── LICENSE
│   ├── Makefile.am
│   ├── README.md
│   ├── configure.ac
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── lib
│   │   ├── Makefile.am
│   │   ├── sharedlib.c
│   │   └── sharedlib.h
│   ├── man
│   │   ├── Makefile.am
│   │   └── hello.1
│   └── src
│       ├── Makefile.am
│       └── hello.c
└── debhello-2.0.tar.gz

6 directories, 14 files

Aqui, os conteúdos desta fonte são como se segue.

src/hello.c (v=2.0): 

 $ cat debhello-2.0/src/hello.c
#include "config.h"
#include <stdio.h>
#include <sharedlib.h>
int
main()
{
        printf("Hello, I am " PACKAGE_AUTHOR "!\n");
        sharedlib();
        return 0;
}

lib/sharedlib.h e lib/sharedlib.c (v=1.6): 

 $ cat debhello-2.0/lib/sharedlib.h
int sharedlib();
 $ cat debhello-2.0/lib/sharedlib.c
#include <stdio.h>
int
sharedlib()
{
        printf("This is a shared library!\n");
        return 0;
}

Makefile.am (v=2.0): 

 $ cat debhello-2.0/Makefile.am
# recursively process `Makefile.am` in SUBDIRS
SUBDIRS = lib src man
 $ cat debhello-2.0/man/Makefile.am
# manpages (distributed in the source package)
dist_man_MANS = hello.1
 $ cat debhello-2.0/lib/Makefile.am
# libtool librares to be produced
lib_LTLIBRARIES = libsharedlib.la

# source files used for lib_LTLIBRARIES
libsharedlib_la_SOURCES = sharedlib.c

# C pre-processor flags used for lib_LTLIBRARIES
#libsharedlib_la_CPPFLAGS =

# Headers files to be installed in <prefix>/include
include_HEADERS = sharedlib.h

# Versioning Libtool Libraries with version triplets
libsharedlib_la_LDFLAGS = -version-info 1:0:0
 $ cat debhello-2.0/src/Makefile.am
# program executables to be produced
bin_PROGRAMS = hello

# source files used for bin_PROGRAMS
hello_SOURCES = hello.c

# C pre-processor flags used for bin_PROGRAMS
AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/lib

# Extra options for the linker for hello
# hello_LDFLAGS =

# Libraries the `hello` binary to be linked
hello_LDADD = $(top_srcdir)/lib/libsharedlib.la

configure.ac (v=2.0): 

 $ cat debhello-2.0/configure.ac
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([debhello],[2.2],[foo@example.org])
AC_CONFIG_SRCDIR([src/hello.c])
AC_CONFIG_HEADERS([config.h])
echo "Standard customization chores"
AC_CONFIG_AUX_DIR([build-aux])

AM_INIT_AUTOMAKE([foreign])

# Set default to --enable-shared --disable-static
LT_INIT([shared disable-static])

# find the libltdl sources in the libltdl sub-directory
LT_CONFIG_LTDL_DIR([libltdl])

# choose one
LTDL_INIT([recursive])
#LTDL_INIT([subproject])
#LTDL_INIT([nonrecursive])

# Add #define PACKAGE_AUTHOR ... in config.h with a comment
AC_DEFINE(PACKAGE_AUTHOR, ["Osamu Aoki"], [Define PACKAGE_AUTHOR])
# Checks for programs.
AC_PROG_CC

# only for the recursive case
AC_CONFIG_FILES([Makefile
                 lib/Makefile
                 man/Makefile
                 src/Makefile])
AC_OUTPUT

Vamos empacotar isto com o comando debmake em múltiplos pacotes:

  • debhello: tipo = bin
  • libsharedlib1: tipo = lib
  • libsharedlib-dev: tipo = dev

Here, the -b\',libsharedlib1,libsharedlib-dev' option is used to specify the generated binary packages.

 $ cd /path/to/debhello-2.0
 $ debmake -b',libsharedlib1,libsharedlib-dev' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="2.0", rev="1"
I: *** start packaging in "debhello-2.0". ***
I: provide debhello_2.0.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-2.0.tar.gz debhello_2.0.orig.tar.gz
I: pwd = "/path/to/debhello-2.0"
I: parse binary package settings: ,libsharedlib1,libsharedlib-dev
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: binary package=libsharedlib1 Type=lib / Arch=any M-A=same
I: binary package=libsharedlib-dev Type=dev / Arch=any M-A=same
I: analyze the source tree
I: build_type = Autotools with autoreconf
 ...

O resultado é semelhante a Section 13.8, “Makefile.in + configure (pacote singular-binário)” mas com mais ficheiros modelo.

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=2.0): 

 $ cd /path/to/debhello-2.0
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1

%:
        dh $@ --with autoreconf

#override_dh_install:
#       dh_install --list-missing -X.la -X.pyc -X.pyo

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=2.0): 

 $ cd /path/to/debhello-2.0
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

%:
        dh $@ --with autoreconf

override_dh_missing:
        dh_missing -X.la

debian/control (versão do maintainer, v=2.0): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper-compat (= 13), dh-autoreconf
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: libsharedlib1 (= ${binary:Version}),
         ${misc:Depends},
         ${shlibs:Depends}
Description: Simple packaging example for debmake
 This package contains the compiled binary executable.
 .
 This Debian binary package is an example package.
 (This is an example only)

Package: libsharedlib1
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: Simple packaging example for debmake
 This package contains the shared library.

Package: libsharedlib-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}
Description: Simple packaging example for debmake
 This package contains the development files.

debian/*.install (versão do maintainer, v=2.0): 

 $ vim debian/copyright
 ... hack, hack, hack, ...
 $ cat debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: debhello
Upstream-Contact: Osamu Aoki <osamu@debian.org>
Source: https://salsa.debian.org/debian/debmake-doc

Files:     *
Copyright: 2015-2021 Osamu Aoki <osamu@debian.org>
License:   Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Como esta fonte de autor cria o auto-gerado Makefile apropriado, não é preciso criar os ficheiros debian/install e debian/manpages.

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

Ficheiros modelo sob debian/. (v=2.0): 

 $ rm -f debian/clean debian/dirs debian/install debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ rm -rf debian/patches
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── debhello.dirs
├── debhello.doc-base
├── debhello.docs
├── debhello.examples
├── debhello.info
├── debhello.install
├── debhello.links
├── debhello.manpages
├── gbp.conf
├── libsharedlib-dev.install
├── libsharedlib1.install
├── libsharedlib1.symbols
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 22 files

O resto das atividades de empacotamento são praticamente o mesmo que em Section 13.8, “Makefile.in + configure (pacote singular-binário)”.

Aqui está a lista de dependências gerada de todos os pacotes binários.

A lista de dependências gerada de todos os pacotes binários (v=2.0): 

 $ dpkg -f debhello-dbgsym_2.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: debhello (= 2.0-1)
 $ dpkg -f debhello_2.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libsharedlib1 (= 2.0-1), libc6 (>= 2.34)
 $ dpkg -f libsharedlib-dev_2.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libsharedlib1 (= 2.0-1)
 $ dpkg -f libsharedlib1-dbgsym_2.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libsharedlib1 (= 2.0-1)
 $ dpkg -f libsharedlib1_2.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libc6 (>= 2.2.5)

Here is an example of creating a set of Debian binary packages including the executable package, the shared library package, the development file package, and the debug symbol package from a simple C source program using CMake (CMakeLists.txt and some files such as config.h.in) as its build system.

Vamos assumir que o tarball do autor seja debhello-2.1.tar.gz.

Este tipo de fonte destina-se a ser instalado como um ficheiro não-sistema, por exemplo, como:

 $ tar -xzmf debhello-2.1.tar.gz
 $ cd debhello-2.1
 $ mkdir obj-x86_64-linux-gnu
 $ cd obj-x86_64-linux-gnu
 $ cmake ..
 $ make
 $ make install

Vamos obter a fonte e criar o pacote Debian.

Download debhello-2.1.tar.gz

 $ wget http://www.example.org/download/debhello-2.1.tar.gz
 ...
 $ tar -xzmf debhello-2.1.tar.gz
 $ tree
.
├── debhello-2.1
│   ├── CMakeLists.txt
│   ├── LICENSE
│   ├── README.md
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── lib
│   │   ├── CMakeLists.txt
│   │   ├── sharedlib.c
│   │   └── sharedlib.h
│   ├── man
│   │   ├── CMakeLists.txt
│   │   └── hello.1
│   └── src
│       ├── CMakeLists.txt
│       ├── config.h.in
│       └── hello.c
└── debhello-2.1.tar.gz

6 directories, 14 files

Aqui, os conteúdos desta fonte são como se segue.

src/hello.c (v=2.1): 

 $ cat debhello-2.1/src/hello.c
#include "config.h"
#include <stdio.h>
#include <sharedlib.h>
int
main()
{
        printf("Hello, I am " PACKAGE_AUTHOR "!\n");
        sharedlib();
        return 0;
}

src/config.h.in (v=2.1): 

 $ cat debhello-2.1/src/config.h.in
/* name of the package author */
#define PACKAGE_AUTHOR "@PACKAGE_AUTHOR@"

lib/sharedlib.c e lib/sharedlib.h (v=2.1): 

 $ cat debhello-2.1/lib/sharedlib.h
int sharedlib();
 $ cat debhello-2.1/lib/sharedlib.c
#include <stdio.h>
int
sharedlib()
{
        printf("This is a shared library!\n");
        return 0;
}

CMakeLists.txt (v=2.1): 

 $ cat debhello-2.1/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(debhello)
set(PACKAGE_AUTHOR "Osamu Aoki")
add_subdirectory(lib)
add_subdirectory(src)
add_subdirectory(man)
 $ cat debhello-2.1/man/CMakeLists.txt
install(
  FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello.1
  DESTINATION share/man/man1
)
 $ cat debhello-2.1/src/CMakeLists.txt
# Always define HAVE_CONFIG_H
add_definitions(-DHAVE_CONFIG_H)
# Generate config.h from config.h.in
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
  "${CMAKE_CURRENT_BINARY_DIR}/config.h"
  )
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_SOURCE_DIR}/lib")

add_executable(hello hello.c)
target_link_libraries(hello sharedlib)
install(TARGETS hello
  RUNTIME DESTINATION bin
)

Vamos empacotar isto com o comando debmake.

 $ cd /path/to/debhello-2.1
 $ debmake -b',libsharedlib1,libsharedlib-dev' -x1
I: set parameters
 ...
I: sanity check of parameters
I: pkg="debhello", ver="2.1", rev="1"
I: *** start packaging in "debhello-2.1". ***
I: provide debhello_2.1.orig.tar.gz for non-native Debian package
I: pwd = "/path/to"
I: $ ln -sf debhello-2.1.tar.gz debhello_2.1.orig.tar.gz
I: pwd = "/path/to/debhello-2.1"
I: parse binary package settings: ,libsharedlib1,libsharedlib-dev
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: binary package=libsharedlib1 Type=lib / Arch=any M-A=same
I: binary package=libsharedlib-dev Type=dev / Arch=any M-A=same
I: analyze the source tree
I: build_type = Cmake
 ...

O resultado é semelhante a Section 13.8, “Makefile.in + configure (pacote singular-binário)”” mas não exactamente o mesmo.

Vamos inspecionar os ficheiros modelo notáveis gerados.

debian/rules (ficheiro modelo, v=2.1): 

 $ cd /path/to/debhello-2.1
 $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1

%:
        dh $@

#override_dh_auto_configure:
#       dh_auto_configure -- \
#             -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_TARGET_MULTIARCH)"

Vamos criar este pacote Debian melhor sendo o maintainer.

debian/rules (versão do maintainer, v=2.1): 

 $ cd /path/to/debhello-2.1
 $ vim debian/rules
 ... hack, hack, hack, ...
 $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)

%:
        dh $@

override_dh_auto_configure:
        dh_auto_configure -- \
              -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_HOST_MULTIARCH)"

debian/control (versão do maintainer, v=2.1): 

 $ vim debian/control
 ... hack, hack, hack, ...
 $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: cmake, debhelper-compat (= 13)
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: libsharedlib1 (= ${binary:Version}),
         ${misc:Depends},
         ${shlibs:Depends}
Description: Simple packaging example for debmake
 This package contains the compiled binary executable.
 .
 This Debian binary package is an example package.
 (This is an example only)

Package: libsharedlib1
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: Simple packaging example for debmake
 This package contains the shared library.

Package: libsharedlib-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}
Description: Simple packaging example for debmake
 This package contains the development files.

debian/*.install (versão do maintainer, v=2.1): 

 $ vim debian/copyright
 ... hack, hack, hack, ...
 $ cat debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: debhello
Upstream-Contact: Osamu Aoki <osamu@debian.org>
Source: https://salsa.debian.org/debian/debmake-doc

Files:     *
Copyright: 2015-2021 Osamu Aoki <osamu@debian.org>
License:   Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Este CMakeList.txt do autor precisa receber uma patch para cooperar com o caminho multiarch.

debian/patches/* (versão do maintainer, v=2.1): 

 ... hack, hack, hack, ...
 $ cat debian/libsharedlib1.symbols
libsharedlib.so.1 libsharedlib1 #MINVER#
 sharedlib@Base 2.1

Como esta fonte de autor cria o auto-gerado Makefile apropriado, não é preciso criar os ficheiros debian/install e debian/manpages.

Existem vários outros ficheiros modelo sob o directório debian/. Estes também precisam de ser atualizados.

Ficheiros modelo sob debian/. (v=2.1): 

 $ rm -f debian/clean debian/dirs debian/install debian/links
 $ rm -f debian/README.source debian/source/*.ex
 $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── debhello.dirs
├── debhello.doc-base
├── debhello.docs
├── debhello.examples
├── debhello.info
├── debhello.install
├── debhello.links
├── debhello.manpages
├── gbp.conf
├── libsharedlib-dev.install
├── libsharedlib1.install
├── libsharedlib1.symbols
├── patches/
│   ├── 000-cmake-multiarch.patch
│   └── series
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

5 directories, 24 files

O resto das atividades de empacotamento são praticamente o mesmo que em Section 13.8, “Makefile.in + configure (pacote singular-binário)”.

Aqui está a lista de dependências gerada de todos os pacotes binários.

A lista de dependências gerada de todos os pacotes binários (v=2.1): 

 $ dpkg -f debhello-dbgsym_2.1-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: debhello (= 2.1-1)
 $ dpkg -f debhello_2.1-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libsharedlib1 (= 2.1-1), libc6 (>= 2.34)
 $ dpkg -f libsharedlib-dev_2.1-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libsharedlib1 (= 2.1-1)
 $ dpkg -f libsharedlib1-dbgsym_2.1-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libsharedlib1 (= 2.1-1)
 $ dpkg -f libsharedlib1_2.1-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libc6 (>= 2.2.5)

Aqui está um exemplo de actualizar a fonte C simples do autor debhello-2.0.tar.gz apresentado em Section 13.11, “Autotools (pacote multi-binário)”” para internacionalização (i18n) e criar a fonte C do autor actualizada debhello-2.0.tar.gz.

Na situação real, o pacote já deveria estar internacionalizado. Assim este exemplo é educativo para você compreender como esta internacionalização é implementada.

[Tip]Tip

A atividade de rotina do maintainer para o i18n é simplesmente adicionar ficheiros po de tradução reportados para si via Bug Tracking System (BTS) para o directório po/ e actualizar a lista de linguagens no ficheiro po/LINGUAS.

Vamos obter a fonte e criar o pacote Debian.

Download debhello-2.0.tar.gz (i18n). 

 $ wget http://www.example.org/download/debhello-2.0.tar.gz
 ...
 $ tar -xzmf debhello-2.0.tar.gz
 $ tree
.
├── debhello-2.0
│   ├── LICENSE
│   ├── Makefile.am
│   ├── README.md
│   ├── configure.ac
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── lib
│   │   ├── Makefile.am
│   │   ├── sharedlib.c
│   │   └── sharedlib.h
│   ├── man
│   │   ├── Makefile.am
│   │   └── hello.1
│   └── src
│       ├── Makefile.am
│       └── hello.c
└── debhello-2.0.tar.gz

6 directories, 14 files

Internacionalizar esta árvore fonte com o comando gettextize e remover ficheiros auto-gerados pelo Autotools.

corra gettextize (i18n): 

 $ cd /path/to/debhello-2.0
 $ gettextize
Creating po/ subdirectory
Creating build-aux/ subdirectory
Copying file ABOUT-NLS
Copying file build-aux/config.rpath
Not copying intl/ directory.
Copying file po/Makefile.in.in
Copying file po/Makevars.template
Copying file po/Rules-quot
Copying file po/boldquot.sed
Copying file po/en@boldquot.header
Copying file po/en@quot.header
Copying file po/insert-header.sin
Copying file po/quot.sed
Copying file po/remove-potcdate.sin
Creating initial po/POTFILES.in
Creating po/ChangeLog
Creating directory m4
Copying file m4/gettext.m4
Copying file m4/iconv.m4
Copying file m4/lib-ld.m4
Copying file m4/lib-link.m4
Copying file m4/lib-prefix.m4
Copying file m4/nls.m4
Copying file m4/po.m4
Copying file m4/progtest.m4
Creating m4/ChangeLog
Updating Makefile.am (backup is in Makefile.am~)
Updating configure.ac (backup is in configure.ac~)
Creating ChangeLog

Please use AM_GNU_GETTEXT([external]) in order to cause autoconfiguration
to look for an external libintl.

Please create po/Makevars from the template in po/Makevars.template.
You can then remove po/Makevars.template.

Please fill po/POTFILES.in as described in the documentation.

Please run 'aclocal' to regenerate the aclocal.m4 file.
You need aclocal from GNU automake 1.9 (or newer) to do this.
Then run 'autoconf' to regenerate the configure file.

You will also need config.guess and config.sub, which you can get from the CV...
of the 'config' project at http://savannah.gnu.org/. The commands to fetch th...
are
$ wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/conf...
$ wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/conf...

You might also want to copy the convenience header file gettext.h
from the /usr/share/gettext directory into your package.
It is a wrapper around <libintl.h> that implements the configure --disable-nl...
option.

Press Return to acknowledge the previous 6 paragraphs.
 $ rm -rf m4 build-aux *~

Vamos verificar os ficheiros gerados sob o directório po/.

ficheiros em po (i18n): 

 $ ls -l po
total 60
-rw-rw-r-- 1 osamu osamu   494 Jul 24 10:14 ChangeLog
-rw-rw-r-- 1 osamu osamu 17577 Jul 24 10:14 Makefile.in.in
-rw-rw-r-- 1 osamu osamu  3376 Jul 24 10:14 Makevars.template
-rw-rw-r-- 1 osamu osamu    59 Jul 24 10:14 POTFILES.in
-rw-rw-r-- 1 osamu osamu  2203 Jul 24 10:14 Rules-quot
-rw-rw-r-- 1 osamu osamu   217 Jul 24 10:14 boldquot.sed
-rw-rw-r-- 1 osamu osamu  1337 Jul 24 10:14 en@boldquot.header
-rw-rw-r-- 1 osamu osamu  1203 Jul 24 10:14 en@quot.header
-rw-rw-r-- 1 osamu osamu   672 Jul 24 10:14 insert-header.sin
-rw-rw-r-- 1 osamu osamu   153 Jul 24 10:14 quot.sed
-rw-rw-r-- 1 osamu osamu   432 Jul 24 10:14 remove-potcdate.sin

Let’s update the configure.ac by adding AM_GNU_GETTEXT([external]), etc..

configure.ac (i18n): 

 $ vim configure.ac
 ... hack, hack, hack, ...
 $ cat configure.ac
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([debhello],[2.2],[foo@example.org])
AC_CONFIG_SRCDIR([src/hello.c])
AC_CONFIG_HEADERS([config.h])
echo "Standard customization chores"
AC_CONFIG_AUX_DIR([build-aux])

AM_INIT_AUTOMAKE([foreign])

# Set default to --enable-shared --disable-static
LT_INIT([shared disable-static])

# find the libltdl sources in the libltdl sub-directory
LT_CONFIG_LTDL_DIR([libltdl])

# choose one
LTDL_INIT([recursive])
#LTDL_INIT([subproject])
#LTDL_INIT([nonrecursive])

# Add #define PACKAGE_AUTHOR ... in config.h with a comment
AC_DEFINE(PACKAGE_AUTHOR, ["Osamu Aoki"], [Define PACKAGE_AUTHOR])
# Checks for programs.
AC_PROG_CC

# desktop file support required
AM_GNU_GETTEXT_VERSION([0.19.3])
AM_GNU_GETTEXT([external])

# only for the recursive case
AC_CONFIG_FILES([Makefile
                 po/Makefile.in
                 lib/Makefile
                 man/Makefile
                 src/Makefile])
AC_OUTPUT

Vamos criar o ficheiro po/Makevars a partir do modelo po/Makevars.template.

po/Makevars (i18n): 

 ... hack, hack, hack, ...
 $ diff -u po/Makevars.template po/Makevars
--- po/Makevars.template        2024-07-24 10:14:46.440850967 +0900
+++ po/Makevars 2024-07-24 10:14:46.520852183 +0900
@@ -18,14 +18,14 @@
 # or entity, or to disclaim their copyright.  The empty string stands for
 # the public domain; in this case the translators are expected to disclaim
 # their copyright.
-COPYRIGHT_HOLDER = Free Software Foundation, Inc.
+COPYRIGHT_HOLDER = Osamu Aoki <osamu@debian.org>

 # This tells whether or not to prepend "GNU " prefix to the package
 # name that gets inserted into the header of the $(DOMAIN).pot file.
 # Possible values are "yes", "no", or empty.  If it is empty, try to
 # detect it automatically by scanning the files in $(top_srcdir) for
 # "GNU packagename" string.
-PACKAGE_GNU =
+PACKAGE_GNU = no

 # This is the email address or URL to which the translators shall report
 # bugs in the untranslated strings:
 $ rm po/Makevars.template

Let’s update C sources for the i18n version by wrapping strings with _(…​).

src/hello.c (i18n): 

 ... hack, hack, hack, ...
 $ cat src/hello.c
#include "config.h"
#include <stdio.h>
#include <sharedlib.h>
#include <libintl.h>
#define _(string) gettext (string)
int
main()
{
        printf(_("Hello, I am " PACKAGE_AUTHOR "!\n"));
        sharedlib();
        return 0;
}

lib/sharedlib.c (i18n): 

 ... hack, hack, hack, ...
 $ cat lib/sharedlib.c
#include <stdio.h>
#include <libintl.h>
#define _(string) gettext (string)
int
sharedlib()
{
        printf(_("This is a shared library!\n"));
        return 0;
}

O novo gettext (v=0.19) consegue lidar coma versão i18n do ficheiro de desktop directamente.

data/hello.desktop.in (i18n): 

 $ fgrep -v '[ja]=' data/hello.desktop > data/hello.desktop.in
 $ rm data/hello.desktop
 $ cat data/hello.desktop.in
[Desktop Entry]
Name=Hello
Comment=Greetings
Type=Application
Keywords=hello
Exec=hello
Terminal=true
Icon=hello.png
Categories=Utility;

Vamos listar os ficheiros de entrada para extrair as strings traduzíveis em po/POTFILES.in.

po/POTFILES.in (i18n): 

 ... hack, hack, hack, ...
 $ cat po/POTFILES.in
src/hello.c
lib/sharedlib.c
data/hello.desktop.in

Aqui está a raiz actualizada Makefile.am com po adicionado à variável de ambiente SUBDIRS.

Makefile.am (i18n): 

 $ cat Makefile.am
# recursively process `Makefile.am` in SUBDIRS
SUBDIRS = po lib src man

ACLOCAL_AMFLAGS = -I m4

EXTRA_DIST = build-aux/config.rpath m4/ChangeLog

Vamos criar um ficheiro modelo de tradução, debhello.pot.

po/debhello.pot (i18n): 

 $ xgettext -f po/POTFILES.in -d debhello -o po/debhello.pot -k_
 $ cat po/debhello.pot
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-24 10:14+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: src/hello.c:9
#, c-format
msgid "Hello, I am "
msgstr ""

#: lib/sharedlib.c:7
#, c-format
msgid "This is a shared library!\n"
msgstr ""

#: data/hello.desktop.in:3
msgid "Hello"
msgstr ""

#: data/hello.desktop.in:4
msgid "Greetings"
msgstr ""

#: data/hello.desktop.in:6
msgid "hello"
msgstr ""

Vamos adicionar uma tradução para Francês.

po/LINGUAS e po/fr.po (i18n): 

 $ echo 'fr' > po/LINGUAS
 $ cp po/debhello.pot po/fr.po
 $ vim po/fr.po
 ... hack, hack, hack, ...
 $ cat po/fr.po
# SOME DESCRIPTIVE TITLE.
# This file is put in the public domain.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: debhello 2.2\n"
"Report-Msgid-Bugs-To: foo@example.org\n"
"POT-Creation-Date: 2015-03-01 20:22+0900\n"
"PO-Revision-Date: 2015-02-21 23:18+0900\n"
"Last-Translator: Osamu Aoki <osamu@debian.org>\n"
"Language-Team: French <LL@li.org>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: src/hello.c:34
#, c-format
msgid "Hello, my name is %s!\n"
msgstr "Bonjour, je m'appelle %s!\n"

#: lib/sharedlib.c:29
#, c-format
msgid "This is a shared library!\n"
msgstr "Ceci est une bibliothèque partagée!\n"

#: data/hello.desktop.in:3
msgid "Hello"
msgstr ""

#: data/hello.desktop.in:4
msgid "Greetings"
msgstr "Salutations"

#: data/hello.desktop.in:6
msgid "hello"
msgstr ""

#: data/hello.desktop.in:9
msgid "hello.png"
msgstr ""

As atividades de empacotamento são praticamente as mesmas que em Section 13.11, “Autotools (pacote multi-binário)”.

Você pode encontrar mais exemplos i18n ao seguir Section 13.14, “Detalhes”.

Detalhes actuais dos exemplos apresentados e suas variantes podem ser obtidos com o seguinte.

Como obter detalhes. 

 $ apt-get source debmake-doc
 $ cd debmake-doc*
 $ cd examples
 $ view examples/README.md

Follow the exact instruction in examples/README.md.

 $ cd examples
 $ make

Now, each directory named as examples/debhello-?.?_build-? contains the Debian packaging example.

  • registo de atividade de linha de comandos de consola emulada: o ficheiro .log
  • registo de atividade de linha de comandos de consola emulada (curto): o ficheiro .slog
  • instantâneo da imagem de árvore fonte após o comando debmake: o directório debmake
  • instantâneo da imagem de árvore fonte após empacotamento apropriado: o directório package
  • instantâneo da imagem de árvore fonte após o comando debuild: o directório test

Os exemplos notáveis são:

  • o script de shell POSIX com Makefile com i18n (v=3.0),
  • a fonte C com Makefile.in + configure com i18n (v=3.2),
  • a fonte C com Autotools com i18n com i18n (v=3.3), e
  • a fonte C com CMake com i18n (v=3.4).