Build Debian Packages

Guide for Debian Maintainers

4. Simple Example

4.1. Packaging tarball

Let’s assume this upstream tarball to be debhello-0.0.tar.gz.
This type of source can be installed :

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

Chapter 8 has "More Examples".

4.2. Big picture

  • The maintainer obtains the upstream tarball debhello-0.0.tar.gz and untars its contents to the debhello-0.0 directory.
  • 
    $ tar -xzmf debhello-0.0.tar.gz        
            
  • The debmake command debianizes the upstream source tree by adding template files only in the debian directory.
  • 
    $ cd debhello-0.0
    $ debmake        
            
    Then, the maintainer customizes template files.
  • The debuild command builds the binary package from the debianized source tree.
  • 
    $ debuild        
            

4.3. What is debmake?

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.

4.4. What is debuild?

  • The debian/rules file defines how the Debian binary package is built.
  • The debuild command is a wrapper script of the dpkg-buildpackage command to build the Debian binary package under the proper environment variables.
The dpkg-buildpackage command is the official command to build the Debian binary package. For normal binary build, it executes roughly:
  • dpkg-source --before-build”
  • Apply Debian patches, unless they are already applied.
  • fakeroot debian/rules clean”
  • dpkg-source --build”
  • Build the Debian source package.
  • fakeroot debian/rules build”
  • fakeroot debian/rules binary”
  • dpkg-genbuildinfo
  • Generate a *.buildinfo file.
  • dpkg-genchanges
  • Generate a *.changes file.
  • fakeroot debian/rules clean”
  • dpkg-source --after-build”
  • Unapply Debian patches, if they are applied during --before-build.
  • debsign
  • Sign the *.dsc and *.changes files.
    Using the -us and -uc options can skip this step , you can run the debsign command manually.

4.5. Step 1: Get the upstream source


$ wget https://github.com/JerryLeeTaipei/examples/blob/master/debhello-0.0.tar.gz
$ tar -xzf debhello-0.0.tar.gz
$ tree
|-- debhello-0.0
|   |-- LICENSE
|   |-- Makefile
|   `-- src
|       `-- hello.c
`-- debhello-0.0.tar.gz
2 directories, 4 files

4.6. Step 2: Generate template files with debmake


$ cd debhello-0.0
$ debmake
...
I: pkg="debhello", ver="0.0", rev="1"
...
I: make debian/* template files
I: single binary package
I: debmake -x "1" ...
...
The debmake command generates all these template files based on command line options.
  • 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)
After the basic debmake execution, the following files are created:

|-- debhello-0.0
|   |-- debian
|   |   |-- README.Debian
|   |   |-- changelog
|   |   |-- compat
|   |   |-- control
|   |   |-- copyright
|   |   |-- patches
|   |   |   `-- series
|   |   |-- rules
|   |   |-- source
|   |   |   |-- format
|   |   |   `-- local-options
|   |   `-- watch
`-- debhello_0.0.orig.tar.gz -> debhello-0.0.tar.gz
  • debian/rules
  • The build script provided by the package maintainer.
    Here is its template file generated by the debmake command:
    
    #!/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    
        
  • debian/control
  • The main meta data for the Debian package.
    Here is its template file generated by the debmake command:
    
    Source: debhello
    Section: unknown
    Priority: optional
    Maintainer: Jerry Lee <jerry.lee@gmail.com>
    Build-Depends: debhelper (>=11~)
    Standards-Version: 4.1.4
    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.
        
  • debian/copyright

4.7. Step 3: Modification to the template files

  • 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    
        
    The dh_auto_install command for the Makefile based build system essentially runs:
    
    $(MAKE) install DESTDIR=debian/debhello”
    	
    The override_dh_auto_install target setting “prefix=/usr” let installed files as a part of the system files under /usr:
    
    $(MAKE) install DESTDIR=debian/debhello prefix=/usr
    	
  • debian/control
  • 
    ...
    Section: devel
    Priority: optional
    ...
    Description: Simple packaging example for debmake
     This Debian binary package is an example package.
     (This is an example only)   
        
  • debian/copyright
  • 
    Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
    Upstream-Name: debhello
    Source: https://github.com/JerryLeeTaipei/examples/blob/master/debhello-0.0.tar.gz
    Upstream-Contact: Jerry Lee <junye.lee@gmail.com>
    
    Files:     *
    Copyright: 2015-2021 Jerry Lee Jerry Lee <junye.lee@gmail.com>
    License:   Expat
        

4.8. Step 4: Building package with debuild

You can create a non-native Debian package using the debuild command in this source tree.

$ debuild
 dpkg-buildpackage -us -uc -ui
...
make[1]: Entering directory '/home/work/jerry/examples/debhello-0.0'
...
cc -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/home/work/jerry/examples/debhello-0.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -pedantic  -o src/hello src/hello.c
...

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

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


$ tree -FL 1 ../
../
|-- debhello-0.0/
|-- debhello-0.0.tar.gz
|-- debhello-dbgsym_0.0-1_amd64.ddeb  # the Debian debug symbol binary package
|-- debhello_0.0-1.debian.tar.xz  # the maintainer generated contents
|-- debhello_0.0-1.dsc # the meta data file for the Debian source package
|-- debhello_0.0-1_amd64.build  # the build log file
|-- debhello_0.0-1_amd64.buildinfo  # the meta data file generated by dpkg-genbuildinfo
|-- debhello_0.0-1_amd64.changes  #  the meta data file for the Debian binary package.
|-- debhello_0.0-1_amd64.deb  # the Debian binary package
`-- debhello_0.0.orig.tar.gz -> debhello-0.0.tar.gz # a symlink to the upstream tarball.

