Multi lib tricks

Architecture independent files

File conflicts

For architecture independent files conflicts should be avoided, so the
files should be identical among arches. It may involve some work with
upstream when header files include architecture specific files, for
example header files which contains autoconf conditionals like
HAVE_INT32.

Another problem that sometimes appears is with gzipped files. Normally gzip will embed the timestamp of the file in its output, and this can cause a multilib conflict. The way to avoid this is to use gzip's '-n' option whenever files are gzipped at build time.

If you are not sure what the reason for a particular conflict is, fetch the packages from two multilibbed architectures (e.g. i386 and x86_64) and unpack them like this:

Then you can use the diff or cmp utilities to discover exactly what is different between the conflicting files.

myautoconf.h files with a size in them

Some packages install myautoconf.h type files which will have something in them relating to the byte size of (size_t) or (void *) at compile time, the possible way to get around this problem is to change from myautoconfig.h to myautoconfig-32.h and myautoconfig-64.h (depending on the platform) and have myautoconfig.h containing just the following on all platforms:

#else
#endif

This kind of API specification is bad in most cases, however, since an API should be completely platform independent.

If what is needed are integer of a length independent from the platform, integers like int32_t from inttypes.h can be used.

Doxygen footers

Doxygen default footers include the date. This leads to conflict since
doc files are not generated at the exact same time. To use a custom
footer without the date, it is possible to modify the dox file used to
drive the documentation generation, and set HTML_FOOTER, for example:

PNG images

PNG images generated for example by doxygen can include the date as part of the PNG format. This leads to conflicts since the *.png files are not generated at the exact same time. To solve this, you can set the internal timestamps of PNG images to a reference timestamp which can be achieved by using the python script png-mtime .

Put this command into your spec file so that it applies to the PNG files where the reference date/file shall be used.

Timestamps

Files should also have the same timestamps. For most of the files this
means taking care to keep the timestamps (which should be done in
every package). For autoconf based packages this is in general achieved
by doing something along:

make install DESTDIR=$RPM_BUILD_ROOT INSTALL="%{__install} -p"

For the architecture independent files generated at build time it is
possible to use the timestamp of a reference file. For example:

touch -r ../cernlib.in src/scripts/cernlib

or

touch -r NEWS $RPM_BUILD_ROOT%{_includedir}/Xbae/patchlevel.h

Multiarch, binaries and compilation scripts

In multilib environments there is a preferred architecture, 64
bit over 32 bit in x86_64, 32 bit over 64 bit in ppc64. When a conflict
is found between two packages corresponding with different arches, the
installed file is the one from the preferred arch. This is very common
for executables in /usr/bin, for example. If the file /usr/bin/foo is
found in an x86_64 package and in an i386 package, the executable
from x86_64 will be installed.

These implicit conflicts are accepted in Fedora, though they are
considered bad by some contributors. There may be some long-term
solution for these issues, but before that there are some tricks
that may allow to avoid those conflicts that are presented below.
Once again they are optional.

In compilation scripts (in general named along mylib-config) it should be advisable to remove -L$libdir when $libdir is the default library directory on this platform. Indeed this is automatically added when linking with the gcc compiler (it may be needed when linking with ld, but using ld is wrong in general, so a user linking with ld should add the flag by himself).

binaries may be put outside of the packages selected to be included in multilib repositories. In general the devel subpackages and their dependencies are included in multilib repositories. A typical split of a package is:

foo for the binaries

foo-libs for the libraries

foo-devel for the development headers, and development symlinks

foo-devel and foo both requires foo-libs, and foo isn't
present in multilib repository.

wrapper scripts may be used to run a binaries based on which one is present. Here is a script example (adapted from firefox)

Another way to handle those conflicts could be to have a different
directory for each architecture, even for executables, enabling
Fedora to be multiarch and not only multilib.

Splitting libraries into separate packages

If you have binaries, libraries, configuration, and data files all in the same package, conflicts can also arise. One way to fix this is to split libraries off into a separate lib<foo> or <foo>-libs package. However, some care must be done when doing this in order to ensure proper upgrades.

For example, if you previously had:

foo-1.1-1

that had binaries, libraries, etc. and had file conflcits, and you split the package into:
into:

foo-1.1-2
foo-libs-1.1-2

you should add:

Obsoletes: foo < 1.1-2

in the %package section for foo-libs. This ensures that an upgrade with yum will remove the older foo for any alternative architecture.

Red Hat, Red Hat Enterprise Linux, the Shadowman logo, and JBoss are trademarks or registered trademarks of
Red Hat, Inc. or its subsidiaries in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.
The Fedora Project is maintained and driven by the community and sponsored by Red Hat. This is a community
maintained site. Red Hat is not responsible for content.