initCommon(); $template->displayHeader(); ?>

9.4. Controlling the Build

After describing information about the package, the crucial step comes when you need to build the package. The spec file should contain all the commands needed to build the application or library you want to package. But, and this is the important part, most of the build process should be run from a Makefile or other conventional way to build applications. Using a build tool such as make means that you can test the application outside of the RPM system. You don’t need an RPM to build the application. Instead, you use the RPM to package the application.

Cross Reference

Chapter 9 covers make and other Linux build tools.

In RPM terms, building the package is split into four steps:

1.Preparing for building, including unpacking the sources

2.Building

3.Installing the application or library

4.Cleaning up

The next sections cover how to control the build run by rpmbuild by defining commands within your spec files.

9.4.1. Preparing for the build

The %prep section defines the commands to prepare for the build. In most cases, you can run the simple %setup macro. For example:

%prep

%setup -q

This command changes to the build directory, typically /usr/src/redhat/BUILD, and then extracts the source files. This macro expects that at least one of the source files will create the necessary subdirectory under /usr/src/redhat/BUILD. This subdirectory should be named with the package name and version, such as telnet-1.0.1. If you are not using a compressed tar archive that will automatically create the right subdirectory, add the –c option to the %setup macro. The –c option creates the subdirectory for extracting the sources.

The –q command-line option runs in quiet mode with minimal output. The –T option disables the automatic extraction of compressed tar files. You can set the name of the build subdirectory with the –n option.

Normally, the %setup macro deletes the subdirectory prior to extracting the sources. You can disable the directory deletion with the –D option.

Table 10-2 summarizes the %setup command-line parameters. Many of these options apply mostly for subpackages, a topic covered in Chapter 11.

Table 10-2 Command-line parameters for %setup

Parameter

Usage

-a number

Only unpack the source directive of the given number, such as –a 0 for source0:, after changing to the directory.

-b number

Only unpack the source directive of the given number, such as –b 0 for source0:, before changing to the directory.

-c

Create directory before unpacking, used if your sources will not create the directory as part of unpacking.

-D

Do not delete the directory before unpacking.

-n name

Name the directory as name.

-q

Run quietly with minimal output.

-T

Disable the automatic unpacking of the archives.

The %setup directive can automatically extract tar, zip, gzip, bzip2, pack, compress, and lzh compressed files. The tar-gzip format is most widely used, though.

Like the %setup macro, the %patch directive applies a patch to the sources. Use this macro in your %prep section if you have patches. You need a %patch directive for each patch.

The %patch directive accepts –p and other command-line parameters for the underlying patch command. The –p option, with a number, such as –p0, tells the patch command to remove that many slashes from the file names within the patch. A –p0 option tells the patch command to remove no slashes, a –p1 option tells patch to remove one slash, and correspondingly, one directory level from the files in the patch. You can also pass other options for the patch command.

Use these options if you need them for the patch command when manually patching the sources. Otherwise, you can set up your %prep section as follows, for a spec file with two patches:

%prep

%setup –q

%patch1

%patch2

Use numbers to identify which patch to apply. For example, %patch0 corresponds to the patch file named with the Patch0: directive.

Note

You must define a separate %patch directive for each patch. In most packages, this format, %patch1, %patch2, and so on, is used.

The %patch directive without a number corresponds to %patch0.

Cross Reference

See the patch and diff online manual pages for more on patches.

In addition to the options supported by the patch command, you can use special options to the %patch directive to control how the directive works. The –P option tells the %patch directive to apply a given patch. For example, to only apply the patch named with the Patch2: directive, use the following %patch directive:

%patch –P 2

Note

This is an uppercase P. The lowercase p performs a different function, described earlier in this section. The -P option is rarely used. Instead, patches are normally applied with %patch0, %patch1, and so on directives.

9.4.2. Building the software

The %prep section prepares for the build, which the %build section performs. You need to fill in the %build section with all the commands necessary to build the software. In most cases, this consists simply of the following commands:

%build

./configure

make

In this case, the %build section runs two commands, ./configure to run the configure script, and make to build the software. For most applications, this may be all you need. You can use the %configure macro in place of the call to the ./configure script. For example:

%build

%configure

make

Most spec files should use the %configure macro, since it automatically sets many environment variables that are often used within the configure script, especially path-related values such as the online manual path, the temporary directory, and so on. You can use the rpm --eval to see how the %configure macro expands. For example:

$ rpm --eval '%configure'

CFLAGS="${CFLAGS:--O2 -march=i386 -mcpu=i686}" ; export CFLAGS ;

CXXFLAGS="${CXXFLAGS:--O2 -march=i386 -mcpu=i686}" ; export CXXFLAGS ;