1 directory, 9 files
The binary package contents can be listed:

$ dpkg -c ../debhello_0.0-1_amd64.deb
drwxr-xr-x root/root         0 2021-10-04 09:47 ./
drwxr-xr-x root/root         0 2021-10-04 09:47 ./usr/
drwxr-xr-x root/root         0 2021-10-04 09:47 ./usr/bin/
-rwxr-xr-x root/root     14488 2021-10-04 09:47 ./usr/bin/hello
drwxr-xr-x root/root         0 2021-10-04 09:47 ./usr/share/
drwxr-xr-x root/root         0 2021-10-04 09:47 ./usr/share/doc/
drwxr-xr-x root/root         0 2021-10-04 09:47 ./usr/share/doc/debhello/
-rw-r--r-- root/root       229 2021-10-04 09:47 ./usr/share/doc/debhello/README.Debian
-rw-r--r-- root/root       181 2021-10-04 09:47 ./usr/share/doc/debhello/changelog.Debian.gz
-rw-r--r-- root/root       316 2021-10-04 09:47 ./usr/share/doc/debhello/copyright

4.9. Step 3 (alternative): Modification to the upstream source

Patch by quilt

  • To add patch with Quilt
  • 
    $ quilt new fix-hello.patch
    Patch fix-hello.patch is now on top
    
    $ quilt add Makefile README
    File debian/rules added to patch fix-hello-target.patch
    File README added to patch fix-hello-target.patch  
      	
  • Modify the source
    • Change Makefile
    • This example changes the upstream source by modifying the upstream Makefile to set the $(prefix) value to /usr:
      
      prefix = /usr
      ...
      			
      so that the debian/rules file doesn’t have the override_dh_auto_install target:
      
      #!/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 $@
      			
    • Add a file README
    • 
      $ echo "Hello!" > README    	
          		
  • Ask quilt to generate the patch
  • 
    $ quilt refresh
    Refreshed patch fix-hello.patch
    
    $ cat debian/patches/series
    # You must remove unused comment lines for the released package.
    fix-hello.patch
    
    $ cat debian/patches/fix-hello.patch 
    --- a/Makefile
    +++ b/Makefile
    @@ -1,4 +1,4 @@
    -prefix = /usr/local
    +prefix = /usr
     
     all: src/hello
    --- /dev/null
    +++ b/README
    @@ -0,0 +1 @@    
        
  • Add header
  • 
    $ quilt header -e 
    Replaced header of patch fix-hello.patch    
        

Building debian packages with debuild

This post will walk you through creating a debian package from a simple hello world C program using debuild.

Setup build environment


$ sudo apt install devscripts build-essential lintian
debuild is a convenient wrapper around dpkg-buildpackage, fakeroot, lintian, and debsign.
It handles all the packaging linting, and signing for us.

"hello world"

Prepare source files

  • main.c
  • 
    #include <stdio.h> 
    int main (int argc, char *argv[]) {  
      printf("Hi\n");  
      return 0;
    }     
        
  • Makefile
  • 
    helloworld:
    	gcc main.c -o helloworld
    
    install: helloworld
    	install -d $$(pwd)/out/usr/local/bin
    	install -m 0755 helloworld $$(pwd)/out/usr/local/bin/helloworld
        

Building and Testing


$ make
$ ./helloworld
    

Packaging our program

