Chapter 4. Simple Example

Table of Contents

4.1. Big picture
4.2. What is debmake?
4.3. What is debuild?
4.4. Step 1: Get the upstream source
4.5. Step 2: Generate template files with debmake
4.6. Step 3: Modification to the template files
4.7. Step 4: Building package with debuild
4.8. Step 3 (alternative): Modification to the upstream source
4.8.1. Patch by diff -u
4.8.2. Patch by dquilt
4.8.3. Patch by dpkg-source --commit

There is an old Latin saying: “Longum iter est per praecepta, breve et efficax per exempla” (“It’s a long way by the rules, but short and efficient with examples”).

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

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

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

 $ tar -xzmf debhello-0.0.tar.gz
 $ cd debhello-0.0
 $ make
 $ 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.

Note

Examples of creating a Debian package from other complicated build systems are described in Chapter 8, More Examples.

The big picture for building a single non-native Debian package from the upstream tarball debhello-0.0.tar.gz can be summarized as:

  • The maintainer obtains the upstream tarball debhello-0.0.tar.gz and untars its contents to the debhello-0.0 directory.
  • The debmake command debianizes the upstream source tree by adding template files only in the debian directory.

    • The debhello_0.0.orig.tar.gz symlink is created pointing to the debhello-0.0.tar.gz file.
    • The maintainer customizes template files.
  • The debuild command builds the binary package from the debianized source tree.

    • debhello-0.0-1.debian.tar.xz is created containing the debian directory.

Big picture of package building. 

 $ tar -xzmf debhello-0.0.tar.gz
 $ cd debhello-0.0
 $ debmake
   ... manual customization
 $ debuild
   ...

Tip

The debuild command in this and following examples may be substituted by equivalent commands such as the pdebuild command.

Tip

If the upstream tarball in the .tar.xz format is available, use it instead of the one in the .tar.gz and .tar.bz2 formats. The xz compression format offers the better compression than the gzip and bzip2 compressions.

The debmake command is the helper script for the Debian packaging.

  • It always sets most of the obvious option states and values to reasonable defaults.
  • It generates the upstream tarball and its required symlink if they are missing.
  • It doesn’t overwrite the existing configuration files in the debian/ directory.
  • It supports the multiarch package.
  • It creates good template files such as the debian/copyright file compliant with DEP-5.

These features make Debian packaging with debmake simple and modern.

Note

The debmake command isn’t the only way to make a Debian package. Many packages are packaged using only a text editor while imitating how other similar packages are packaged.

Here is a summary of commands similar to the debuild command.

Note

See dpkg-buildpackage(1) for exact details.

Let’s get the upstream source.

Download debhello-0.0.tar.gz

 $ wget http://www.example.org/download/debhello-0.0.tar.gz
 ...
 $ tar -xzf debhello-0.0.tar.gz
 $ tree
/home/ned/deb_holgerw/fremdpakete/debmake-doc/on-salsa/debmake-doc/bin/L: lin...

Here, the C source hello.c is a very simple one.

hello.c

        

Here, the Makefile supports GNU Coding Standards and FHS. Notably:

  • build binaries honoring $(CPPFLAGS), $(CFLAGS), $(LDFLAGS), etc.
  • install files with $(DESTDIR) defined to the target system image
  • install files with $(prefix) defined, which can be overridden to be /usr

Makefile

        

Note

The echo of the $(CFLAGS) variable is used to verify the proper setting of the build flag in the following example.

Tip

If the debmake command is invoked with the -T option, more verbose comments are generated for the template files.

The output from the debmake command is very verbose and explains what it does as follows.

        

The debmake command generates all these template files based on command line options. Since no options are specified, the debmake command chooses reasonable default values for you:

  • The source package name: debhello
  • The upstream version: 0.0
  • The binary package name: debhello
  • The Debian revision: 1
  • The package type: bin (the ELF binary executable package)
  • The -x option: -x1 (default for the single binary package)

Let’s inspect generated template files.

The source tree after the basic debmake execution. 

        

The debian/rules file is the build script provided by the package maintainer. Here is its template file generated by the debmake command.

debian/rules (template file): 

        

This is essentially the standard debian/rules file with the dh command. (There are some commented out contents for you to customize it.)

The debian/control file provides the main meta data for the Debian package. Here is its template file generated by the debmake command.

debian/control (template file): 

        

Warning

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

Since this is the ELF binary executable package, the debmake command sets “Architecture: any” and “Multi-Arch: foreign”. Also, it sets required substvar parameters as “Depends: ${shlibs:Depends}, ${misc:Depends}”. These are explained in Chapter 5, Basics.

Note

Please note this debian/control file uses the RFC-822 style as documented in 5.2 Source package control files — debian/control of the “Debian Policy Manual”. The use of the empty line and the leading space are significant.

The debian/copyright file provides the copyright summary data of the Debian package. Here is its template file generated by the debmake command.

debian/copyright (template file): 

        

Some manual modification is required to make the proper Debian package as a maintainer.

