Chapter 8. More Examples

Table of Contents

8.1. Cherry-pick templates
8.2. No Makefile (shell, CLI)
8.3. Makefile (shell, CLI)
8.4. setup.py (Python3, CLI)
8.5. Makefile (shell, GUI)
8.6. setup.py (Python3, GUI)
8.7. Makefile (single-binary)
8.8. Makefile.in + configure (single-binary)
8.9. Autotools (single-binary)
8.10. CMake (single-binary)
8.11. Autotools (multi-binary)
8.12. CMake (multi-binary)
8.13. Internationalization
8.14. Details

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

It is highly recommended to practice and experiment with all the steps of Debian packaging with simple packages. This chapter provides you with the many upstream cases for your practice.

This should also serve as introductory examples for many programing topics.

Please note Debian takes few things serious.

The typical packaging example presented in Chapter 4, Simple Example is the prerequisite for this chapter.

Some details are intentionally left vague in the following. Please try to read the pertinent documentation and practice yourself to find them out.

[Tip] Tip

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

Here is an example of creating a simple Debian package from a zero content source on an empty directory.

This is a good platform to get all the template files without making mess in the upstream source tree you are working on.

Let’s assume this empty directory to be debhello-0.1.

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

1 directory, 0 files

Let’s generate the maximum amount of template files by specifying the -x4 option.

Let’s also use the “-p debhello -t -u 0.1 -r 1” options to make missing upstream tarball.

 $ debmake -t -p debhello -u 0.1 -r 1 -x4
I: set parameters
 ...
I: debmake -x "4" ...
I: creating => debian/control
I: creating => debian/copyright
I: substituting => /usr/share/debmake/extra0/changelog
 ...
I: substituting => /usr/share/debmake/extra4/GPL-2.0+
I: creating => debian/license-examples/GPL-2.0+
I: substituting => /usr/share/debmake/extra4/LGPL-3.0+
I: creating => debian/license-examples/LGPL-3.0+
I: substituting => /usr/share/debmake/extra4/LGPL-2.1+
I: creating => debian/license-examples/LGPL-2.1+
I: $ wrap-and-sort

Let’s inspect generated template files.

 $ cd ..
 $ tree
.
├── debhello-0.1
│   └── debian
│       ├── README.Debian
│       ├── changelog
│       ├── clean
│       ├── compat
│       ├── control
│       ├── copyright
│       ├── debhello.bug-control.ex
│       ├── debhello.bug-presubj.ex
│       ├── debhello.bug-script.ex
│       ├── debhello.conffiles.ex
 ...
│       ├── source.lintian-overrides.ex
│       └── watch
├── debhello-0.1.tar.gz
└── debhello_0.1.orig.tar.gz -> debhello-0.1.tar.gz

5 directories, 52 files

Now you can copy any of these generated template files in the debhello-0.1/debian/ directory to your package as needed while renaming them as needed.

[Tip] Tip

The generated template files can be made more verbose ones by invoking the debmake command with the -T option (tutorial mode).

Here is an example of creating a simple Debian package from a POSIX shell CLI program without its build system.

Let’s assume this upstream tarball to be debhello-0.2.tar.gz.

This type of source has no automated means and files must be installed manually.

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

Let’s get the source and make the Debian package.

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
│   ├── LICENSE
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
└── debhello-0.2.tar.gz

4 directories, 6 files

Here, the POSIX shell script hello is a very simple one.

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

Here, the hello.desktop supports Desktop Entry Specification.

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;

Here, the hello.png is the icon graphics file.

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

 $ cd debhello-0.2
 $ debmake -b':sh'
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
...

Let’s inspect notable template files generated.

The source tree after the basic debmake execution. (v=0.2). 

 $ cd ..
 $ tree
.
├── debhello-0.2
│   ├── LICENSE
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── debian
│   │   ├── README.Debian
│   │   ├── changelog
│   │   ├── compat
│   │   ├── control
│   │   ├── copyright
│   │   ├── patches
│   │   │   └── series
│   │   ├── rules
│   │   ├── source
│   │   │   ├── format
│   │   │   └── local-options
│   │   └── watch
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
├── debhello-0.2.tar.gz
└── debhello_0.2.orig.tar.gz -> debhello-0.2.tar.gz

7 directories, 17 files

debian/rules (template file, v=0.2): 

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

%:
        dh $@

This is essentially the standard debian/rules file with the dh command. Since this is the script package, this template debian/rules file has no build flag related contents.

debian/control (template file, v=0.2): 

 $ cat debhello-0.2/debian/control
Source: debhello
Section: unknown
Priority: extra
Maintainer: "Firstname Lastname" <email.address@example.org>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.8
Homepage: <insert the upstream URL, if relevant>

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 5, Basics.

Since this upstream source lacks the upstream Makefile, that functionality needs to be provided by the maintainer. This upstream contains only a script file and data files and no C source files, the build process can be skipped but the install process needs to be implemented. For this case, this is achieved cleanly by adding the debian/install and debian/manpages files without complicating the debian/rules file.

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=0.2): 

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

%:
        dh $@

