14. Multiple platform builds

A specfile's build header may contain a BuildArch: line with more than one architecture. When that happens, lpbuild processes the package declarations, the build scripts, and the file manifest sections, more than once. lpbuild sets the %__arch macro to the first listed architecture, then processes the package declarations, runs the build scripts, reads the file manifest sections, and creates the package files. lpbuild then sets the %__arch macro to the second architecture, and does everything again. If there are more than two architectures, the remaining ones are processed accordingly.

Conditional text inclusion is often used when building multiple architectures, to create different subpackages for each architecture. Consider the following specfile:

Name: testpackage     # Package name.
Version: 1
Release: 1
Source: test-1.tar.gz
BuildArch: %{__platform} noarch

%package

This is the main package
%package doc
This is the documentation package.

%begin

%setup

%begin compile

%if %{!=__arch: noarch}
make
%endif

%begin install

%if %{!=__arch: noarch}
make install DESTDIR="$__installdir"
%endif

# End of the build script

%if %{!=__arch: noarch}

%files

%{_bindir}/*

%else

%files doc

%doc README INSTALL ...

%endif

The first pass over this specfile sets %__arch to i386 (if this package gets built on an Intel 32-bit platform). This specfile has two package declarations, the main package and the doc subpackage. On the first pass, however, only the main package's file manifest gets conditionally included and processed, creating testpackage-1-1.i386.lp. lpbuild creates a package file only if it reads the package's file manifest. Even though the doc subpackage is declared, its manifest is not conditionally read on the first pass.

On the second pass the sets %__arch is set to noarch, so the doc subpackage's file manifest is processed, creating testpackage-doc-1-1.noarch.lp.

The end result is that lpbuild creates the following packages: testpackage-1-1.i386.lp and testpackage-doc-1-1.noarch.lp. If conditional text inclusion was not used, lpbuild would've created testpackage-1-1.i386.lp, testpackage-doc-1-1.i386.lp, testpackage-1-1.noarch.lp and testpackage-doc-1-1.noarch.lp.

Note

The conditionally-included text in the %begin scripts needs additional explaining. On the second pass lpbuild processes only the subpackage's manifest, that references only the documentation files. Nothing is actually expected to be present in the installation image directory.

Each pass starts with an empty source and installation image temporary directories, and the %setup macro, described in Section 13.4, “Predefined macros”, unpacks the source. If the specfile also runs make install on the second pass, the installation image directory would also contain the installed application files. This will be reported as an error, because those files would not be declared in any package's file manifest.

Multiple platform builds do not generally require conditional text inclusion in the package declaration section. To select which packages and subpackages should be built for a particular architecture, conditionally include the appropriate file manifests. Conditional text inclusion in the package declaration section poses additional complications.

The first %package line normally terminates the build header portion of the specfile. If an %if precedes the first %package line, lpbuild will be in the middle of conditionally-included text when it stops processing the build header. This is not allowed. Recall that lpbuild makes a pass over the package declaration section, the build scripts, and the file manifest sections for each build architecture. After finishing the first pass, lpbuild can't exactly rewind back, and jump in the middle of conditionally-included text and begin the second pass, for the second build architecture.

This is true even if the specfile specifies only a single build platform. Conditionally-included text should be avoided in the package declaration section. If it is absolutely necessary to begin the package declaration section with conditionally-included text, insert a line that contains only %%. lpbuild explicitly terminates processing the build header section when it reads a line that contains %%.