[[rules]]
=== debian/rules

The *debian/rules* script is the executable script to build the Debian package.

* The *debian/rules* script re-targets the upstream build system (see <<build>>) to install files in the **$(DESTDIR)** and creates the archive file of the generated files as the *deb* file.
** The *deb* file is used for the binary distribution and installed to the system using the *dpkg* command.
* The *dh* command is normally used as the front-end to the build system inside the *debian/rules* script.
* **$(DESTDIR)** path depends on the build type.
** **$(DESTDIR)=debian/**'binarypackage'  (single binary package)
** **$(DESTDIR)=debian/tmp**  (multiple binary package)

[[dh]]
==== dh

The *dh* command from the *debhelper* package with the help from its associated packages functions as the wrapper to the typical upstream build systems and offers us with the uniform access to them by supporting all the Debian policy stipulated targets of the *debian/rules* file.

* *dh clean* : clean files in the source tree.
* *dh build* : build the source tree
* *dh build-arch* : build the source tree for architecture dependent packages
* *dh build-indep* : build the source tree for architecture independent packages
* *dh install* : install the binary files to *$(DESTDIR)*
* *dh install-arch* : install the binary files to *$(DESTDIR)* for architecture dependent packages
* *dh install-indep* : install the binary files to *$(DESTDIR)* for architecture independent packages
* *dh binary* : generate the *deb* file
* *dh binary-arch* : generate the *deb* file for architecture dependent packages
* *dh binary-indep* : generate the *deb* file for architecture independent packages

NOTE: For *debhelper* ``compat >= 9'', the *dh* command exports compiler flags (*CFLAGS*, *CXXFLAGS*, *FFLAGS*, *CPPFLAGS* and *LDFLAGS*) with values as returned by *dpkg-buildflags* if they are not set previously.  (The *dh* command calls *set_buildflags* defined in the *Debian::Debhelper::Dh_Lib* module.)

[[simplerules]]
==== Simple debian/rules

Thanks to this abstraction of the *dh* command footnote:[This simplicity is available since the version 7 of the *debhelper* package.  This guide assumes the use of the *debhelper* version 9 or newer.], the Debian policy compliant *debian/rules* file supporting all the required targets can be written as simple as footnote:[The *debmake* command generates a bit more complicated *debian/rules* file.  But this is the core part.]:

.Simple *debian/rules*:
----
#!/usr/bin/make -f
#export DH_VERBOSE = 1

%:
	dh $@
----

Essentially, this *dh* command functions as the sequencer to call all required *dh_** commands at the right moment.

NOTE: The *debmake* command sets the *debian/control* file with ``*Build-Depends: debhelper (>=9)*'' and the *debian/compat* file with ``*9*''.

TIP: Setting ``*export DH_VERBOSE = 1*'' outputs every command that modifies files on the build system.  Also it enables verbose build logs for some build systems.

[[customrules]]
==== Customized debian/rules

Flexible customization of the *debian/rules* is realized by adding appropriate *override_dh_** targets and their rules.

Whenever some special operation is required for a certain *dh_*'foo' command invoked by the *dh* command, any automatic execution of it can be overridden by adding the makefile target *override_dh_*'foo' in the *debian/rules* file.

The *debmake* command creates the initial template file taking advantage of the above simple *debian/rules* while adding some extra customizations for the package hardening, etc.

You need to know how underlying build systems work under the hood (see <<build>>) to address their irregularities using the package customization.

See <<simple>> for the actual simple *debian/rules* generated by the *debmake* command which comes with the commented out parts addressing the hardening via compile options (see <<harden>>) and the multiarch customization (see <<multiarch>>).

[[variablesrules]]
==== Variables for debian/rules

Some variable definitions useful for customizing *debian/rules* can be found in files under */usr/share/dpkg/*.  Notably:

*pkg-info.mk*::
  *DEB_SOURCE*, *DEB_VERSION*, *DEB_VERSION_EPOCH_UPSTREAM*, *DEB_VERSION_UPSTREAM_REVISION*, *DEB_VERSION_UPSTREAM*, and *DEB_DISTRIBUTION* variables.
  +
  These are useful for the backport support etc..

*vender.mk*::
  *DEB_VENDOR* and *DEB_PARENT_VENDOR* variables; and *dpkg_vendor_derives_from* macro.
  +
  These are useful for the vendor support (Debian, Ubuntu, ...).

*architecture.mk*::
  Set **DEB_HOST_*** and  **DEB_BUILD_*** variables.
  +
  Only variables used explicitly in *debian/rules* need to be defined using *dpkg-architecture*.  So there is no need to include *architecture.mk* in *debian/rules*.

*buildflags.mk*::
  Set *CFLAGS*, *CPPFLAGS*, *CXXFLAGS*, *OBJCFLAGS*, *OBJCXXFLAGS*, *GCJFLAGS*, *FFLAGS*, *FCFLAGS*, and *LDFLAGS* build flags.

If you wish to use some of these useful variables in *debian/rules*, copy relevant codes to *debian/rules* or write a simpler alternative in it.  Please keep *debian/rules* simple.

For example, you can add an extra option to *CONFIGURE_FLAGS* for *linux-any* target architectures by adding the followings to *debian/rules*:

----
DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
 ...
ifeq ($(DEB_HOST_ARCH_OS),linux)
CONFIGURE_FLAGS += --enable-wayland
endif
----

TIP: It was useful to include *buildflags.mk* in the *debian/rules* to set the build flags such as *CPPFLAGS*, *CFLAGS*, *LDFLAGS*, etc. properly while honoring *DEB_CFLAGS_MAINT_APPEND*, *DEB_BUILD_MAINT_OPTIONS*, etc. for the *debhelper* ``compat \<= 8''.  Now you should use the *debhelper* ``compat >= 9'', should not include *buildflags.mk* without specific reasons, and should let the *dh* command set these build flags.

See <<multiarch>>, *dpkg-architecture*(1) and *dpkg-buildflags*(1).

[[reproducible]]
==== Reproducible build

Here are some recommendations to attain the reproducible build result.

* Don't embed the timestamp based on the system time.
* Use ``*dh $@*'' in the *debian/rules* to access the latest *debhelper* features.
* Export the build environment as ``*LC_ALL=C.UTF-8*'' (see <<utf-8-build>>).
* Read more at https://wiki.debian.org/ReproducibleBuilds[ReproducibleBuilds].

If the timestamp is needed, please consider to patch the upstream source to obtain the timestamp from the last entry in *debian/changelog*.

.Shell code snippet example to obtain a formatted timestamp string:
----
date +'%Y-%m-%d' -d"`dpkg-parsechangelog -SDate`"
----