debian/control (maintainer version, v=0.2): 

 $ vim debhello-0.2/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-0.2/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Description: example package in the debmake-doc package
 This is an example package to demonstrate the 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)'.

[Warning] Warning

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

debian/install (maintainer version, v=0.2): 

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

debian/manpages (maintainer version, v=0.2): 

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

There are several other template files under the debian/ directory. These also need to be updated.

Template files under debian/. (v=0.2): 

 $ tree debhello-0.2/debian
debhello-0.2/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── install
├── manpages
├── patches
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 12 files

You can create a non-native Debian package using the debuild command (or its equivalents) in this source tree. The command output is very verbose and explains what it does as follows.

 $ cd debhello-0.2
 $ debuild
 dpkg-buildpackage -rfakeroot -us -uc -i
 ...
 fakeroot debian/rules clean
dh clean
 ...
 debian/rules build
dh build
   dh_update_autotools_config
   dh_auto_configure
   dh_auto_build
   dh_auto_test
 fakeroot debian/rules binary
dh binary
   dh_testroot
   dh_prep
        rm -f -- debian/debhello.substvars
 ...
 fakeroot debian/rules binary
dh binary
 ...
Finished running lintian.

Let’s inspect the result.

The generated files of debhello version 0.2 by the debuild command: 

 $ cd ..
 $ 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

1 directory, 8 files

You see all the generated files.

  • The debhello_0.2.orig.tar.gz is a symlink to the upstream tarball.
  • The debhello_0.2-1.debian.tar.xz contains the maintainer generated contents.
  • The debhello_0.2-1.dsc is the meta data file for the Debian source package.
  • The debhello_0.2-1_amd64.deb is the Debian binary package.
  • The debhello_0.2-1_amd64.changes is the meta data file for the Debian binary package.

The debhello_0.2-1.debian.tar.xz contains the Debian changes to the upstream source as follows.

The compressed archive contents of 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.png
debhello-0.2/data/hello.desktop
debhello-0.2/scripts/
debhello-0.2/scripts/hello
debhello-0.2/LICENSE
debhello-0.2/man/
debhello-0.2/man/hello.1
 $ tar --xz -tf debhello_0.2-1.debian.tar.xz
debian/
debian/README.Debian
debian/changelog
debian/compat
debian/control
debian/copyright
debian/install
debian/manpages
debian/patches/
debian/patches/series
debian/rules
debian/source/
debian/source/format
debian/watch

The debhello_0.2-1_amd64.deb contains the files to be installed as follows.

The binary package contents of debhello_0.2-1_amd64.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

Here is an example of creating a simple Debian package from a POSIX shell CLI program using the Makefile as its build system.

Let’s assume its upstream tarball to be debhello-1.0.tar.gz.

This type of source is meant to be installed as a non-system file as:

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

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

Let’s get the source and make the Debian package.

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
│   ├── LICENSE
│   ├── Makefile
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
└── debhello-1.0.tar.gz

4 directories, 7 files

Here, the Makefile uses $(DESTDIR) and $(prefix) properly. All other files are the same as Section 8.2, “No Makefile (shell, CLI)” and most of the packaging activities are the same.

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

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

 $ cd debhello-1.0
 $ debmake -b':sh'
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
...

Let’s inspect notable template files generated.

debian/rules (template file, v=1.0): 

 $ cat debhello-1.0/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

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=1.0): 

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

%:
        dh $@

override_dh_auto_install:
        dh_auto_install -- prefix=/usr

Since this upstream source has the proper upstream Makefile, there are no needs to create debian/install and debian/manpages files.

The debian/control file is exactly the same as the one in Section 8.2, “No Makefile (shell, CLI)”.

There are several other template files under the debian/ directory. These also need to be updated.

Template files under debian/. (v=1.0): 

 $ tree debhello-1.0/debian
debhello-1.0/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── patches
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 10 files

The rest of the packaging activities are practically the same as the one in Section 8.2, “No Makefile (shell, CLI)”.

Here is an example of creating a simple Debian package from a Python3 CLI program using the setup.py as its build system.

Let’s assume its upstream tarball to be debhello-1.1.tar.gz.

This type of source is meant to be installed as a non-system file as:

 $ tar -xzmf debhello-1.1.tar.gz
 $ cd debhello-1.1
 $ python3 setup.py install

Debian packaging requires to change the last line to “python3 setup.py install --install-layout=deb” to install files to the target system image location. This issue is automatically addressed when using the dh command for the Debian packaging.

Let’s get the source and make the Debian package.

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
│   ├── PKG-INFO
│   ├── hello_py
│   │   └── __init__.py
│   ├── scripts
│   │   └── hello
│   └── setup.py
└── debhello-1.1.tar.gz

3 directories, 7 files

Here, the hello script and its associated hello_py module are as follows.

hello (v=1.1). 

 $ cat debhello-1.1/scripts/hello
#!/usr/bin/python3
import hello_py

if __name__ == '__main__':
    hello_py.main()

hello_py/__init__.py (v=1.1). 

 $ cat debhello-1.1/hello_py/__init__.py
#!/usr/bin/python3
def main():
    print('Hello Python3!')
    input("Press Enter to continue...")
    return

