RPM at Idle

Donnie Barnes

Red Hat, Inc.


Revision History
Revision V3.03 November 1999

Table of Contents
1. Introduction
2. Overview
3. General Information
3.1. Acquiring RPM
3.2. RPM Requirements
4. Using RPM
5. Now what can I really do with RPM?
6. Building RPMs
6.1. The Spec File
6.2. The Header
6.3. Prep
6.4. Build
6.5. Install
6.6. Cleaning your system
6.7. Optional pre and post Install/Uninstall Scripts
6.8. Files
6.9. Changelog
7. Building It
7.1. The Source Directory Tree
7.2. Test Building
7.3. Generating the File List
7.4. Building the Package with RPM
7.5. Testing It
7.6. What to do with your new RPMs
7.7. What Now?
8. Multi-architectural RPM Building
8.1. Sample spec File
8.2. Optflags
8.3. Macros
8.4. Excluding Architectures from Packages
8.5. Finishing Up

1. Introduction

RPM is the RPM Package Manager. It is an open packaging system available for anyone to use. It allows users to take source code for new software and package it into source and binary form such that binaries can be easily installed and tracked and source can be rebuilt easily. It also maintains a database of all packages and their files that can be used for verifying packages and querying for information about files and/or packages.

Red Hat, Inc. encourages other distribution vendors to take the time to look at RPM and use it for their own distributions. RPM is quite flexible and easy to use, though it provides the base for a very extensive system. It is also completely open and available, though we would appreciate bug reports and fixes. Permission is granted to use and distribute RPM royalty free under the GPL.

More complete documentation is available on RPM in the book by Ed Bailey, Maximum RPM. That book is available for download or purchase at www.redhat.com.

2. Overview

First, let me state some of the philosophy behind RPM. One design goal was to allow the use of "pristine" sources. With RPP (our former packaging system of which none of RPM is derived), our source packages were the "hacked" sources that we built from.

Theoretically, one could install a source RPP and then make it with no problems. But the sources were not the original ones, and there was no reference as to what changes we had to make to get it to build. One had to download the pristine sources separately. With RPM, you have the pristine sources along with patches that we used to compile from. We see this as a big advantage. Why? Several reasons. For one, if a new version of a program comes out, you don't necessarily have to start from scratch to get it to compile under RHL. You can look at the patch to see what you might need to do. All the compile-in defaults are easily visible this way.

RPM is also designed to have powerful querying options. You can do searches through your entire database for packages or just certain files. You can also easily find out what package a file belongs to and where it came from. The RPM files themselves are compressed archives, but you can query individual packages easily and quickly because of a custom binary header added to the package with everything you could possibly need to know contained in uncompressed form. This allows for fast querying.

Another powerful feature is the ability to verify packages. If you are worried that you deleted an important file for some package, just verify it. You will be notified of any anomalies. At that point, you can reinstall the package if necessary. Any config files that you had are preserved as well.

We would like to thank the folks from the BOGUS distribution for many of their ideas and concepts that are included in RPM. While RPM was completely written by Red Hat, Inc., its operation is based on code written by BOGUS (PM and PMS).

3. General Information

4. Using RPM

In its simplest form, RPM can be used to install packages:

rpm -i foobar-1.0-1.i386.rpm

The next simplest command is to uninstall a package:

rpm -e foobar

One of the more complex but highly useful commands allows you to install packages via FTP. If you are connected to the net and want to install a new package, all you need to do is specify the file with a valid URL, like so:

rpm -i ftp://ftp.redhat.com/pub/redhat/rh-2.0-beta/RPMS/foobar-1.0-1.i386.rpm

Please note, that RPM will now query and/or install via FTP.

While these are simple commands, rpm can be used in a multitude of ways. To see which options are available in your version of RPM, type:

rpm --help

You can find more details on what those options do in the RPM man page, found by typing:

man rpm

5. Now what can I really do with RPM?

RPM is a very useful tool and, as you can see, has several options. The best way to make sense of them is to look at some examples. I covered simple install/uninstall above, so here are some more examples:

These are just several examples. More creative ones can be thought of really easy once you are familiar with RPM.

6. Building RPMs

Building RPMs is fairly easy to do, especially if you can get the software you are trying to package to build on its own. We assume here that you know how to build software from source. If you don't you probably shouldn't be starting with this document.

The basic procedure to build an RPM is as follows:

Under normal operation, RPM builds both binary and source packages.

6.1. The Spec File

We'll begin with discussion of the spec file. Spec files are required to build a package. The spec file is a description of the software along with instructions on how to build it and a file list for all the binaries that get installed.

You'll want to name your spec file according to a standard convention. It should be the package name-dash-version number-dash-release number-dot-spec. This will ensure that if you install multiple source RPMs for different versions of the same package that at least the spec files remain intact.

Here is a small spec file (eject-2.0.2-1.spec):

Summary: A program that ejects removable media using software control.
Name: eject
Version: 2.0.2
Release: 3
Copyright: GPL
Group: System Environment/Base
Source: http://metalab.unc.edu/pub/Linux/utils/disk-management/eject-2.0.2.tar.gz
Patch: eject-2.0.2-buildroot.patch
BuildRoot: /var/tmp/%{name}-buildroot

The eject program allows the user to eject removable media
(typically CD-ROMs, floppy disks or Iomega Jaz or Zip disks)
using software control. Eject can also control some multi-
disk CD changers and even some devices' auto-eject features.

Install eject if you'd like to eject removable media using
software control.

%setup -q
%patch -p1 -b .buildroot


mkdir -p $RPM_BUILD_ROOT/usr/bin
mkdir -p $RPM_BUILD_ROOT/usr/man/man1

install -s -m 755 eject $RPM_BUILD_ROOT/usr/bin/eject
install -m 644 eject.1 $RPM_BUILD_ROOT/usr/man/man1/eject.1




* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com> 
- auto rebuild in the new build environment (release 3)

* Wed Feb 24 1999 Preston Brown <pbrown@redhat.com> 
- Injected new description and group.

[ Some changelog entries trimmed for brevity.  -Editor. ]

6.2. The Header

The header has some standard fields in it that you need to fill in. There are a few caveats as well. The fields must be filled in as follows:

6.3. Prep

This is the second section in the spec file. It is used to get the sources ready to build. Here you need to do anything necessary to get the sources patched and setup like they need to be setup to do a make.

One thing to note: Each of these sections is really just a place to execute shell scripts. You could simply make an sh script and put it after the %prep tag to unpack and patch your sources. We have made macros to aid in this, however.

The first of these macros is the %setup macro. In its simplest form (no command line options), it simply unpacks the sources and cd's into the source directory. It also takes the following options:

The next of the available macros is the %patch macro. This macro helps automate the process of applying patches to the sources. It takes several options, listed below:

That should be all the macros you need. After you have those right, you can also do any other setup you need to do via sh type scripting. Anything you include up until the %build macro (discussed in the next section) is executed via sh. Look at the example above for the types of things you might want to do here.

6.8. Files

This is the section where you must list the files for the binary package. RPM has no way to know what binaries get installed as a result of make install. There is NO way to do this. Some have suggested doing a find before and after the package install. With a multiuser system, this is unacceptable as other files may be created during a package building process that have nothing to do with the package itself.

There are some macros available to do some special things as well. They are listed and described here:

The biggest caveat in the file list is listing directories. If you list /usr/bin by accident, your binary package will contain every file in /usr/bin on your system.

7. Building It

8. Multi-architectural RPM Building

RPM can now be used to build packages for the Intel i386, the Digital Alpha running Linux, and the Sparc (and others). There are several features that make building packages on all platforms easy. The first of these is the "optflags" directive in the /etc/rpmrc. It can be used to set flags used when building software to architecture specific values. Another feature is the "arch" macros in the spec file. They can be used to do different things depending on the architecture you are building on. Another feature is the "Exclude" directive in the header.

8.1. Sample spec File

The following is part of the spec file for the "fileutils" package. It is setup to build on both the Alpha and the Intel.

Summary: GNU File Utilities
Name: fileutils
Version: 3.16
Release: 1
Copyright: GPL
Group: Utilities/File
Source0: prep.ai.mit.edu:/pub/gnu/fileutils-3.16.tar.gz
Patch: fileutils-3.16-mktime.patch

These are the GNU file management utilities.  It includes programs
to copy, move, list, etc, files.

The ls program in this package now incorporates color ls!


%ifarch alpha
%patch -p1
configure --prefix=/usr --exec-prefix=/

rm -f /usr/info/fileutils*
make install
gzip -9nf /usr/info/fileutils*