summaryrefslogtreecommitdiffstats
path: root/dev/multiarch/design.mdwn
blob: 4d2ad15ecf33579a05dbb727cd160519da5e1e87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
[[!meta title="Multiarch Design"]]

This is a [[release_goal|dev/releases/1/multiarch]] 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][wuc-mas] and [other
documentation][wdo-ma] 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][ac-systemtype].

The scope of Debian's and Ubuntu's multiarch work [does not include][wdo-ma-fut]
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 of `gcc-<arch>`), and
    `fakeroot` (recommendation of `opkhelper-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.).


[wdo-ma]: http://wiki.debian.org/Multiarch
[wuc-mas]: https://wiki.ubuntu.com/MultiarchSpec
[ac-systemtype]: https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/System-Type.html
[wdo-ma-fut]: http://wiki.debian.org/Multiarch#Future_development