Note: debuild will make use of symlinks in it’s build process, so if you are using a Virtualbox or VMware Shared folder to build your package, it will not work.

  1. Create a debian folder
  2. This is where all of our debian specific packaging files will go.
    
    $ mkdir debian    
        
  3. Create a debian/control file
  4. This file describes your package using debian control fields. Below, we have defined a binary package and a corresponding source package (from which the binary package can be repackaged):
    
    Source: helloworld  
    Maintainer: Jerry Lee <jerry.lee@canonical.com>
    Build-Depends: debhelper (>= 8.0.0)
    Standards-Version: 3.9.3
    Section: utils
    
    Package: helloworld  
    Priority: extra  
    Architecture: any
    Depends: ${shlibs:Depends}, ${misc:Depends}  
    Description: a simple helloworld package
     Just prints "Hi", it's very useful.
    	
  5. Create a debian/changelog file
  6. This file tracks all the changes to the package.
    The syntax of this file is tricky, it’s recommended to use the debchange tool, or dch to create a template file.
    
    $ dch -i --create  
      	
    Make sure to change UNRELEASED to unstable.
    
    helloworld (0.0.1) unstable; urgency=medium
    
      * Initial release.
    
     -- Jerry Lee <jerry.lee@canonical.com>  Wed, 12 May 2021 09:14:35 +0800
      
  7. Create a debian/rules file
  8. This file tells debian specifically how to build your package.
    Make sure you use hard tabs here, since it uses the same format as Makefile
    
    #!/usr/bin/make -f  
    override_dh_usrlocal:
    
    %:  
    	dh $@    
        
    In general, if you have a building problem with a specific target, you just override it by adding override_{target} in your debian/rules.
  9. Create a debian/copyright file
  10. you need a copyright file (however, it can be blank).
    
    $ touch debian/copyright    
        
  11. Create a debian/compat file
  12. 
    9
        
  13. Run debuild to build your package.
  14. 
    $ debuild -us -uc    
        
    Those (-us -uc) are dpkg-buildpackage flags which are passed from debuild to dpkg-buildpackage and then would have been able to use dpkg-buildpackage's manpage to find the answer.
    • -us
    • Do not sign the source package.
    • -uc
    • Do not sign the .changes file.
  15. To see your built package
  16. 
    $ ls -l ../*amd*
    -rw-r--r-- 1 jerry jerry 2890 Jun 30 09:11 ../helloworld_0.0.1_amd64.build
    -rw-r--r-- 1 jerry jerry 5539 Jun 30 09:11 ../helloworld_0.0.1_amd64.buildinfo
    -rw-r--r-- 1 jerry jerry 1416 Jun 30 09:11 ../helloworld_0.0.1_amd64.changes
    -rw-r--r-- 1 jerry jerry 1112 Jun 30 09:11 ../helloworld_0.0.1_amd64.deb
    

HOWTO: GPG sign and verify deb packages and APT repositories

Building ubuntu packages from source

Debian

Debian New Maintainers' Guide

1. Getting started The Right Way

There are several types of people interacting around Debian with different roles:
  • upstream author
  • the person who made the original program.
  • upstream maintainer
  • the person who currently maintains the program.
  • maintainer
  • the person making the Debian package of the program.
  • sponsor
  • a person who helps maintainers to upload packages to the official Debian package archive (after checking their contents).
  • mentor
  • a person who helps novice maintainers with packaging etc.
  • Debian Developer (DD)
  • a member of the Debian project with full upload rights to the official Debian package archive.
  • Debian Maintainer (DM)
  • a person with limited upload rights to the official Debian package archive.

Chapter 2. First steps

  • Choose your program
  • A trivial upstream tarball, hello-sh-1.0.tar.gz, created as follows may offer a good starting point:
    
      
      $ mkdir -p hello-sh/hello-sh-1.0; cd hello-sh/hello-sh-1.0
    $ cat > hello <<EOF
    #!/bin/sh
    # (C) 2011 Foo Bar, GPL2+
    echo "Hello!"
    EOF
    $ chmod 755 hello
    $ cd ..
    $ tar -cvzf hello-sh-1.0.tar.gz hello-sh-1.0
    
  • Get the program, and try it out
  • Package name and version
  • If the upstream source comes as gentoo-0.9.12.tar.gz,
    • package name
    • gentoo
    • upstream version
    • 0.9.12
    Version strings can be compared using dpkg:
    
      $ dpkg --compare-versions ver_1 op ver_2
      
    Compare version numbers, where op is a binary operator: lt le eq ne ge gt.
  • Set up the shell environment variables $DEBEMAIL and $DEBFULLNAME so that various Debian maintenance tools recognize your email address and name to use for packages.
  • 
    $ cat >>~/.bashrc <<EOF
    DEBEMAIL="your.email.address@example.org"
    DEBFULLNAME="Firstname Lastname"
    export DEBEMAIL DEBFULLNAME
    EOF
    $ . ~/.bashrc  	
        
  • Initial non-native Debian package
  • dh_make is a tool to convert a regular source code package into one formatted according to the requirements of the Debian Policy.
    
      $ sudo apt-get install dh-make
      
    dh_make must be invoked within a directory containing the source code, which must be named <packagename>-<version>.
    
    ~/test/hello-sh/hello-sh-1.0$ dh_make -f ../hello-sh-1.0.tar.gz
    Type of package: (single, indep, library, python)
    [s/i/l/p]?
    Maintainer Name     : Jerry Lee
    Email-Address       : junye.lee@gmail.com
    Date                : Sun, 27 Sep 2020 21:25:30 +0800
    Package Name        : hello-sh
    Version             : 1.0
    License             : blank
    Package Type        : single
    Are the details correct? [Y/n/q]
    Please respond with "yes" or "no" (or "y" or "n")
    Currently there is not top level Makefile. This mayrequire additional tuning
    Done. Please edit the files in the debian/ subdirectory now.
    	
    This execution of dh_make creates a copy of the upstream tarball as hello-sh_1.0.orig.tar.gz in the parent directory to accommodate the creation of the non-native Debian source package with the name hello-sh-1.0.tar.gz later:
     
    $ ls -F ..
    hello-sh-1.0/  hello-sh_1.0.orig.tar.gz  hello-sh-1.0.tar.gz
      	
    Please note two things:
    • Package name and version are separated by the character _ (underscore).
    • The string .orig is inserted before the .tar.gz.

Chapter 3. Modifying the source

In Debian packaging, any changes to a file outside the debian directory must be reversible via the patch.

There are a number of different ways of handling patches in Debian packages, fortunately we are standardizing on one system, Quilt, which is now used by most packages.
References:

Quilt ia a script collection.
With quilt, all work occurs within a single directory tree.
Commands are of the form “quilt cmd”, commands print some help text with “quilt cmd -h”.
Quilt manages a stack of patches. Patches are applied incrementally on top of the base tree plus all preceding patches.
By default, most commands apply to the topmost patch on the stack.

  • Files that are not part of a patch must be added before modifying them so that quilt is aware of the original versions of the files.
  • When files in the working directory are changed, those changes become part of the working state of the topmost patch.
  • Patches can be pushed on top of the stack (quilt push)
  • Patches can be popped off the stack (quilt pop)
  • The contents of the series file can be queried (quilt series
  • The contents of the stack can be queried(quilt applied, quilt previous, quilt top)
  • The patches that are not applied at a particular moment can be queried(quilt next, quilt unapplied).
  • The quilt refresh command regenerates a patch. After the refresh, the patch and the working state are the same.
  • Before a patch is applied (or “pushed on the stack”), copies of all files the patch modifies are saved to the .pc/patch directory.
  • The patch is added to the list of currently applied patches (.pc/applied-patches).
    Later, when a patch is regenerated (quilt refresh), the backup copies in .pc/patch are compared with the current versions of the files in the source tree using GNU diff.
This means you have applied changes to the unpacked upstream source, and, the changes are not part of a patch in the debian/patches/ directory, or listed in the debian/patches/series file yet.
  • The patches are kept in debian/patches.
  • The QUILT_PATCHES environment variable can be used to override this location.
    These changes are kept as separate patches, in the form of diff files.
  • The order of patches to apply is kept in debian/patches/series.
  • A file called series contains a list of patch file names that defines the order in which patches are applied.
    Patch files are identified by pathnames that are relative to the patches directory.
    Lines in the series file that start with a hash character (#) are ignored.
    When quilt adds, removes, or renames patches, it automatically updates the series file.
  • Files in the .pc directory are automatically removed when they are no longer needed, so usually there is no need to clean up manually.
  • The QUILT_PC environment variable can be used to override the location of the .pc directory.
To patch with Quilt:
  • Setting up quilt
  • The program quilt offers a basic method for recording modifications to the upstream source for Debian packaging.
    If you have downloaded a Debian source package which uses quilt, you need to use quilt to submit a patch to the maintainers.
    It's useful to have a slightly customized default for quilt,
    • Modify ~/.bashrc
    • Create an alias dquilt for Debian packaging by adding the following lines to
      
      alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg"
      complete -F _quilt_completion -o filenames dquilt   
      export QUILT_PATCHES=debian/patches
      export QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
                  
      Then, source the file to apply the new export:
      
                  $ . ~/.bashrc
                  
    • create ~/.quiltrc
    • 
      d=. ; while [ ! -d $d/debian -a `readlink -e $d` != / ]; do d=$d/..; done
      if [ -d $d/debian ] && [ -z $QUILT_PATCHES ]; then
              # if in Debian packaging tree with unset $QUILT_PATCHES
              QUILT_PATCHES="debian/patches"
      
              if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
      fi            
                  
      This apply quilt options only when inside a Debian source package.
  • Fixing upstream bugs
  • To add a new patch you need to tell Quilt to:
    1. apply existing patches to the source
    2. 
              $ quilt push -a
              
      to "push" all existing patches onto the source tree (when you build a package, this is done by the build scripts)
    3. create a new patch
    4. 
              $ quilt new  patchname
              
      Create a new patch with the specified file name patchname
    5. which files that patch should change
    6. 
              $ quilt add file1 file2 ...
              
      Add one or more files to the topmost patch. One quilt patch can change multiple files.
      Files must be added to the patch before being modified.
    7. edit the files
    8. Now, make your changes to the files added to the patch: edit it, or replace it with an already modified file stored in a different directory.
    9. refresh the patch
    10. 
              $ quilt refresh
              
      Refreshes the the topmost patch by default.
      The actual patch file is created (and later updated) with quilt refresh.
    The quilt add step is important, if you forget it the files will not end up in the patch.
    The change will now be in debian/patches/*.diff and the series file will have had the new patch added to it.

    Assume hello should say "Hello world!". Let's use the quilt command to record the changes as fix-hello-target.patch:

    
    $ mkdir debian/patches
    $ quilt new fix-hello-target.patch
    $ quilt add hello
      	
    Change the hello file as follows:
    
    #!/bin/sh
    # (C) 2011 Foo Bar, GPL2+
    echo "Hello world!"
      
      	
    Ask quilt to generate the patch:
    
    $ quilt refresh  
      	
    and add its description following DEP-3: Patch Tagging.
    DEP-3 is a proposal to formalize a set of meta-information to be embedded in patches applied to Debian packages.
    The structure of this meta information:
    • The first header should start on the first non-empty line
    • A header always ends on the first empty line.
    • A second header (the “pseudo-header”) can start on any new paragraph.
    • A line containing 3 dashes (---) should stop the parsing: lines after it are not relevant part of the meta-information.
    Here are some headers that you can use:
    Description:(required) Description of what the patch does.
    It is formatted like Description field in debian/control: first line is short description, starting with lowercase letter, the next lines are long description, indented with a space.
    The long description allows for a more verbose explanation of the patch and its history.
    Author:(optional) This field can be used to record the name and email of the patch author(ex: “Jerry Lee <jerry.lee@canonical.com>”).
    This field can be used multiple times if several people authored the patch.
    Origin:(required except if Author is present) If the Author field is present, the Origin field can be omitted and it's assumed that the patch comes from its author. This field should document the origin of the patch. In most cases, it should be a simple URL.
    • For patches backported/taken from upstream
    • It should point into the upstream VCS web interface when possible, otherwise it can simply list the relevant commit identifier (it should be prefixed with "commit: " in that case).
      The field can be optionaly prefixed with a single keyword followed by a comma and a space to categorize the origin.
      • upstream:
      • a patch cherry-picked from the upstream
      • backport:
      • an upstream patch that had to be modified to apply on the current version
      • vendor:
      • a patch created by Debian or another distribution vendor
      • other:
      • for all other kind of patches.
    • For other cases, one should simply indicate the URL where the patch was taken from (mailing list archives, distribution bugtrackers, etc.) when possible.
    Where this patch comes from (i.e. “upstream”), when Author is not present.
    Bug-Ubuntu:A link to Launchpad bug, a short form is preferred (like https://bugs.launchpad.net/bugs/XXXXXXX).
    If there are also bugs in upstream or Debian bugtrackers, add Bug or Bug-Debian headers.
    Forwarded:(optional)Any value other than "no" or "not-needed" means that the patch has been forwarded upstream.
    Whether the patch was forwarded upstream. Either “yes”, “no” or “not-needed”.
    Applied-Upstream:(optional) This field can be used to document the fact that the patch has been applied upstream.
    It may contain the upstream version expected to contain this patch, or the URL or commit identifier of the upstream commit (with commit identifiers prefixed with "commit:", as in the Origin field), or both separated by a comma and a space.
    Last-Update:(optional)This field can be used to record the date when the meta-information was last updated. It should use the ISO date format YYYY-MM-DD.
    
    $ quilt header -e    
    	
    Examples:
    • A patch cherry-picked from upstream:
    • 
      From: Ulrich Drepper <drepper@redhat.com>
      Subject: Fix regex problems with some multi-bytes characters
      
      * posix/bug-regex17.c: Add testcases.
      * posix/regcomp.c (re_compile_fastmap_iter): Rewrite COMPLEX_BRACKET
        handling.
      
      Origin: upstream, http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=bdb56bac
      Bug: http://sourceware.org/bugzilla/show_bug.cgi?id=9697
      Bug-Debian: http://bugs.debian.org/510219
      		
    • A patch created by the Debian maintainer John Doe, which got forwarded and rejected:
    • 
      Description: Use FHS compliant paths by default
       Upstream is not interested in switching to those paths.
       .
       But we will continue using them in Debian nevertheless to comply with
       our policy.
      Forwarded: http://lists.example.com/oct-2006/1234.html
      Author: John Doe <johndoe-guest@users.alioth.debian.org>
      Last-Update: 2006-12-21
      		
    • A vendor specific patch not meant for upstream submitted on the BTS by a Debian developer:
    • 
      Description: Workaround for broken symbol resolving on mips/mipsel
       The correct fix will be done in etch and it will require toolchain
       fixes.
      Forwarded: not-needed
      Origin: vendor, http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=80;bug=265678
      Bug-Debian: http://bugs.debian.org/265678
      Author: Thiemo Seufer <ths@debian.org>
      		
    • A patch submitted and applied upstream:
    • 
      Description: Fix widget frobnication speeds
       Frobnicating widgets too quickly tended to cause explosions.
      Forwarded: http://lists.example.com/2010/03/1234.html
      Author: John Doe <johndoe-guest@users.alioth.debian.org>
      Applied-Upstream: 1.2, http://bzr.example.com/frobnicator/trunk/revision/123
      Last-Update: 2010-03-29
      
      
       
        	
  • Installation of files to their destination
  • On Debian, third-party software installs itself in the /usr/bin directory hierarchy.

Chapter 4. Required files under the debian directory

There are a number of files in the new created directory debian that we should edit in order to customize the behavior of the package.
  • control
  • This file contains various values which package management(dpkg, dselect, apt-get, apt-cache, aptitude...) tools will use to manage the package.
    Here is the control file dh_make created for us:
    
    
    Source: hello-sh
    Section: unknown
    Priority: optional
    Maintainer: Jerry Lee <junye.lee@gmail.com>
    Build-Depends: debhelper (>= 10)
    Standards-Version: 4.1.2
    Homepage: <insert the upstream URL, if relevant>
    #Vcs-Git: https://anonscm.debian.org/git/collab-maint/hello-sh.git
    #Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/hello-sh.git
    
    Package: hello-sh
    Architecture: any
    Depends: ${shlibs:Depends}, ${misc:Depends}
    Description: <insert up to 60 chars description>
     <insert long description, indented with spaces>
     
      
    • Source
    • the name of the source package.
    • Section
    • the section of the distribution the source package goes into.
      The Debian archive is divided into multiple areas: main (the free software), non-free (the not really free software) and contrib (free software that depends on non-free software).
      Each of the area is divided into sections that classify packages into rough categories:
      • admin
      • administrator-only programs
      • devel
      • programmer tools
      • doc
      • documentation
      • libs
      • libraries
      • mail
      • email readers and daemons
      • net
      • network apps and daemons
      • x11
      • X11 programs
      Let's change it then to x11. (A main/ prefix is implied so we can omit it.)
    • Priority
    • how important this package is: optional, required, important, or standard.
    • Maintainer
    • the bug tracking system will use it to deliver bug emails to you.
    • Build-Depends
    • the list of packages required to build this package. Multiple entries are separated with commas.
      For all packages packaged with the dh command in the debian/rules file, you must have debhelper (>=9) in the Build-Depends field to satisfy the Debian Policy requirement for the clean target.
    • Standards-Version
    • the version of the Debian Policy Manual standards this package follows.
    • Homepage
    • the URL of the software's upstream homepage.
    • Package
    • the name of the binary package.
    • Architecture
    • the architectures the binary package can be compiled for.
    • Depends
    • This depending on the type of the binary package.
      • any
      • an architecture dependent binary package which is usually in a compiled language..
      • all
      • an architecture independent binary package which consists of text, images, or scripts in an interpreted language..
      This example is a shell script, change this to all.
      The relationship fields: Depends, Recommends, Suggests, Pre-Depends, Build-Depends, Build-Depends-Indep and Build-Depends-Arch. These fields all have a uniform syntax. They are a list of package names separated by commas.
      The last feature you need to know about is ${shlibs:Depends}, ${perl:Depends}, ${misc:Depends}, etc.
      • ${shlibs:Depends}
      • dh_shlibdeps calculates shared library dependencies for binary packages. It generates a list of ELF executables and shared libraries it has found for each binary package. This list is used for substituting ${shlibs:Depends}.
      • ${perl:Depends}
      • dh_perl calculates Perl dependencies. It generates a list of a dependencies on perl or perlapi for each binary package. This list is used for substituting ${perl:Depends}.
      • ${misc:Depends}
      • Some debhelper commands may cause the generated package to depend on some additional packages. All such commands generate a list of required packages for each binary package. This list is used for substituting ${misc:Depends}.
    • Description
    Section and Priority are used by the packaging front-ends like aptitude when they sort packages and select defaults.
  • copyright
  • This file contains information about the copyright and license of the upstream sources.
  • changelog
  • This is a required file, which has a special format. This format is used by dpkg and other programs to obtain the version number, revision, distribution, and urgency of your package.
    dh_make created a default one,
    
    hello-sh (1.0-1) unstable; urgency=medium
    
      * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
    
     -- Jerry Lee <junye.lee@gmail.com>  Sun, 27 Sep 2020 21:25:30 +0800
        
  • rules
  • This file is in fact another Makefile that dpkg-buildpackage will use to actually create the package.
    This one is marked as executable.
    Newer dh_make generates a very simple but powerful default rules file:
    
    #!/usr/bin/make -f
    # See debhelper(7) (uncomment to enable)
    # output every command that modifies files on the build system.
    #export DH_VERBOSE = 1
    
    # see FEATURE AREAS in dpkg-buildflags(1)
    #export DEB_BUILD_MAINT_OPTIONS = hardening=+all
    
    # see ENVIRONMENT in dpkg-buildflags(1)
    # package maintainers to append CFLAGS
    #export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
    # package maintainers to append LDFLAGS
    #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
    
    %:
            dh $@
    
    # dh_make generated override targets
    # This is example for Cmake (See https://bugs.debian.org/641051 )
    #override_dh_auto_configure:
    #       dh_auto_configure -- #  -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
        
        
    A rule that you want to execute is invoked by its target name as a command line argument. For example,
    • debian/rules build
    • It runs dh build, which in turn runs the following:
      
      dh_testdir
      dh_auto_configure
      dh_auto_build
      dh_auto_test
      		
    • debian/rules clean
    • It runs dh clean, which in turn runs the following:
           
      dh_testdir
      dh_auto_clean
      dh_clean        
      		

Chapter 6. Building the package

  • Complete (re)build
  • Issue the following command in the source directory:
    
    		$ dpkg-buildpackage  [option...]
      	
    This will do everything to make full binary and source packages for you
    • clean the source tree
    • debian/rules clean
    • build the source package
    • It runs the source hook and calls dpkg-source -b to generate the source package.
      Pass option opt to dpkg-source
      
            	--source-option=opt
              
    • build the program
    • debian/rules build
    • build binary packages
    • fakeroot debian/rules binary
    • make the .dsc file
    • make the .changes file
    • dpkg-genchanges
    If the building is successful, the .dsc and .changes files will be signed with your private GPG key using the debsign command.
  • Autobuilder
  • debuild command
  • 
           debuild [debuild options] [dpkg-buildpackage options] [--lintian-opts lintian options]
           debuild [debuild options] -- binary|binary-arch|binary-indep|clean ...    
        
    debuild creates all the files necessary for uploading a Debian package. It
    • first runs dpkg-buildpackage
    • The dpkg-buildpackage options may be given on the command line.
      
      -us, --unsigned-source
               Do not sign the source package (long option since dpkg 1.18.8).     
      
      -uc, --unsigned-changes
               Do not sign the .buildinfo and .changes files (long option since dpkg 1.18.8).
            		
    • then runs lintian on the .changes file created
    • finally signs the .changes and/or .dsc files as appropriate.
    The debuild command executes the lintian command to make a static check after building the Debian package.
    The lintian command can be customized with the following in the ~/.devscripts file:
    
    DEBUILD_DPKG_BUILDPACKAGE_OPTS="-us -uc -I -i"
    DEBUILD_LINTIAN_OPTS="-i -I --show-overrides"    	
        
    To clean the source and rebuild the package:
    
      	$ debuild
      	
    You can clean the source tree as simply as:
    
        $ debuild -- clean
        
  • pbuilder package
  • Quick rebuild
  • For testing purposes, you can make a .deb file without rebuilding the upstream sources :
    
      		$ fakeroot debian/rules build        
      	
The .changes files are the manifest the "maintainer" prepares for the upload, is it indeed signed, and the archive software accepting that upload needs to trust that maintainer.

Then, the trust is transferred to the archive.
The archive makes sure to sign the Sources and Packages repository meta-indices, takes care of key rotation, expiration, etc.
The trust anchor is thus transferred from maintainer to archive.
If you don't trust an archive, you should not simply attempt to download artifacts from it.

That's the main reason why apt does enforce signature verification on the Sources meta-indices before downloading a .dsc, but then dpkg-source only has opportunistic (and non-fatal) verification for the .dsc signatures.

Chapter 7. Checking the package

Debian Policy Manual

This manual describes the policy requirements for the Debian distribution.

The reason source and binary package names don't always match is that building a source package can produce multiple binary packages.

You can see the name of the source package corresponding to a binary package(if the package is installed) by checking the Source: … line in the output of


$  dpkg -s BINARY_PACKAGE_NAME 
or

$ apt-cache show BINARY_PACKAGE_NAME.

You can list the binary packages produced by a source package with

$ aptitude search '?source-package(^SOURCE_PACKAGE_NAME$).
The command downloads a source package PACKAGE_NAME,

$ apt-get source PACKAGE_NAME
If you give it an PACKAGE_NAME which isn't a known source package, it looks it up in the database of installable binary packages and tries to download the corresponding source package.

The command queries the source package database to obtain a list of binary packages (the list in the Build-Dep: field), and installs those binary packages.


$ apt-get build-dep PACKAGE_NAME

3. Binary packages

4. Source packages

4.1. Standards conformance

The version is specified in the Standards-Version control field.

4.2. Package relationships

Source packages should specify which binary packages they require to be installed or not to be installed in order to build correctly.(build-time dependency.)
The build-essential package includes required package for building.
When specifying the set of build-time dependencies, one should list only those packages explicitly required by the build. It is not necessary to list packages which are required merely because some other package in the list of build-time dependencies depends on them.

5. Control files and their fields

6. Package maintainer scripts and installation procedure

6.1. Introduction to package maintainer scripts

It is possible to supply scripts as part of a package which the package management system will run for you when your package is installed, upgraded or removed. They must be proper executable files

It is important that they exit with a non-zero status if there is an error, so that the package management system can stop its processing.
For shell scripts this means that you almost always need to use the following to exit immediately if a command exits with a non-zero status:

  
  set -e 
Broadly speaking:
  • the preinst is called before (a particular version of) a package is unpacked
  • This script is executed before the package it belongs to is unpacked from its Debian archive (".deb") file.
    Many 'preinst' scripts stop services for packages which are being upgraded until their installation or upgrade is completed (following the successful execution of the 'postinst' script).
  • the postinst after a package is unpacked
  • This script typically completes any required configuration of the package foo once foo has been unpacked from its Debian archive (".deb") file.
    Often, 'postinst' scripts ask users for input, and/or warn them that if they accept default values, they should remember to go back and re-configure that package as needed.
    Many 'postinst' scripts then execute any commands necessary to start or restart a service once a new package has been installed or upgraded.
  • the prerm before (a version of) a package is removed
  • This script typically stops any daemons which are associated with a package.
    It is executed before the removal of files associated with the package.
  • the postrm after a package is removed
  • This script typically modifies links or other files associated with foo, and/or removes files created by the package.
Programs called from maintainer scripts should not normally have a path prepended to them.

Along with a file named control, all of these files are part of the "control" section of a Debian archive file, and should be located in the ‘debian’ folder.

(make sure the files are executeable, ‘chmod 0755’)


$ tree modemmanager-1.12.8/debian/            
modemmanager-1.12.8/debian/
|-- 77-mm-qdl-device-blacklist.rules
|-- changelog
|-- compat
|-- control
|-- copyright
|-- gbp.conf
|-- gir1.2-modemmanager-1.0.install
|-- libmm-glib-dev.install
|-- libmm-glib-doc.install
|-- libmm-glib0.install
|-- libmm-glib0.symbols
|-- modemmanager-dev.install
|-- modemmanager-doc.install
|-- modemmanager.docs
|-- modemmanager.install
|-- modemmanager.maintscript
|-- modemmanager.postrm
|-- modemmanager.prerm
|-- patches
|   |-- default_strict_probing_policy.patch
|   `-- series
|-- rules
|-- source
|   `-- format
`-- watch
  
$ cat modemmanager-1.12.8/debian/modemmanager.prerm
#!/bin/sh
set -e

# avoid cancelling of "stop" when NM D-BUS reactivates modemmanager
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
    systemctl mask --runtime ModemManager
fi

#DEBHELPER#
  
$ cat modemmanager-1.12.8/debian/modemmanager.postrm
#!/bin/sh
set -e

#DEBHELPER#
  
  
  
Currently all of the control files can be found in the directory /var/lib/dpkg/info:

$ ls /var/lib/dpkg/info/modemmanager.p*
/var/lib/dpkg/info/modemmanager.postinst  /var/lib/dpkg/info/modemmanager.preinst
/var/lib/dpkg/info/modemmanager.postrm    /var/lib/dpkg/info/modemmanager.prerm  
  
  • The files relevant to a package "modemmanager" begin with the package's name "modemmanager" and have file extensions of "preinst", "postinst", etc., as appropriate.
  • The file modemmanager.list in that directory lists all of the files that were installed with the package "modemmanager".
  • Note that the location of these files is a dpkg internal; you should not rely on it.
After customizing maintainer scripts for a software package , you must ensure that you not only test install and upgrade , but also remove and purge .

6.2. Maintainer scripts idempotency

  • if it is run successfully, and then it is called again
  • it doesn’t bomb out or cause any harm, but just ensures that everything is the way it ought to be.
  • if the first call failed, or aborted half way through for some reason
  • the second call should merely do the things that were left undone the first time, if any, and exit with a success status if everything is OK

6.3. Controlling terminal for maintainer scripts

Maintainer scripts are not guaranteed to run with a controlling terminal and may not be able to interact with the user.

6.4. Exit status

Each script must return a zero exit status for success, or a nonzero one for failure.

6.5. Summary of ways maintainer scripts are called

The maintainer scripts may be called along with what facilities those scripts may rely on being available at that time.
In the following discussions,
  • Script names preceded by new- are the scripts from the new version of a package being installed, upgraded to, or downgraded to.
  • Script names preceded by old- are the scripts from the old version of a package that is being upgraded from or downgraded from.
Different scripts may be called in different ways by different utilities.

preinst
postinst
  1. postinst configure most-recently-configured-version
  2. old-postinst abort-upgrade new-version
  3. conflictor's-postinst abort-remove in-favour package new-version
  4. postinst abort-remove
  5. deconfigured's-postinst abort-deconfigure in-favour failed-install-package version [ removing conflicting-package version ]
prerm
  1. old-prerm upgrade new-version
  2. conflictor's-prerm remove in-favour package new-version
  3. deconfigured's-prerm deconfigure in-favour package-being-installed version [removing conflicting-package version]
  4. new-prerm failed-upgrade old-version
postrm
  1. postrm remove
  2. postrm purge
  3. old-postrm upgrade new-version
  4. disappearer's-postrm disappear overwriter overwriter-version
  5. new-postrm failed-upgrade old-version
  6. new-postrm abort-install
  7. new-postrm abort-install old-version
  8. new-postrm abort-upgrade old-version

6.6. Details of unpack phase of installation or upgrade

If a major error occurs in the action of package management, the maintainer scripts are run with different arguments in reverse order.

These are cases for the “error unwind” calls listed below.

  • Notify the currently installed package
  • If a “conflicting” package is being removed at the same time, or if any package will be broken (due to Breaks)
  • Run the preinst of the new package
  • The new package’s files are unpacked, overwriting any that may be on the system already
    • Backups of the old files are kept temporarily, and if anything goes wrong the package management system will attempt to put them back as part of the error unwind.
    • It is an error for a package to contain files which are on the system in another package.(unless Replaces is used)
    • It is a more serious error for a package to contain a plain file or other kind of non-directory where another package has a directory (unless Replaces is used).
    • A directory will never be replaced by a symbolic link to a directory or vice versa
  • If the package is being upgraded
    1. call
    2. 
      old-postrm upgrade new-version        
              
    3. If the above fails
    4. dpkg will attempt:
      
      new-postrm failed-upgrade old-version
      				
      • If this works, installation continues.
      • If the above fails
      • error unwind:
        
        old-preinst abort-upgrade new-version                
                        
        1. If this fails, the old version is left in a “Half-Installed” state.
        2. If it works
        3. dpkg now calls:
          
          new-postrm abort-upgrade old-version                
                          		
          • If this fails, the old version is left in a “Half-Installed” state.
          • If it works
          • dpkg now calls:
            
            old-postinst abort-upgrade new-version                
                            				
            If this fails, the old version is in an “Unpacked” state.
            If dpkg gets this far, it won’t back off past this point if an error occurs.
            This will leave the package in a fairly bad state, which will require a successful re-installation to clear up, but it’s when dpkg starts doing things that are irreversible.
  • Any files which were in the old version of the package but not in the new are removed.
  • The backup files made during installation, above, are deleted.

7. Declaring relationships between packages

7.1. Syntax of relationship fields

They are a list of package names separated by commas.

  • alternative package names separated by vertical bar (pipe) symbols |
  • The dependency can be satisfied by any one of the alternative packages.
  • The relations allowed
    • <<
    • strictly earlier
    • &kt;=
    • earlier or equal
    • =
    • exactly equal
    • >=
    • later or equal
    • >>
    • strictly later
  • restricted to a certain set of architectures
  • This is indicated in brackets after each individual package name and the optional version specification. A list separated by whitespace.
Foe ex.,

Package: mutt
Version: 1.3.17-1
Depends: libc6 (>= 2.2.1) [i386 amd64 kfreebsd-i386 armel armhf powerpc mips], default-mta | mail-transport-agent   
    

7.2. Binary Dependencies - Depends, Recommends, Suggests, Enhances, Pre-Depends

A Depends field takes effect only when a package is to be configured. A package will not be configured unless all of the packages listed in its Depends field have been correctly configured.

The Depends field should also be used:

  • if the postinst or prerm scripts require the depended-on package to be unpacked or configured in order to run.
  • if the depended-on package is needed by the postrm script to fully clean up after the package removal.

Newer software versions in Debian stable

留言

熱門文章