if __name__ == '__main__':
    main()

These are packaged using the Python distutils with the setup.py and MANIFEST.in files.

setup.py (v=1.1). 

 $ cat debhello-1.1/setup.py
#!/usr/bin/python3
# vi:se ts=4 sts=4 et ai:
from distutils.core import setup

setup(name='debhello',
    version='4.0',
    description='Hello Python',
    long_description='Hello Python program.',
    author='Osamu Aoki',
    author_email='osamu@debian.org',
    url='http://people.debian.org/~osamu/',
    packages=['hello_py'],
    package_dir={'hello_py': 'hello_py'},
    scripts=['scripts/hello'],
    classifiers = ['Development Status :: 3 - Alpha',
        'Environment :: Console',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        'Operating System :: POSIX :: Linux',
        'Programming Language :: Python :: 3',
        'Topic :: Utilities',
    ],
    platforms   = 'POSIX',
    license     = 'MIT License'
)

MANIFEST.in (v=1.1). 

 $ cat debhello-1.1/MANIFEST.in
include MANIFEST.in
include LICENSE

[Tip] Tip

Many modern Python packages are distributed using setuptools. Since setuptools is an enhanced alternative to distutils, this example is useful for them.

Let’s package this with the debmake command. Here, the -b':py3' option is used to specify the generated binary package contain Python3 script and module files.

 $ cd debhello-1.1
 $ debmake -b':py3'
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
...

Let’s inspect notable template files generated.

debian/rules (template file, v=1.1): 

 $ cat debhello-1.1/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

This is essentially the standard debian/rules file with the dh command.

The use of “--with python3” option invokes dh_python3 to calculate Python dependencies, adds maintainer scripts to byte compile files, etc. See dh_python3(1).

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

debian/control (template file, v=1.1): 

 $ cat debhello-1.1/debian/control
Source: debhello
Section: unknown
Priority: extra
Maintainer: "Firstname Lastname" <email.address@example.org>
Build-Depends: debhelper (>=9), dh-python, python3-all
Standards-Version: 3.9.8
Homepage: <insert the upstream URL, if relevant>
X-Python3-Version: >= 3.2

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 5, Basics.

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=1.1): 

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

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

debian/control (maintainer version, v=1.1): 

 $ vim debhello-1.1/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-1.1/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper (>=9), dh-python, python3-all
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/
X-Python3-Version: >= 3.2

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}, ${python3:Depends}
Description: example package in the debmake-doc package
 This is an example package to demonstrate the 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)'.

The hello command does not come with the upstream provided manpage, let’s add it as the maintainer.

debian/manpages etc. (maintainer version, v=1.1): 

 $ vim debhello-1.1/debian/hello.1
 ... hack, hack, hack, ...
 $ vim debhello-1.1/debian/manpages
 ... hack, hack, hack, ...
 $ cat debhello-1.1/debian/manpages
debian/hello.1

There are several other template files under the debian/ directory. These also need to be updated.

The rest of the packaging activities are practically the same as the one in Section 8.3, “Makefile (shell, CLI)”.

Template files under debian/. (v=1.1): 

 $ tree debhello-1.1/debian
debhello-1.1/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── hello.1
├── manpages
├── patches
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 12 files

Here is the generated dependency list of binary packages.

The generated dependency list of binary packages (v=1.1): 

 $ dpkg -f debhello_1.1-1_all.deb pre-depends depends recommends conflicts br...
Depends: python3:any (>= 3.3.2-2~)

Here is an example of creating a simple Debian package from a POSIX shell GUI program using the Makefile as its build system.

This upstream is based in Section 8.3, “Makefile (shell, CLI)” with enhanced GUI support.

Let’s assume its upstream tarball to be debhello-1.2.tar.gz.

Let’s get the source and make the Debian package.

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
│   ├── LICENSE
│   ├── Makefile
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── scripts
│       └── hello
└── debhello-1.2.tar.gz

4 directories, 7 files

Here, the hello has been re-written to use the zenity command to make this a GTK+ GUI program.

hello (v=1.2). 

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

Here, the desktop file is updated to be Terminal=false as a GUI program.

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;

All other files are the same as Section 8.3, “Makefile (shell, CLI)”.

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

 $ cd debhello-1.2
 $ debmake -b':sh'
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
...

Let’s inspect notable template files generated.

debian/control (template file, v=1.2): 

 $ cat debhello-1.2/debian/control
Source: debhello
Section: unknown
Priority: extra
Maintainer: "Firstname Lastname" <email.address@example.org>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.8
Homepage: <insert the upstream URL, if relevant>

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.

Let’s make this Debian package better as the maintainer.

debian/control (maintainer version, v=1.2): 

 $ vim debhello-1.2/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-1.2/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: zenity, ${misc:Depends}
Description: example package in the debmake-doc package
 This is an example package to demonstrate the 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)'.

Please note manually added zenity.

The debian/rules file is exactly the same as the one in Section 8.3, “Makefile (shell, CLI)”.

There are several other template files under the debian/ directory. These also need to be updated.

Template files under debian/. (v=1.2): 

 $ tree debhello-1.2/debian
