This is a release goal for release 1.0.
There are three high-level design aspects to this multiarch implementation: the filesystem hierarchy that primarily enables package coinstallability, control information documenting package coinstallability and dependency satisfaction, and coinstallability considerations in package management.
For reference, see the specification and other documentation for multiarch in Debian and Ubuntu.
Filesystem Hierarchy
For packages to be coninstallable with themselves (such that a user can have multiple architecture builds of one package installed simultaneously), all architecture-dependent files must be installed in architecture-dependent locations. The most straightforward way to do this is to embed architecture strings into filesystem paths.
Debian and Ubuntu do something similar to this. In a Debian library package
that supports multiarch, shared object files are installed in
/usr/lib/<triplet>
, where <triplet>
is a GNU system type.
The scope of Debian's and Ubuntu's multiarch work does not include coinstallable executable programs.
Such work, however, would help enable cross installation of packages. So a goal of this multiarch implementation is to support coinstallation of shared object files, header files, and executable programs.
There are two proposed filesystem hierarchies (see below) to support this.
Parts of the toolchain (especially the dynamic linker) need to be configured
and/or patched to use multiarch library paths. Additionally, at least the
native-architecture executable program directories have to be added to the
PATH
environment variable (set in libbb/messages.c
and libbb/libbb.h
in
the BusyBox source as of versions 1.19.3 and 1.20.2).
Proposal 1: /usr
Organized Primarily by Architecture
It may be useful to install all architecture-dependent files under
/usr/<arch>
, where <arch>
is a distribution architecture string. The
filesystem hierarchy would then look something like this:
/
+- bin/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
+- lib/
| +- core-linux-eglibc/
| \- cortexa8-linux-eglibc/
+- sbin/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
\- usr/
+- core-linux-eglibc/
| +- bin/
| +- games/
| +- include/
| +- lib/
| +- sbin/
+- cortexa8-linux-eglibc/
| +- bin/
| +- games/
| +- include/
| +- lib/
| +- sbin/
+- bin/
+- games/
+- include/
+- local/
+- native -> core-linux-eglibc
+- sbin/
+- share/
\- src/
Note that /usr/lib
doesn't exist, as no architecture-independent files should
be installed there.
BusyBox needs to be patched to set the PATH
environment variable to
/sbin:/sbin/native:/usr/sbin:/usr/native/sbin:/bin:/bin/native:/usr/bin:/usr/native/bin
.
Proposal 2: /usr
Organized Secondarily by Architecture
It may be cleaner and slightly more efficient to install architecture-dependent files within an architecture-dependent directory under otherwise standard paths. This is similar to how Debian and Ubuntu have designed their multiarch filesystem hierarchy. Such an organized filesystem hierarchy would look something like this:
/
+- bin/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
+- lib/
| +- core-linux-eglibc/
| \- cortexa8-linux-eglibc/
+- sbin/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
\- usr/
+- bin/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
+- games/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
+- include/
| +- core-linux-eglibc/
| \- cortexa8-linux-eglibc/
+- lib/
| +- core-linux-eglibc/
| \- cortexa8-linux-eglibc/
+- local/
+- sbin/
| +- core-linux-eglibc/
| +- cortexa8-linux-eglibc/
| \- native -> core-linux-eglibc
+- share/
\- src/
Note that this hierarchy is more consistent than is the hierarchy in proposal 1.
That is, /bin
and /usr/bin
, for example, are both laid out the same.
BusyBox needs to be patched to set the PATH
environment variable to
/sbin:/sbin/native:/usr/sbin:/usr/sbin/native:/bin:/bin/native:/usr/bin:/usr/bin/native
.
Control Information
New package control information will be needed to indicate whether a package is coinstallable with itself and to mark its purpose.
During build-time, there are two possible architectures for any dependent package:
- Host-architecture (architecture for which packages are built). Packages for
this architecture provide things like libraries and headers. An example is
libexpat.1-dev
. - Build-architecture (architecture on which packages are built). Packages for
this architecture provide things like build utilities. An example is
pkg-config
.
During install-time, there are also two possible architectures for any dependent package:
- Host-architecture (architecture for which packages are installed). Packages
for this architecture provide things like libraries and utilities. Examples
include
libz.1
,gcc-4.7-<arch>
(dependency ofgcc-<arch>
), andfakeroot
(recommendation ofopkhelper-1.0
). - Install-architecture (architecture on which packages are installed).
Packages for this architecture provide things like utilities used by
maintainer scripts. An example is
insserv
(or a similar tool).
Host-architecture packages should be coinstallable with themselves, and they
should satisfy dependencies of the same architecture. For example, the
dependency of libexpat.1-dev:cortexa8-linux-eglibc
on libexpat.1
should
resolve to a dependency on libexpat.1:cortexa8-linux-eglibc
.
Build- and install-architecture packages need not be coinstallable with
themselves, and they should satisfy dependencies of any architecture. For
example, the build dependency of glib
(built on core-linux-eglibc
for
cortexa8-linux-eglibc
) on pkg-config
should resolve to a build dependency on
pkg-config:core-linux-eglibc
.
Debian and Ubuntu specify such properties in a Multi-Arch
control field. A
value of same
indicates that a package satisfies dependencies of the same
architecture; a value of foreign
indicates that a package satisfies
dependencies of any architecture. We can implement something similar, perhaps
even using the same terminology.
Logic to handle the new control information will need to be added to opkg and opkhelper (specifically oh-checkbuilddeps).
Special design considerations need to be given to install-time dependencies. Specific use case analysis can help here.
Architecture-Independent Files
Many packages provide architecture-independent files (configuration files,
documentation, data, etc.). To the extent possible and feasible, these should
simply be provided by architecture-independent packages (with names like
*-common
, *-data
, or *-base
).
If this is not possible in all cases, then some modifications to opkg will be necessary (reference counting, implicit "Breaks" relationships, etc.).