FFLAGS="${FFLAGS:--O2 -march=i386 -mcpu=i686}" ; export FFLAGS ;

[ -f configure.in ] && libtoolize --copy --force ;

./configure i386-redhat-linux \

--prefix=/usr \

--exec-prefix=/usr \

--bindir=/usr/bin \

--sbindir=/usr/sbin \

--sysconfdir=/etc \

--datadir=/usr/share \

--includedir=/usr/include \

--libdir=/usr/lib \

--libexecdir=/usr/libexec \

--localstatedir=/var \

--sharedstatedir=/usr/com \

--mandir=/usr/share/man \

--infodir=/usr/share/info

Note

The vast majority of the work of building the software should remain in the Makefile where it belongs. The commands in the spec file should invoke the targets defined in the Makefile. Don’t place too much logic in your RPM spec file as this makes it harder to test the application or library you plan to package.

If you intend to support relocatable packages, covered in Chapter 11, you will likely need to pass a --prefix option to the configure script. For example:

%build

./configure --prefix=$RPM_BUILD_ROOT/usr

make

You can also pass other options to the configure script, as needed, for compiling the application.

9.4.3. Installing the software

The %install section should install the software built in the %build section. If your Makefile contains all the instructions to install, you can define an %install section as follows:

%install

make install PREFIX=$RPM_BUILD_ROOT/usr

In most cases, you need to pass some parameter to make or install or another command to install all files into the buildroot directory, as shown in this example with the $RPM_BUILD_ROOT environment variable. You need to look within the Makefile to determine if the make variable should be PREFIX, prefix, or something else.

Sometimes, you want to call the install command instead of make to perform the installation. For example:

%install

install -m755 myapp $RPM_BUILD_ROOT/usr/bin/myapp

This example uses a hypothetical application name of myapp.

Many packages use the %makeinstall macro, which runs the make install command. For example:

%install

rm -rf $RPM_BUILD_ROOT

%makeinstall

This example also cleans the files from the buildroot. Use the rpm --eval command to see how the %makeinstall macro expands. For example:

$ rpm --eval '%makeinstall'

make \

prefix=/usr \

exec_prefix=/usr \

bindir=/usr/bin \

sbindir=/usr/sbin \

sysconfdir=/etc \

datadir=/usr/share \

includedir=/usr/include \

libdir=/usr/lib \

libexecdir=/usr/libexec \

localstatedir=/var \

sharedstatedir=/usr/com \

mandir=/usr/share/man \

infodir=/usr/share/info \

install

Note

RPM 4.2 adds a %check section after the %install.

9.4.4. Cleaning up after the build

The %clean section should clean up after the build and installation, removing compiled files and other files created as part of the build. If you use a buildroot, discussed previously, then you can provide a %clean section like the following:

%clean

rm -rf $RPM_BUILD_ROOT

9.4.5. Defining installation scripts

In addition to the sections described previously for controlling the build of the package software, you can define more scripts in your RPM spec files. RPM supports a script run prior to installation, %pre, and a script run after installation, %post. The same concepts apply when a package is erased, or uninstalled. The %preun script is run just before the uninstall and the %postun script just after the uninstall.

Cross Reference

Chapter 11 covers triggers, another form of script that gets run when packages are installed or removed.

Start your scripts with the RPM section marker for the given script, such as %pre for the pre-install script. Then, place the shell commands you want to run. For example, the following define %post, %preun and %postun scripts from the ypbind networking package:

%post

/sbin/chkconfig --add ypbind

%preun

if [ "$1" = 0 ] ; then

/sbin/service ypbind stop > /dev/null 2>&1

/sbin/chkconfig --del ypbind

fi

exit 0

%postun

if [ "$1" -ge 1 ]; then

/sbin/service ypbind condrestart > /dev/null 2>&1

fi

exit 0

Few packages need to perform any work prior to installation, so the %pre script is rarely used.

In this example, the chkconfig command is called to update the runlevel information for system services after installation and prior to removal. This is an example where just installing the application, ypbind in this case, is not enough. Since this application acts as a system service, more work needs to be done to finish the installation with the %pre script or clean up the service on removal with the %preun script.

Warning

Do not try to write interactive scripts. Many users install RPMs automatically. In such cases, or if the user runs a graphical RPM tool, any information your scripts output will be lost. User input will not be available.

The rpm command will pass one argument to your scripts, shown as $1 in the previous example, which holds a count of the number of versions of the package that are installed. Table 10-3 lists the counts for specific cases.

Table 10-3 Install and uninstall script count values

Action

Count

Install the first time

1

Upgrade

2 or higher (depending on the number of versions installed)

Remove last version of package

0

The previous script example accesses the count using the shell variable $1.

displayFooter('$Date: 2005/11/02 19:30:06 $'); ?>