debhello-1.2/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── patches
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 10 files

The rest of the packaging activities are practically the same as the one in Section 8.3, “Makefile (shell, CLI)”.

Here is the generated dependency list of binary packages.

The generated dependency list of binary packages (v=1.2): 

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

Here is an example of creating a simple Debian package from a Python3 GUI program using the setup.py as its build system.

This upstream is based in Section 8.4, “setup.py (Python3, CLI)” with enhanced GUI, desktop icon, and manpage supports.

Let’s assume this upstream tarball to be debhello-1.3.tar.gz.

Let’s get the source and make the Debian package.

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
│   ├── PKG-INFO
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── hello_py
│   │   └── __init__.py
│   ├── man
│   │   └── hello.1
│   ├── scripts
│   │   └── hello
│   └── setup.py
└── debhello-1.3.tar.gz

5 directories, 10 files

Here are the upstream sources.

hello (v=1.3). 

 $ cat debhello-1.3/scripts/hello
#!/usr/bin/python3
import hello_py

if __name__ == '__main__':
    hello_py.main()

hello_py/__init__.py (v=1.3). 

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

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()

setup.py (v=1.3). 

 $ cat debhello-1.3/setup.py
#!/usr/bin/python3
# vi:se ts=4 sts=4 et ai:
from distutils.core import setup

setup(name='debhello',
    version='4.1',
    description='Hello Python',
    long_description='Hello Python program.',
    author='Osamu Aoki',
    author_email='osamu@debian.org',
    url='http://people.debian.org/~osamu/',
    packages=['hello_py'],
    package_dir={'hello_py': 'hello_py'},
    scripts=['scripts/hello'],
    data_files=[
        ('share/applications', ['data/hello.desktop']),
        ('share/pixmaps', ['data/hello.png']),
        ('share/man/man1', ['man/hello.1']),
    ],
    classifiers = ['Development Status :: 3 - Alpha',
        'Environment :: Console',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        'Operating System :: POSIX :: Linux',
        'Programming Language :: Python :: 3',
        'Topic :: Utilities',
    ],
    platforms   = 'POSIX',
    license     = 'MIT License'
)

MANIFEST.in (v=1.3). 

 $ cat debhello-1.3/MANIFEST.in
include MANIFEST.in
include LICENSE
include data/hello.deskto
include data/hello.png
include man/hello.1

Let’s package this with the debmake command. Here, the -b':py3' option is used to specify the generated binary package contain Python3 script and module files.

 $ cd debhello-1.3
 $ debmake -b':py3'
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
...

The result is practically the same as Section 8.4, “setup.py (Python3, CLI)”.

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=1.3): 

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

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

debian/control (maintainer version, v=1.3): 

 $ vim debhello-1.3/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-1.3/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper (>=9), dh-python, python3-all
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/
X-Python3-Version: >= 3.2

Package: debhello
Architecture: all
Multi-Arch: foreign
Depends: gir1.2-gtk-3.0, python3-gi, ${misc:Depends}, ${python3:Depends}
Description: example package in the debmake-doc package
 This is an example package to demonstrate the 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)'.

Please note manually added python3-gi and gir1.2-gtk-3.0.

Since this upstream source has manpage and other files with matching entries in the setup.py file, there are no needs to create them and add debian/install and debian/manpages files which was required in Section 8.4, “setup.py (Python3, CLI)”.

The rest of the packaging activities are practically the same as the one in Section 8.4, “setup.py (Python3, CLI)”.

Here is the generated dependency list of binary packages.

The generated dependency list of binary packages (v=1.3): 

 $ dpkg -f debhello_1.3-1_all.deb pre-depends depends recommends conflicts br...
Depends: gir1.2-gtk-3.0, python3-gi, python3:any (>= 3.3.2-2~)

Here is an example of creating a simple Debian package from a simple C source using the Makefile as its build system.

This is an enhanced upstream source example for Chapter 4, Simple Example. This comes with the manpage, the desktop file, and the desktop icon. This also links to an external library libm to be a more practical example.

Let’s assume this upstream tarball to be debhello-1.4.tar.gz.

This type of source is meant to be installed as a non-system file as:

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

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

Let’s get the source and make the Debian package.

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
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── src
│       ├── config.h
│       └── hello.c
└── debhello-1.4.tar.gz

4 directories, 8 files

Here, the contents of this source are as follows.

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/src/config.h
#define PACKAGE_AUTHOR "Osamu Aoki"

