Table of Contents
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 to change 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 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:
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 the equivalent commands such as the pdebuild command. |
The debmake command is the helper script for the Debian packaging.
These features make Debian packaging with debmake simple and modern.
Here is a summary of commands similar to the debuild command.
Let’s get the source.
Download debhello-0.0.tar.gz.
Script started on Tue Apr 26 23:05:15 2016 $ wget http://www.example.org/download/debhello-0.0.tar.gz ... $ tar -xzmf debhello-0.0.tar.gz $ tree . ├── debhello-0.0 │ ├── LICENSE │ ├── Makefile │ └── src │ └── hello.c └── debhello-0.0.tar.gz 2 directories, 4 files
Here, the C source hello.c is a very simple one.
hello.c.
Script started on Tue Apr 26 23:05:15 2016 $ cat debhello-0.0/src/hello.c #include <stdio.h> int main() { printf("Hello, world!\n"); return 0; }
Here, the Makefile supports GNU Coding Standards and FHS. Notably:
Makefile.
Script started on Tue Apr 26 23:05:15 2016 $ cat debhello-0.0/Makefile prefix = /usr/local all: src/hello src/hello: src/hello.c @echo "CFLAGS=$(CFLAGS)" | \ fold -s -w 70 | \ sed -e 's/^/# /' $(CC) $(CPPFLAGS) $(CFLAGS) $(LDCFLAGS) -o $@ $^ install: src/hello install -D src/hello \ $(DESTDIR)$(prefix)/bin/hello clean: -rm -f src/hello distclean: clean uninstall: -rm -f $(DESTDIR)$(prefix)/bin/hello .PHONY: all install clean distclean uninstall
![]() |
Note |
---|---|
The echo of the $(CFLAGS) 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.
Script started on Tue Apr 26 23:05:15 2016 $ cd debhello-0.0 $ debmake I: set parameters I: sanity check of parameters I: pkg="debhello", ver="0.0", rev="1" I: *** start packaging in "debhello-0.0". *** I: provide debhello_0.0.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-0.0.tar.gz debhello_0.0.orig.tar.gz I: pwd = "/path/to/debhello-0.0" I: parse binary package settings: I: binary package=debhello Type=bin / Arch=any M-A=foreign I: analyze the source tree I: build_type = make I: scan source for copyright+license text and file extensions I: 100 %, ext = c I: check_all_licenses I: .. I: check_all_licenses completed for 2 files. I: bunch_all_licenses I: format_all_licenses I: make debian/* template files I: single binary package I: debmake -x "1" ... I: creating => debian/control I: creating => debian/copyright I: substituting => /usr/share/debmake/extra0/changelog I: creating => debian/changelog I: substituting => /usr/share/debmake/extra0/rules I: creating => debian/rules I: substituting => /usr/share/debmake/extra1/README.Debian I: creating => debian/README.Debian I: substituting => /usr/share/debmake/extra1/compat I: creating => debian/compat I: substituting => /usr/share/debmake/extra1/watch I: creating => debian/watch I: substituting => /usr/share/debmake/extra1source/local-options I: creating => debian/source/local-options I: substituting => /usr/share/debmake/extra1source/format I: creating => debian/source/format I: substituting => /usr/share/debmake/extra1patches/series I: creating => debian/patches/series I: run "debmake -x2" to get more template files I: $ wrap-and-sort
The debmake command generates all these template files based on the command line option. Since no options are specified, the debmake command choses reasonable default values for you:
Let’s inspect generated template files.
The source tree after the basic debmake execution.
Script started on Tue Apr 26 23:05:15 2016 $ cd .. $ tree . ├── debhello-0.0 │ ├── LICENSE │ ├── Makefile │ ├── debian │ │ ├── README.Debian │ │ ├── changelog │ │ ├── compat │ │ ├── control │ │ ├── copyright │ │ ├── patches │ │ │ └── series │ │ ├── rules │ │ ├── source │ │ │ ├── format │ │ │ └── local-options │ │ └── watch │ └── src │ └── hello.c ├── debhello-0.0.tar.gz └── debhello_0.0.orig.tar.gz -> debhello-0.0.tar.gz 5 directories, 15 files
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):
Script started on Tue Apr 26 23:05:15 2016 $ cat debhello-0.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 $@ #override_dh_auto_install: # dh_auto_install -- prefix=/usr #override_dh_install: # dh_install --list-missing -X.pyc -X.pyo
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):
Script started on Tue Apr 26 23:05:15 2016 $ cat debhello-0.0/debian/control Source: debhello Section: unknown Priority: extra Maintainer: "Firstname Lastname" <email.address@example.org> Build-Depends: debhelper (>=9) Standards-Version: 3.9.6 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.
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):
Script started on Tue Apr 26 23:05:15 2016 $ cat debhello-0.0/debian/copyright Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: debhello Source: <url://example.com> Files: Makefile src/hello.c Copyright: __NO_COPYRIGHT_NOR_LICENSE__ License: __UNKNOWN__ #----------------------------------------------------------------------------... # Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following # license/copyright files. #----------------------------------------------------------------------------... # License file: LICENSE License: . All files in this archive are licensed under the MIT License as below. . Copyright 2015 Osamu Aoki <osamu@debian.org> . Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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):
Script started on Tue Apr 26 23:05:15 2016 $ vim debhello-0.0/debian/rules ... hack, hack, hack, ... $ cat debhello-0.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 $@ override_dh_auto_install: dh_auto_install -- prefix=/usr
Exporting the DH_VERBOSE in the debian/rules file as above forces the debhelper tool to make a fine grained build report.
Exporting the DEB_BUILD_MAINT_OPTION as above sets the hardening options as described in the “FEATURE AREAS/ENVIRONMENT” in dpkg-buildflags(1). [9]
Exporting the DEB_CFLAGS_MAINT_APPEND as above forces C compiler to emit all the warnings.
Exporting the DEB_LDFLAGS_MAINT_APPEND as above forces linker to link only when the library is actually needed. [10]
The dh_auto_install command for the Makefile based build system does essentially “$(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 version of the debian/control and debian/copyright files.
debian/control (maintainer version):
Script started on Tue Apr 26 23:05:15 2016 $ vim debhello-0.0/debian/control ... hack, hack, hack, ... $ cat debhello-0.0/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: 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)'.
debian/copyright (maintainer version):
Script started on Tue Apr 26 23:05:15 2016 $ vim debhello-0.0/debian/copyright ... hack, hack, hack, ... $ cat debhello-0.0/debian/copyright Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: debhello Source: http://anonscm.debian.org/cgit/collab-maint/debmake-doc.git/tree/base... Files: * Copyright: 2015 Osamu Aoki <osamu@debian.org> License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
There are several other template files under the debian/ directory. These also needs to be updated.
Template files under debian/. (v=0.0):
Script started on Tue Apr 26 23:05:15 2016 $ tree debhello-0.0/debian debhello-0.0/debian ├── README.Debian ├── changelog ├── compat ├── control ├── copyright ├── patches │ └── series ├── rules ├── source │ ├── format │ └── local-options └── watch 2 directories, 10 files
![]() |
Tip |
---|---|
Configuration files used by the dh_* commands from the debhelper package usually treat # as the start of the comment line. |
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.
Script started on Tue Apr 26 23:05:15 2016 $ cd debhello-0.0 $ debuild ... fakeroot debian/rules clean dh clean ... debian/rules build dh build dh_testdir dh_update_autotools_config dh_auto_configure dh_auto_build make -j1 make[1]: Entering directory '/path/to/debhello-0.0' # CFLAGS=-g -O2 -fstack-protector-strong -Wformat # -Werror=format-security cc -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -... ... fakeroot debian/rules binary dh binary ... ... ... dpkg-buildpackage: full upload (original source is included)
You can verify 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 the 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:
Script started on Tue Apr 26 23:05:21 2016 $ cd .. $ tree -FL 1 . ├── debhello-0.0/ ├── debhello-0.0.tar.gz ├── debhello-dbgsym_0.0-1_amd64.ddeb ├── debhello_0.0-1.debian.tar.xz ├── debhello_0.0-1.dsc ├── debhello_0.0-1_amd64.build ├── debhello_0.0-1_amd64.changes ├── debhello_0.0-1_amd64.deb └── debhello_0.0.orig.tar.gz -> debhello-0.0.tar.gz 1 directory, 8 files
You see all the generated files.
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:
Script started on Tue Apr 26 23:05:21 2016 $ tar -tzf debhello-0.0.tar.gz debhello-0.0/ debhello-0.0/Makefile debhello-0.0/src/ debhello-0.0/src/hello.c debhello-0.0/LICENSE $ tar --xz -tf debhello_0.0-1.debian.tar.xz debian/ debian/README.Debian debian/control debian/compat debian/patches/ debian/patches/series debian/copyright debian/source/ debian/source/format debian/watch debian/changelog debian/rules
The debhello_0.0-1_amd64.deb contains the files to be installed as follows.
The binary package contents of debhello_0.0-1_amd64.deb:
Script started on Tue Apr 26 23:05:21 2016 $ dpkg -c debhello_0.0-1_amd64.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/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/copyright -rw-r--r-- root/root ... ./usr/share/doc/debhello/changelog.Debian.gz
The generated dependency of debhello_0.0-1_amd64.deb is as follows.
The generated dependency of debhello_0.0-1_amd64.deb:
Script started on Tue Apr 26 23:05:21 2016 $ dpkg -f debhello_0.0-1_amd64.deb pre-depends depends recommends conflics b... Depends: libc6 (>= 2.2.5)
![]() |
Caution |
---|---|
Much more details need to be addressed before uploading the package to the Debian archive. |
![]() |
Note |
---|---|
If manual adjustments of auto-generated configuration files 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 step-by-step example did not touch the upstream source to make the proper Debian package.
An alternative approach is to change the upstream source by creating the patch 000-prefix-usr.patch which modifies the upstream Makefile to set the $(prefix) value to /usr in advance.
create 000-prefix-usr.patch by the diff command:
Script started on Tue Apr 26 23:05:21 2016 $ cp -a debhello-0.0 debhello-0.0.orig $ vim debhello-0.0/Makefile ... hack, hack, hack, ... $ diff -Nru debhello-0.0.orig debhello-0.0 >000-prefix-usr.patch $ cat 000-prefix-usr.patch diff -Nru debhello-0.0.orig/Makefile debhello-0.0/Makefile --- debhello-0.0.orig/Makefile 2016-04-26 23:05:21.194810999 +0000 +++ debhello-0.0/Makefile 2016-04-26 23:05:21.278810999 +0000 @@ -1,4 +1,4 @@ -prefix = /usr/local +prefix = /usr all: src/hello $ rm -rf debhello-0.0 $ mv -f debhello-0.0.orig debhello-0.0
Please note that the upstream source tree is restored to the original state.
The packaging is practically the same as the above step-by-step example except for 2 points of the maintainer modification.
The maintainer modification to the debian/rules file doesn’t have the override_dh_auto_install target as follows:
debian/rules (alternative maintainer version):
Script started on Tue Apr 26 23:05:21 2016 $ vim debhello-0.0/debian/rules ... hack, hack, hack, ... $ cat debhello-0.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 $@
The maintainer modification to the upstream source during the package building process is enabled by adding the corresponding patch file in the debian/patches/ directory and listing its file names in the debian/patches/series file.
Set of files to modify the upstream Makefile:
Script started on Tue Apr 26 23:05:22 2016 $ echo '000-prefix-usr.patch' >debhello-0.0/debian/patches/series $ vim 000-prefix-usr.patch ... hack, hack, hack, ... $ mv -f 000-prefix-usr.patch debhello-0.0/debian/patches/000-prefix-usr.patc... $ cat debhello-0.0/debian/patches/000-prefix-usr.patch From: Osamu Aoki <osamu@debian.org> Description: set prefix=/usr patch diff -Nru debhello-0.0.orig/Makefile debhello-0.0/Makefile --- debhello-0.0.orig/Makefile +++ debhello-0.0/Makefile @@ -1,4 +1,4 @@ -prefix = /usr/local +prefix = /usr all: src/hello
The rest of the packaging is the same as the step-by-step example.
As indicated in Section 5.12.3, “patches/* approach”, there are several tools other than the diff command which generate patch files used for this alternative approach of packaging. Most frequently used ones are the dquilt or gbp-pq commands.
There is no need to create the patch file in advance for these commands since it can be generated as you make the maintainer modification. Here is an example for the dquilt command.
patch file generation using the dquilt command:
Script started on Tue Apr 26 23:05:28 2016 $ cd debhello-0.0 $ dquilt new 000-prefix-usr.patch Patch debian/patches/000-prefix-usr.patch is now on top $ dquilt add Makefile File Makefile added to patch debian/patches/000-prefix-usr.patch ... hack, hack, hack, ... $ head -1 Makefile prefix = /usr $ dquilt refresh Refreshed patch debian/patches/000-prefix-usr.patch $ dquilt header -e --dep3 ... hack, hack, hack, ... Replaced header of patch 000-prefix-usr.patch $ dquilt pop -a Removing patch debian/patches/000-prefix-usr.patch Restoring Makefile No patches applied $ cat debian/patches/series 000-prefix-usr.patch $ cat debian/patches/000-prefix-usr.patch Description: set prefix=/usr patch Author: Osamu Aoki <osamu@debian.org> Index: debhello-0.0/Makefile =================================================================== --- debhello-0.0.orig/Makefile +++ debhello-0.0/Makefile @@ -1,4 +1,4 @@ -prefix = /usr/local +prefix = /usr all: src/hello $ cd ..
![]() |
Tip |
---|---|
If the package is maintained in the git repository using the gbp command, please use the gbp-pq command to manage patches. |
This alternative approach to the Debian packaging using a series of patch files may be less robust for the future upstream changes but more flexible to cope with the difficult upstream source. (See Section 7.15, “3.0 source format”.)
[9] This is a cliché to force 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 seems to produce false positive warning for this case which has no linked library.
[10] 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.