[[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/*
|====

== The multiarch package split scenario examples

Here are some typical multiarch package split scenario examples for the followings:

* a library source *lib*'foo'*-1.tar.gz*
* a tool source 'bar'*-1.tar.gz* written in a compiled language
* a tool source 'baz'*-1.tar.gz* written in an interpreted language

.Package split examples
[options="header", cols="3,2,2,8"]
|====
|Package            |Architecture: |Multi-Arch: |Package content
|*lib*'foo1'        |any           |same        |the shared library, co-installable
|*lib*'foo1'*-dbg*  |any           |same        |the shared library debug symbols, co-installable
|*lib*'foo'*-dev*   |any           |same        |the shared library header files etc., co-installable
|*lib*'foo`*-tools* |any           |foreign     |the run-time support programs, not co-installable
|*lib*'foo'*-doc*   |all           |foreign     |the shared library documentation files
|'bar'              |any           |foreign     |the compiled program files, not co-installable
|'bar'*-doc*        |all           |foreign     |the documentation files for the program
|'baz'              |all           |foreign     |the interpreted program files
|====

Please note that the development package should contain a symlink for the associated shared library without a version number. E.g.: */usr/lib/x86_64-linux-gnu/libfoo.so* -> *libfoo.so.1*