Makefile (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

Please note that this Makefile has the proper install target for the manpage, the desktop file, and the desktop icon.

Let’s package this with the debmake command.

 $ cd debhello-1.4
 $ debmake
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
...

The result is practically the same as Section 4.5, “Step 2: Generate template files with debmake”.

Let’s make this Debian package better as the maintainer which is practically the same as Section 4.6, “Step 3: Modification to the template files”.

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

The debian/control file making it exactly the same as one in Section 4.6, “Step 3: Modification to the template files”, since the libm library is always available as a part of the libc6 (Priority: required).

There are several other template files under the debian/ directory. These also need to be updated.

Template files under debian/. (v=1.4): 

 $ tree debhello-1.4/debian
debhello-1.4/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── patches
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 10 files

The rest of the packaging activities are practically the same as the one in Section 4.7, “Step 4: Building package with debuild”.

Here is the generated dependency list of binary packages.

The generated dependency list of binary packages (v=1.4): 

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

Here is an example of creating a simple Debian package from a simple C source using the Makefile.in and configure as its build system.

This is an enhanced upstream source example for Section 8.7, “Makefile (single-binary)”. This also links to an external library libm and this source is configurable using arguments to the configure script which generates the Makefile and src/config.h files.

Let’s assume this upstream tarball to be debhello-1.5.tar.gz.

This type of source is meant to be installed as a non-system file, for example, as:

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

Let’s get the source and make the Debian package.

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
│   ├── configure
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   └── hello.1
│   └── src
│       └── hello.c
└── debhello-1.5.tar.gz

4 directories, 8 files

Here, the contents of this source are as follows.

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 the Makefile.in to produce Makefile and creates src/config.h.

Let’s package this with the debmake command.

 $ cd debhello-1.5
 $ debmake
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
...

The result is similar to Section 4.5, “Step 2: Generate template files with debmake” but not exactly the same.

Let’s inspect notable template files generated.

debian/rules (template file, v=1.5): 

 $ cat debhello-1.5/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,--as-needed

%:
        dh $@

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=1.5): 

 $ vim debhello-1.5/debian/rules
 ... hack, hack, hack, ...
 $ cat debhello-1.5/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"

There are several other template files under the debian/ directory. These also need to be updated.

The rest of the packaging activities are practically the same as the one in Section 4.7, “Step 4: Building package with debuild”.

Here is an example of creating a simple Debian package from a simple C source using the Autotools = Autoconf and Automake (Makefile.am and configure.ac) as its build system. See Section 5.16.1, “Autotools”.

This source usually comes with the upstream auto-generated Makefile.in and configure files, too. This source can be packaged using these files as Section 8.8, “Makefile.in + configure (single-binary)” with the help of the autotools-dev package.

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 the porting to the new CPU architectures etc. This can be automated by using the “--with autoreconf” option for the dh command.

Let’s assume this upstream tarball to be debhello-1.6.tar.gz.

This type of source is meant to be installed as a non-system file, for example, as:

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

Let’s get the source and make the Debian package.

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
│   ├── Makefile.am
│   ├── configure.ac
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   ├── Makefile.am
│   │   └── hello.1
│   └── src
│       ├── Makefile.am
│       └── hello.c
└── debhello-1.6.tar.gz

4 directories, 9 files

Here, the contents of this source are as follows.

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

Let’s package this with the debmake command.

 $ cd debhello-1.6
 $ debmake
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
...

The result is similar to Section 8.8, “Makefile.in + configure (single-binary)” but not exactly the same.

Let’s inspect notable template files generated.

debian/rules (template file, v=1.6): 

 $ cat debhello-1.6/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,--as-needed

%:
        dh $@ --with autoreconf

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

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=1.6): 

 $ vim debhello-1.6/debian/rules
 ... hack, hack, hack, ...
 $ cat debhello-1.6/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

There are several other template files under the debian/ directory. These also need to be updated.

The rest of the packaging activities are practically the same as the one in Section 4.7, “Step 4: Building package with debuild”.

Here is an example of creating a simple Debian package from a simple C source using the CMake (CMakeLists.txt and some files such as config.h.in) as its build system. See Section 5.16.2, “CMake”.

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

Let’s assume this upstream tarball to be debhello-1.7.tar.gz.

This type of source is meant to be installed as a non-system file, for example, as:

 $ 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

Let’s get the source and make the Debian package.

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
│   ├── data
│   │   ├── hello.desktop
│   │   └── hello.png
│   ├── man
│   │   ├── CMakeLists.txt
│   │   └── hello.1
│   └── src
│       ├── CMakeLists.txt
│       ├── config.h.in
│       └── hello.c
└── debhello-1.7.tar.gz

4 directories, 9 files

Here, the contents of this source are as follows.

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
)

Let’s package this with the debmake command.

 $ cd debhello-1.7
 $ debmake
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
...

The result is similar to Section 8.8, “Makefile.in + configure (single-binary)” but not exactly the same.

Let’s inspect notable template files generated.

debian/rules (template file, v=1.7): 

 $ cat debhello-1.7/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,--as-needed

%:
        dh $@

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

debian/control (template file, v=1.7): 

 $ cat debhello-1.7/debian/control
Source: debhello
Section: unknown
Priority: extra
Maintainer: "Firstname Lastname" <email.address@example.org>
Build-Depends: cmake, debhelper (>=9)
Standards-Version: 3.9.8
Homepage: <insert the upstream URL, if relevant>

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.

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=1.7): 

 $ vim debhello-1.7/debian/rules
 ... hack, hack, hack, ...
 $ cat debhello-1.7/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 (maintainer version, v=1.7): 

 $ vim debhello-1.7/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-1.7/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: cmake, debhelper (>=9)
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: example package in the debmake-doc package
 This is an example package to demonstrate the 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)'.

There are several other template files under the debian/ directory. These also need to be updated.

