Policies/Multiarch
From Mandriva Community Wiki
This page explains multiarch support for devel packages as implemented on Mandriva Linux. It is based on an email Gwenole sent to the Cooker mailing list.
Contents |
[edit] Context
Up to now, Mandriva Linux for x86-64 had really good support for 32-bit runtime, i.e. if you wanted a 32-bit program you simply had to install its required dependencies too. Mostly no conflicts at all, no hack to generate the 32-bit packages, independent updates. That's it.
Now, it's time to move on and provide a higher level of 32-bit compatibility with development packages and the ability to generate those directly without a chroot.
[edit] Building 32-bit rpm's on a x86_64 distribution
Building a 32-bit rpm is now as simple as executing linux32 rpm --rebuild <sourcerpm>. linux32 is a small program that turns the running personality to PER_LINUX32 so that uname -m reports i686. Besides, a few core applications were patched so that they know when to generate 32-bit code in such a case (gcc[1], rpm[2], as, etc.) or use the right pkgconfig files.
Now, you may ask: some development headers or config scripts are arch dependent, so how to deal with them?
[edit] How this works
[edit] Binaries
For binaries, this is determined at runtime. Arch dependent config scripts (e.g. glib-config) are placed into /usr/bin/multiarch-ARCH-linux/*. Then, a wrapper script multiarch-dispatch is used to dispatch execution according to the underlying personality.
[a@dhcp136 a]$ glib-config --cflags -I/usr/include/glib-1.2 -I/usr/lib64/glib/include [a@dhcp136 a]$ linux32 glib-config --cflags -I/usr/include/glib-1.2 -I/usr/lib/glib/include
At the packaging level, glib-1.2 in our example, you need some arrangements but the required changes are reduced to the minimum. Basically, you annotate multiarch binaries at the end of the %install section (after installing files) as follows:
%multiarch_binaries $RPM_BUILD_ROOT%{_bindir}/glib-config
Similarly, the %files list also needs a "note", but this one is rather cosmetic and especially required when you want to rebuild the package on an older distribution which is not multiarch -devel aware. In our example:
%multiarch %{multiarch_bindir}/glib-config
%multiarch is a macro function that expands to nothing on older distributions, provided you have installed multiarch-utils and your macrofiles: list contains /etc/rpm/macros.multiarch too. So, the additionnal file will not be listed on the old distributions.
Take care, %multiarch and =%multiarch_binaries= are functions, so do not put {} around the macro name or it will not see its arguments.
[edit] Headers
For header files, the process is very similar as shows this example:
%multiarch_includes $RPM_BUILD_ROOT%{_includedir}/pci/config.h
<pci/config.h> will be a trampoline to the right header depending on the CPU you target.
[a@dhcp136 SPECS]$ cat /usr/include/pci/config.h #define ''MULTIARCH''HEADER pci/config.h #include <multiarch-dispatch.h>
The arch-dependent header is placed into /usr/include/multiarch-ARCH-linux/ with the same hierarchy. Then, depending on your compilation mode, gcc will grab multiarch-x86_64-linux/pci/config.h or multiarch-i386-linux/pci/config.h and all is fine.
[a@dhcp136 vrac]$ gcc -E pci.c | grep multiarch.*config.h # 1 "/usr/include/multiarch-x86_64-linux/pci/config.h" 1 3 4 [a@dhcp136 vrac]$ linux32 gcc -E pci.c | grep multiarch.*config.h # 1 "/usr/include/multiarch-i386-linux/pci/config.h" 1 3 4
Note, the %multiarch_includes script tries to be smart and will also dispatch headers locally included in the currently dispatched header, e.g. we have <gkrellm2/gkrellm.h> that #include "gkrellm-public-proto.h". Obvisouly, it needs to be relocated in the multiarch include dir too.

