[[multiarch]]
=== Multiarch

The multiarch support for cross-architecture installation of binary packages (particularly *i386* and *amd64*, but also other combinations) in the *dpkg* and *apt* packages introduced to Debian *wheezy* (7.0, May 2013) demands us to pay extra attention for the packaging.

You should read the following references in detail.

* Ubuntu wiki (upstream)
** https://wiki.ubuntu.com/MultiarchSpec[MultiarchSpec]
* Debian wiki (Debian situation)
** https://wiki.debian.org/Multiarch[Debian multiarch support]
** https://wiki.debian.org/Multiarch/Implementation[Multiarch/Implementation]

The multiarch is enabled by using the *<triplet>* value such as *i386-linux-gnu* and *x86_64-linux-gnu* in the install path of shared libraries as */usr/lib/<triplet>/*, etc..

* The *<triplet>* value required internally by *debhelper* scripts is implicitly set in themselves.  The maintainer doesn't need to worry.

* The *<triplet>* value used in **override_dh_*** target scripts must be explicitly set in the *debian/rules* by the maintainer.  The *<triplet>* value is stored in *$(DEB_HOST_MULTIARCH)* variable in the following *debian/rules* snippet example:
+
----
DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
...
override_dh_install:
	mkdir -p package1/lib/$(DEB_HOST_MULTIARCH)
	cp -dR tmp/lib/. package1/lib/$(DEB_HOST_MULTIARCH)
----

See <<variablesrules>> and *dpkg-architecture*.

==== The multiarch library path

Debian policy requires to follow https://www.debian.org/doc/packaging-manuals/fhs/fhs-2.3.html[Filesystem Hierarchy Standard].  Its https://www.debian.org/doc/packaging-manuals/fhs/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA[/usr/lib : Libraries for programming and packages] states "*/usr/lib* includes object files, libraries, and internal binaries that are not intended to be executed directly by users or shell scripts."

Debian policy makes an exception to https://www.debian.org/doc/packaging-manuals/fhs/fhs-2.3.html[Filesystem Hierarchy Standard] to use */usr/lib/<triplet>/* instead of */usr/lib<qual>/* (e.g., */lib32/* and */lib64/*) to support the multiarch library.

.The multiarch library path options
[options="header", cols="2,3,3"]
|====
|Classic path	|i386 multiarch path		|amd64 multiarch path
|*/lib/*	|*/lib/i386-linux-gnu/*		|*/lib/x86_64-linux-gnu/*
|*/usr/lib/*	|*/usr/lib/i386-linux-gnu/*	|*/usr/lib/x86_64-linux-gnu/*
|====

For Autotools based packages under the *debhelper* package (compat>=9), this path setting is automatically taken care by the *dh_auto_configure* command.

For other packages with non-supported build systems, you need to manually adjust the install path as follows.

* If *./configure* is used in the part of *override_dh_auto_configure* target in *debian/rules*, make sure to replace it with ``*dh_auto_configure --*'' while re-targeting the install path from */usr/lib/* to */usr/lib/$(DEB_HOST_MULTIARCH)/*.
* Replace all occurrences of **/usr/lib/** with **/usr/lib/*/** in **debian/**'foo'**.install** files.

All files installed simultaneously as the multiarch package to the same file path should have exactly the same file content. You must be careful on differences generated by the data byte order and by the compression algorithm.

NOTE: The *--libexecdir* option of the *./configure* command specifies the default path to install executable programs run by other programs rather than by users. Its Autotools default is */usr/libexec/* but its Debian non-multi-arch default is */usr/lib/*.  If such executables are a part of a "Multi-arch: foreign" package, path such as */usr/lib/* or */usr/lib/*'packagename' may be more desirable than */usr/lib/<triplet>/* which *dh_auto_configure* uses.  The http://www.gnu.org/prep/standards/html_node/Directory-Variables.html[GNU Coding Standards: 7.2.5 Variables for Installation Directories] has description for *libexecdir* as "The definition of *libexecdir* is the same for all packages, so you should install your data in a subdirectory thereof. Most packages install their data under *$(libexecdir)/package-name/* ...". (It is always good idea to follow GNU unless it conflicts with the Debian policy)

The shared library files in the default path **/usr/lib/** and **/usr/lib/<triplet>/** are loaded automatically.

For the shared library files in the other path, GCC option *-l* must be set by the *pkg-config* command to make them loaded properly.

==== The multiarch header file path

GCC includes both */usr/include/* and */usr/include/<triplet>/* by default on the multiarch Debian system.

If the header file is not in those paths, GCC option *-I* must be set by the *pkg-config* command to make "**#include <**'foo.h'**>**" work properly.

.The multiarch header file path options
[options="header", cols="2,3,3"]
|====
|Classic path	|i386 multiarch path		|amd64 multiarch path
|*/usr/include/*	|*/usr/include/i386-linux-gnu/*	|*/usr/include/x86_64-linux-gnu/*
|*/usr/include/*'packagename'*/*	|*/usr/include/i386-linux-gnu/*'packagename'*/*	|*/usr/include/x86_64-linux-gnu/*'packagename'*/*
|	|*/usr/lib/i386-linux-gnu/*'packagename'*/*	|*/usr/lib/x86_64-linux-gnu/*'packagename'*/*
|====

The use if the */usr/lib/<triplet>/*'packagename'*/* path for the header files allows the upstream to use the same install script for the multiatch system with */usr/lib/<triplet>* and the biarch system with */usr/lib<qual>/*. footnote:[This path is compliant to the FHS.  https://www.debian.org/doc/packaging-manuals/fhs/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA[Filesystem Hierarchy Standard: /usr/lib : Libraries for programming and packages] states "Applications may use a single subdirectory under */usr/lib*. If an application uses a subdirectory, all architecture-dependent data exclusively used by the application must be placed within that subdirectory."]

The use of the file path containing 'packagename' enables to have more than 2 development libraries simultaneously installed on a system.

==== The multiarch ***.pc** file path

The *pkg-config* program is used to retrieve information about installed libraries in the system.  It stores its configuration parameters in the ***.pc** file and is used for setting the **-I** and **-l** options for GCC.

.The ***.pc** file path options
[options="header", cols="2,3,3"]
|====
|Classic path	|i386 multiarch path		|amd64 multiarch path
|*/usr/lib/pkgconfig/*	|*/usr/lib/i386-linux-gnu/pkgconfig/*	|*/usr/lib/x86_64-linux-gnu/pkgconfig/*
|====