The rest of the packaging activities are practically the same as the one in Section 8.8, “Makefile.in + configure (single-binary)”.

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 using the Autotools = Autoconf and Automake (Makefile.am and configure.ac) as its build system. See Section 5.16.1, “Autotools”.

Let’s package this in the same way as Section 8.9, “Autotools (single-binary)”.

Let’s assume this upstream tarball to be debhello-2.0.tar.gz.

This type of source is meant to be installed as a non-system file, for example, as:

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

Let’s get the source and make the Debian package.

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
│   ├── Makefile.am
│   ├── 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

5 directories, 12 files

Here, the contents of this source are as follows.

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 and 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

Let’s package this with the debmake command into multiple packages:

  • debhello: type = bin
  • libsharedlib1: type = lib
  • libsharedlib-dev: type = dev
  • debhello-dbg: type = dbg
  • libsharedlib1-dbg: type = dbg

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

 $ cd debhello-2.0
 $ debmake -b',libsharedlib1,libsharedlib-dev,-dbg,libsharedlib1-dbg'
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,-dbg,libsha...
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: binary package=debhello-dbg Type=dbg / Arch=any M-A=same
I: binary package=libsharedlib1-dbg Type=dbg / Arch=any M-A=same
...

The result is similar to Section 8.8, “Makefile.in + configure (single-binary)” but with more template files.

Let’s inspect notable template files generated.

debian/rules (template file, v=2.0): 

 $ cat debhello-2.0/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,--as-needed

%:
        dh $@ --with autoreconf

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

override_dh_strip:
        dh_strip -Xlibsharedlib1 --dbg-package=debhello-dbg
        dh_strip -Xdebhello --dbg-package=libsharedlib1-dbg

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=2.0): 

 $ vim debhello-2.0/debian/rules
 ... hack, hack, hack, ...
 $ cat debhello-2.0/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_install:
        dh_install --list-missing -X.la

override_dh_strip:
        dh_strip -Xlibsharedlib1 --dbg-package=debhello-dbg
        dh_strip -Xdebhello --dbg-package=libsharedlib1-dbg

debian/control (maintainer version, v=2.0): 

 $ vim debhello-2.0/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-2.0/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: debhelper (>=9), dh-autoreconf
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: libsharedlib1 (= ${binary:Version}),
         ${misc:Depends},
         ${shlibs:Depends}
Description: example executable package
 This is an example package to demonstrate the 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)'.
 .
 This package provides the executable program.

Package: libsharedlib1
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: example shared library package
 This is an example package to demonstrate the 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)'.
 .
 This package contains the shared library.

Package: libsharedlib-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}
Description: example development package
 This is an example package to demonstrate the 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)'.
 .
 This package contains the development files.

Package: debhello-dbg
Section: debug
Architecture: any
Multi-Arch: same
Depends: debhello (= ${binary:Version}), ${misc:Depends}
Description: example debugging package for debhello
 This is an example package to demonstrate the 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)'.
 .
 This package contains the debugging symbols for debhello.

Package: libsharedlib1-dbg
Section: debug
Architecture: any
Multi-Arch: same
Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}
Description: example debugging package for libsharedlib1
 This is an example package to demonstrate the 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)'.
 .
 This package contains the debugging symbols for libsharedlib1.

debian/*.install (maintainer version, v=2.0): 

 $ vim debhello-2.0/debian/debhello.install
 ... hack, hack, hack, ...
 $ cat debhello-2.0/debian/debhello.install
usr/bin/*
usr/share/man/*
 $ vim debhello-2.0/debian/libsharedlib1.install
 ... hack, hack, hack, ...
 $ cat debhello-2.0/debian/libsharedlib1.install
usr/lib/*/*.so.*
 $ vim debhello-2.0/debian/libsharedlib-dev.install
 ... hack, hack, hack, ...
 $ cat debhello-2.0/debian/libsharedlib-dev.install
