10318N/ABuilding the same code for multiple ISAs
10318N/A
10318N/A
10318N/A1 Introduction
10318N/A
10318N/A Building both 32-bit and 64-bit variants of the same library is now really
10318N/A easy. What's more, adding more ISAs, for example SSE2 is also easy.
10318N/A This document explains how to change a 32-bit only spec file to support
10318N/A multiple ISAs.
10318N/A
10318N/A2 Include files
10318N/A
10318N/A There are a bunch of include files in the include subdirectory that
10318N/A define macros useful for building code for various ISAs:
10318N/A
10318N/A base.inc - default macros, used for building 32-bit binaries
10318N/A automatically included by Solaris.inc, but you can
10318N/A include this to reset macros to the defaults after
10318N/A including one of the other includes below.
10318N/A
10318N/A arch64.inc - macros for building 64-bit binaries: amd64 or sparcv9
10318N/A
10318N/A x86_sse2.inc - macros for building binaries that make use of Intel SSE2
10318N/A extensions.
10318N/A
10318N/A You need to include Solaris.inc before including any of these files.
10318N/A
10318N/A What they do is, they set macros that define the compiler flags:
10318N/A
10318N/A %gcc_optflags - C compiler flags for building with gcc
10318N/A %suncc_optflags - C compiler flags for building with Sun Studio cc
10318N/A %gcc_cxx_optflags - C++ compiler flags for building with g++
10318N/A %suncc_cxx_optflags - C++ compiler flags for building with Sun Studio CC
10318N/A
10318N/A %optflags - C compiler flags for the current C compiler ($CC)
10318N/A %cxx_optflags - C++ compiler flags for the current C++ compiler ($CXX)
10318N/A
10318N/A and update the directory macros for the given architecture:
10318N/A
10318N/A %_bindir - set to %{_prefix}/bin/<ISA specific dir>, e.g. /usr/bin/amd64
10318N/A %_libdir - same with /usr/lib/<ISA>
10318N/A %_libexecdir - same as %_libdir
10318N/A %_pkg_config_path - directory that contains the pkgconfig files for
10318N/A this ISA, e.g. /usr/lib/sparcv9/pkgconfig
10318N/A
10318N/A They also define some handy macros:
10318N/A
10318N/A can_isaexec - 1 if multiple ISAs are built, 0 if only 32-bit
10318N/A If 1, we can use isaexec to automatically run the
10318N/A executable that best matches the current system, see
10318N/A details in "Using isaexec" below.
10318N/A gtk_doc_option - always set to --disable-gtk-doc for non-default
10318N/A ISAs so that we only build the gtk docs for the base ISA.
10318N/A In the case of the base ISA, you can continue to the
10318N/A --without-gtk-doc or --with-gtk-doc to control whether
10318N/A or not to build the gtk-doc API documentation
10318N/A
10318N/A3 Using the ISA specific include files
10318N/A
10318N/A pkgbuild processes the "child" spec files when it reads the %use line.
10318N/A Macros defined in the parent spec file before the %use line are visible
10318N/A in the child spec file, macros defined or redefined after the %use line
10318N/A do not affect the child spec file.
10318N/A
10318N/A This means that changing %{_libdir} to /usr/lib/amd64 using %define
10318N/A before the %use line will cause the libdir of the child spec to be
10318N/A /usr/lib/amd64, if it uses the --libdir=%{_libdir} configure option.
10318N/A We can also control the compiler flags used in the child spec by
10318N/A defining optflags before the %use line and setting CFLAGS="%optflags"
10318N/A in the child spec.
10318N/A
10318N/A So adding a new ISA of a library is as simple as including the
10318N/A appropriate .inc file (which sets up optflags, _libdir, etc.) and then
10318N/A using %use:
10318N/A
10318N/A %include Solaris.inc <- always include before arch64.inc
10318N/A
10318N/A %ifarch amd64 sparcv9
10318N/A %include arch64.inc <- sets %optflags, %_libdir, etc.
10318N/A %use flac_64 = flac.spec <- process the child spec
10318N/A %endif
10318N/A
10318N/A %include base.inc <- reset %optflags, %_libdir, etc.
10318N/A %use flac = flac.spec <- process the child spec again
10318N/A note that we assign a different
10318N/A label from the 64-bit variant
10318N/A
10318N/A Then we add another section for %prep:
10318N/A
10318N/A %prep
10318N/A rm -rf %name-%version
10318N/A mkdir %name-%version
10318N/A
10318N/A %ifarch amd64 sparcv9
10318N/A mkdir %name-%version/%_arch64
10318N/A %flac_64.prep -d %name-%version/%_arch64
10318N/A %endif
10318N/A
10318N/A mkdir %name-%version/%base_arch
10318N/A %flac.prep -d %name-%version/%base_arch
10318N/A
10318N/A The above sets up the following directory structure under
10318N/A %_topdir/BUILD (considering an amd64 platform for this example):
10318N/A
10318N/A .../packages/BUILD
10318N/A |
10318N/A +-----> SUNWflac-1.1.4
10318N/A |
10318N/A +-----> i86
10318N/A | |
10318N/A | +-----> flac-1.1.4
10318N/A |
10318N/A +-----> amd64
10318N/A |
10318N/A +-----> flac-1.1.4
10318N/A
10318N/A Now we need to build both source trees:
10318N/A
10318N/A %build
10318N/A %ifarch amd64 sparcv9
10318N/A %flac_64.build -d %name-%version/%_arch64
10318N/A %endif
10318N/A
10318N/A %flac.build -d %name-%version/%base_arch
10318N/A
10318N/A And then install both trees:
10318N/A
10318N/A %install
10318N/A rm -rf $RPM_BUILD_ROOT
10318N/A
10318N/A %ifarch amd64 sparcv9
10318N/A %flac_64.install -d %name-%version/%_arch64
10318N/A %endif
10318N/A
10318N/A %flac.install -d %name-%version/%base_arch
10318N/A
10318N/A Finally, update %files to include the 64-bit binaries:
10318N/A
10318N/A %ifarch amd64 sparcv9
10318N/A %dir %attr (0755, root, bin) %{_bindir}/%{_arch64}
10318N/A %{_bindir}/%{_arch64}/*
10318N/A %dir %attr (0755, root, bin) %{_libdir}/%{_arch64}
10318N/A %{_libdir}/%{_arch64}/lib*.so*
10318N/A %endif
10318N/A
10318N/A Note that we didn't need to touch base-specs/flac.spec for this.
10318N/A We do need to make sure that:
10318N/A - it sets CFLAGS="%optflags" and LDFLAGS="%{_ldflags}"
10318N/A - it passes at least --libdir=%{_libdir} and --bindir=%{_bindir}
10318N/A to configure (for modules using the GNU autotools)
10318N/A
10318N/A4 Using isaexec
10318N/A
10318N/A There is one more trick we can do: setting up the executables so that
10318N/A the OS will automatically execute the one best suited for the
10318N/A architecture it's running on.
10318N/A
10318N/A To do that, we need to move the base executables into a subdirectory
10318N/A under the bin directory and hard link /usr/lib/isaexec using the name
10318N/A of the executable. isaexec will look for executables with the same
10318N/A name under the ISA-specific subdirectories, in the order printed by
10318N/A isalist, for example:
10318N/A
10318N/A laca@ultra20:~> isalist
10318N/A amd64 pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86
10318N/A
10318N/A I.e. the binary in bin/amd64 will be run if it's found, if not then
10318N/A bin/pentium_pro+mmx, etc. finally i86.
10318N/A
10318N/A In the following example we're moving the 32-bit "flac" binary into the
10318N/A i86 subdir. Note that the 64-bit version is automatically installed
10318N/A in the amd64 subdir, because arch64.inc sets _bindir to
10318N/A %{_prefix}/bin/amd64.
10318N/A
10318N/A This goes into %install:
10318N/A
10318N/A %if %can_isaexec
10318N/A mkdir $RPM_BUILD_ROOT%{_bindir}/%{base_isa}
10318N/A cd $RPM_BUILD_ROOT%{_bindir}
10318N/A mv flac metaflac %{base_isa}
10318N/A ln -s ../../usr/lib/isaexec flac
10318N/A ln -s ../../usr/lib/isaexec metaflac
10318N/A %endif
10318N/A
10318N/A In the %file list, %{_bindir}/flac and %{_bindir}/metaflac must be
10318N/A flagged at hard links using the %hard flag. You need pkgbuild 1.1.2
10318N/A or later for hard links.
10318N/A
10318N/A %hard %{_bindir}/flac
10318N/A %hard %{_bindir}/metaflac