In order to install files as a part of the system files, the $(prefix) value of /usr/local in the Makefile should be overridden to be /usr. This can be accommodated by the following the debian/rules file with the override_dh_auto_install target setting “prefix=/usr”.

debian/rules (maintainer version): 

        

Exporting the DH_VERBOSE environment variable in the debian/rules file as above forces the debhelper tool to make a fine grained build report.

Exporting DEB_BUILD_MAINT_OPTION as above sets the hardening options as described in the “FEATURE AREAS/ENVIRONMENT” in dpkg-buildflags(1). [8]

Exporting DEB_CFLAGS_MAINT_APPEND as above forces the C compiler to emit all the warnings.

Exporting DEB_LDFLAGS_MAINT_APPEND as above forces the linker to link only when the library is actually needed. [9]

The dh_auto_install command for the Makefile based build system essentially runs “$(MAKE) install DESTDIR=debian/debhello”. The creation of this override_dh_auto_install target changes its behavior to “$(MAKE) install DESTDIR=debian/debhello prefix=/usr”.

Here are the maintainer versions of the debian/control and debian/copyright files.

debian/control (maintainer version): 

        

debian/copyright (maintainer version): 

        

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

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

        

Tip

Configuration files used by the dh_* commands from the debhelper package usually treat # as the start of a comment line.

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

 ...

 ...

 ...

 ...

 ...

 ...

You can verify that CFLAGS is updated properly with -Wall and -pedantic by the DEB_CFLAGS_MAINT_APPEND variable.

The manpage should be added to the package as reported by the lintian package, as shown in later examples (see Chapter 8, More Examples). Let’s move on for now.

Let’s inspect the result.

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

        

You see all the generated files.

  • The debhello_0.0.orig.tar.gz is a symlink to the upstream tarball.
  • The debhello_0.0-1.debian.tar.xz contains the maintainer generated contents.
  • The debhello_0.0-1.dsc is the meta data file for the Debian source package.
  • The debhello_0.0-1_amd64.deb is the Debian binary package.
  • The debhello-dbgsym_0.0-1_amd64.deb is the Debian debug symbol binary package. See Section 5.17.1, “New -dbgsym package (Stretch 9.0 and after)”.
  • The debhello_0.0-1_amd64.build file is the build log file.
  • The debhello_0.0-1_amd64.buildinfo file is the meta data file generated by dpkg-genbuildinfo(1).
  • The debhello_0.0-1_amd64.changes is the meta data file for the Debian binary package.

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

The compressed archive contents of debhello_0.0-1.debian.tar.xz

        

The debhello_0.0-1_amd64.deb contains the binary files to be installed to the target system.

The debhello-debsym_0.0-1_amd64.deb contains the debug symbol files to be installed to the target system..

The binary package contents of all binary packages: 

        

The generated dependency list of all binary packages.

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

        

Caution

Many more details need to be addressed before uploading the package to the Debian archive.

Note

If manual adjustments of auto-generated configuration files by the debmake command are skipped, the generated binary package may lack meaningful package description and some of the policy requirements may be missed. This sloppy package functions well under the dpkg command, and may be good enough for your local deployment.

The above example did not touch the upstream source to make the proper Debian package.

An alternative approach as the maintainer is to change the upstream source by modifying the upstream Makefile to set the $(prefix) value to /usr.

The packaging is practically the same as the above step-by-step example except for two points in Section 4.6, “Step 3: Modification to the template files”:

This alternative approach to Debian packaging using a series of patch files may be less robust for future upstream changes but more flexible coping with the difficult upstream source. (See Section 7.13, “3.0 source format”.)

Note

For this particular packaging case, the above Section 4.6, “Step 3: Modification to the template files” using the debian/rules file is the better approach. But let’s keep on with this approach as a leaning process.

Here is an example to create 000-prefix-usr.patch by the dquilt command which is a simple wrapper of the quilt program. The syntax and function of the dquilt command is the same as the quilt(1) command, except for the fact that the patch is stored in the debian/patches/ directory.

          

Here, Makefile in the upstream source tree doesn’t need to be restored to the original state. The dpkg-source command invoked by the Debian packaging procedure in Section 4.7, “Step 4: Building package with debuild”, understands the patch application state recorded by the dquilt program in the .pc/ directory. As long as all the changes are committed by the dquilt command, the Debian source package can be built from the modified source tree.

Note

If the .pc/ directory is missing, the dpkg-source command assumes that no patch was applied. That’s why the more primitive patch generation methods like in Section 4.8.1, “Patch by diff -u” without generating the .pc/ directory require the upstream source tree to be restored.



[8] This is a cliché to force a read-only relocation link for the hardening and to prevent the lintian warning “W: debhello: hardening-no-relro usr/bin/hello”. This is not really needed for this example but should be harmless. The lintian tool seems to produce a false positive warning for this case which has no linked library.

[9] This is a cliché to prevent overlinking for the complex library dependency case such as Gnome programs. This is not really needed for this simple example but should be harmless.