###usr/lib/*/pkgconfig/*.pc
usr/include
usr/lib/*/*.so

Since this upstream source creates the proper auto-generated Makefile, there are no needs to create debian/install and debian/manpages files.

There are several other template files under the debian/ directory. These also need to be updated.

Template files under debian/. (v=2.0): 

 $ tree debhello-2.0/debian
debhello-2.0/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── debhello.install
├── libsharedlib-dev.install
├── libsharedlib1.install
├── libsharedlib1.symbols
├── patches
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 14 files

The rest of the packaging activities are practically the same as the one in Section 8.8, “Makefile.in + configure (single-binary)”.

Here are the generated dependency lists of binary packages.

The generated dependency lists of binary packages (v=2.0): 

 $ dpkg -f debhello-dbg_2.0-1_amd64.deb pre-depends depends recommends confli...
Depends: debhello (= 2.0-1)
 $ dpkg -f debhello_2.0-1_amd64.deb pre-depends depends recommends conflicts ...
Depends: libsharedlib1 (= 2.0-1), libc6 (>= 2.2.5)
 $ dpkg -f libsharedlib-dev_2.0-1_amd64.deb pre-depends depends recommends co...
Depends: libsharedlib1 (= 2.0-1)
 $ dpkg -f libsharedlib1-dbg_2.0-1_amd64.deb pre-depends depends recommends c...
Depends: libsharedlib1 (= 2.0-1)
 $ dpkg -f libsharedlib1_2.0-1_amd64.deb pre-depends depends recommends confl...
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 using the CMake (CMakeLists.txt and some files such as config.h.in) as its build system. See Section 5.16.2, “CMake”.

Let’s assume this upstream tarball to be debhello-2.1.tar.gz.

This type of source is meant to be installed as a non-system file, for example, as:

 $ 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

Let’s get the source and make the Debian package.

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
│   ├── 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

5 directories, 12 files

Here, the contents of this source are as follows.

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 and 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
)

Let’s package this with the debmake command.

 $ cd debhello-2.1
 $ debmake -b',libsharedlib1,libsharedlib-dev,-dbg,libsharedlib1-dbg'
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,-dbg,libsha...
I: binary package=debhello Type=bin / Arch=any M-A=foreign
...

The result is similar to Section 8.8, “Makefile.in + configure (single-binary)” but not exactly the same.

Let’s inspect notable template files generated.

debian/rules (template file, v=2.1): 

 $ cat debhello-2.1/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,--as-needed

%:
        dh $@

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

override_dh_strip:
        dh_strip -Xlibsharedlib1 --dbg-package=debhello-dbg
        dh_strip -Xdebhello --dbg-package=libsharedlib1-dbg

Let’s make this Debian package better as the maintainer.

debian/rules (maintainer version, v=2.1): 

 $ vim debhello-2.1/debian/rules
 ... hack, hack, hack, ...
 $ cat debhello-2.1/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)"

override_dh_install:
        dh_install --list-missing

override_dh_strip:
        dh_strip -Xlibsharedlib1 --dbg-package=debhello-dbg
        dh_strip -Xdebhello --dbg-package=libsharedlib1-dbg

debian/control (maintainer version, v=2.1): 

 $ vim debhello-2.1/debian/control
 ... hack, hack, hack, ...
 $ cat debhello-2.1/debian/control
Source: debhello
Section: devel
Priority: extra
Maintainer: Osamu Aoki <osamu@debian.org>
Build-Depends: cmake, debhelper (>=9)
Standards-Version: 3.9.6
Homepage: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends: libsharedlib1 (= ${binary:Version}),
         ${misc:Depends},
         ${shlibs:Depends}
Description: example executable package
 This is an example package to demonstrate the 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)'.
 .
 This package provides the executable program.

Package: libsharedlib1
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: example shared library package
 This is an example package to demonstrate the 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)'.
 .
 This package contains the shared library.

Package: libsharedlib-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}
Description: example development package
 This is an example package to demonstrate the 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)'.
 .
 This package contains the development files.

Package: debhello-dbg
Section: debug
Architecture: any
Multi-Arch: same
Depends: debhello (= ${binary:Version}), ${misc:Depends}
Description: example debugging package for debhello
 This is an example package to demonstrate the 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)'.
 .
 This package contains the debugging symbols for debhello.

Package: libsharedlib1-dbg
Section: debug
Architecture: any
Multi-Arch: same
Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}
Description: example debugging package for libsharedlib1
 This is an example package to demonstrate the 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)'.
 .
 This package contains the debugging symbols for libsharedlib1.

debian/*.install (maintainer version, v=2.1): 

 $ vim debhello-2.1/debian/debhello.install
 ... hack, hack, hack, ...
 $ cat debhello-2.1/debian/debhello.install
usr/bin/*
usr/share/man/*
 $ vim debhello-2.1/debian/libsharedlib1.install
 ... hack, hack, hack, ...
 $ cat debhello-2.1/debian/libsharedlib1.install
usr/lib/*/*.so.*
 $ vim debhello-2.1/debian/libsharedlib-dev.install
 ... hack, hack, hack, ...
 $ cat debhello-2.1/debian/libsharedlib-dev.install
###usr/lib/*/pkgconfig/*.pc
usr/include
usr/lib/*/*.so

This upstream CMakeList.txt needs to be patched to cope with the multiarch path.

debian/patches/* (maintainer version, v=2.1): 

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

Since this upstream source creates the proper auto-generated Makefile, there are no needs to create debian/install and debian/manpages files.

There are several other template files under the debian/ directory. These also need to be updated.

Template files under debian/. (v=2.1): 

 $ tree debhello-2.1/debian
debhello-2.1/debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── debhello.install
├── libsharedlib-dev.install
├── libsharedlib1.install
├── libsharedlib1.symbols
├── patches
│   ├── 000-cmake-multiarch.patch
│   └── series
├── rules
├── source
│   ├── format
│   └── local-options
└── watch

2 directories, 15 files

The rest of the packaging activities are practically the same as the one in Section 8.8, “Makefile.in + configure (single-binary)”.

Here are the generated dependency lists of binary packages.

The generated dependency lists of binary packages (v=2.1): 

 $ dpkg -f debhello-dbg_2.1-1_amd64.deb pre-depends depends recommends confli...
Depends: debhello (= 2.1-1)
 $ dpkg -f debhello_2.1-1_amd64.deb pre-depends depends recommends conflicts ...
Depends: libsharedlib1 (= 2.1-1), libc6 (>= 2.2.5)
 $ dpkg -f libsharedlib-dev_2.1-1_amd64.deb pre-depends depends recommends co...
Depends: libsharedlib1 (= 2.1-1)
 $ dpkg -f libsharedlib1-dbg_2.1-1_amd64.deb pre-depends depends recommends c...
Depends: libsharedlib1 (= 2.1-1)
 $ dpkg -f libsharedlib1_2.1-1_amd64.deb pre-depends depends recommends confl...
Depends: libc6 (>= 2.2.5)

Here is an example of updating the simple upstream C source debhello-2.0.tar.gz presented in Section 8.11, “Autotools (multi-binary)” for the internationalization (i18n) and creating the updated upstream C source debhello-2.0.tar.gz.

In the real situation, the package should be already internationalized. So this example is educational for you to understand how this internationalization is implemented.

[Tip] Tip

The routine maintainer activity for the i18n is simply to add translation po files reported to you via BTS system to the po/ directory and to update the language list in the po/LINGUAS.

Let’s get the source and make the Debian package.

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
│   ├── Makefile.am
│   ├── 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

5 directories, 12 files

Internationalize this source tree with the gettextize command and remove files auto-generated by the Autotools.

run gettextize (i18n): 

 $ cd 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 *~

Let’s check generated files under the po/ directory.

files in po (i18n): 

 $ ls -l po
/build/debmake-doc-1.9/debhello-2.0-pkg2/step151.cmd: line 2: SOURCE_DATE_EPO...
total 60
-rw-r--r-- 1 pbuilder pbuilder   494 Mar 27 13:34 ChangeLog
-rw-r--r-- 1 pbuilder pbuilder 17577 Mar 27 13:34 Makefile.in.in
-rw-r--r-- 1 pbuilder pbuilder  3376 Mar 27 13:34 Makevars.template
-rw-r--r-- 1 pbuilder pbuilder    59 Mar 27 13:34 POTFILES.in
-rw-r--r-- 1 pbuilder pbuilder  2203 Mar 27 13:34 Rules-quot
-rw-r--r-- 1 pbuilder pbuilder   217 Mar 27 13:34 boldquot.sed
-rw-r--r-- 1 pbuilder pbuilder  1337 Mar 27 13:34 en@boldquot.header
-rw-r--r-- 1 pbuilder pbuilder  1203 Mar 27 13:34 en@quot.header
-rw-r--r-- 1 pbuilder pbuilder   672 Mar 27 13:34 insert-header.sin
-rw-r--r-- 1 pbuilder pbuilder   153 Mar 27 13:34 quot.sed
-rw-r--r-- 1 pbuilder pbuilder   432 Mar 27 13:34 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

Let’s create the po/Makevars from the po/Makevars.template.

po/Makevars (i18n): 

 ... hack, hack, hack, ...
 $ diff -u po/Makevars.template po/Makevars
--- po/Makevars.template        2017-09-17 08:40:22.686980438 +0000
+++ po/Makevars 2017-09-17 08:40:25.994904688 +0000
@@ -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 by wrapping strings with _(…).

src/hello.c (i18n): 

 ... hack, hack, hack, ...
 $ cat src/hello.c
#include "config.h"
#include <stdio.h>
#include <sharedlib.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>
#define _(string) gettext (string)
int
sharedlib()
{
        printf(_("This is a shared library!\n"));
        return 0;
}

The new gettext (v=0.19) can handle the i18n of the desktop file directly.

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;

Let’s list the input files to extract translatable strings in po/POTFILES.in.

po/POTFILES.in (i18n): 

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

Here is the updated root Makefile.am with po added to the 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

Let’s make a translation template file 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: 2017-09-17 08:40+0000\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:8
#, c-format
msgid "Hello, I am "
msgstr ""

#: lib/sharedlib.c:6
#, 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 ""

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

Let’s add Japanese translation.

po/LINGUAS and 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, I am %s!\n"
msgstr "Bonjour, je suis %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 ""

The packaging activities are practically the same as the one in Section 8.11, “Autotools (multi-binary)”.

You can find more i18n examples in Section 8.14, “Details” for

  • the POSIX shell script with the Makefile (v=3.0),
  • the Python3 script with the distutils (v=3.1),
  • the C source with the Makefile.in + configure (v=3.2),
  • the C source with the Autotools (v=3.3), and
  • the C source with the CMake (v=3.4).

Actual details of the examples presented and their variants can be obtained by the following.

How to get details. 

 $ apt-get source debmake-doc
 $ sudo apt-get install devscripts build-essentials
 $ sudo apt-get build-dep debmake-doc
 $ cd debmake-doc*
 $ make

Each directory with the -pkg[0-9] suffix contains the Debian packaging example.

  • emulated console command line activity log: the .log file
  • emulated console command line activity log (short): the .slog file
  • snapshot source tree image after the debmake command: the debmake directory
  • snapshot source tree image after the proper packaging: the packge directory
  • snapshot source tree image after the debuild command: the test directory