include("site.inc"); $template = new Page; $template->initCommon(); $template->displayHeader(); ?>
In previous chapters, just about everything you want to do with RPMs is accomplished with the rpm command. Building RPMs is one exception. Just about everything you want to do to build an RPM is done by the rpmbuild command, often with a single command.
Warning
Older RPM manuals refer to using the –b option to the rpm command to create RPMs. Don’t use that option. Instead, always use the rpmbuild command. The reason for this change is that starting with version 4.1, RPM no longer maps the rpm -b command to the real command, rpmbuild.
When building RPMs, go through the following steps:
1.Set up the directory structure.
2.Place the sources in the right directory.
3.Create a spec file that tells the rpmbuild command what to do.
4.Build the source and binary RPMs.
The following sections provide details for these steps.
The RPM system expects five directories, as listed in Table 9-1.
Table 9-1 RPM directories
Directory | Usage |
BUILD | The rpmbuild command builds software in this directory. |
RPMS | The rpmbuild command stores binary RPMs it creates in this directory. |
SOURCES | You should put the sources for the application in this directory. |
SPECS | You should place the spec file for each RPM you plan to make in this directory. |
SRPMS | The rpmbuild command places source RPMs in this directory. |
The RPMS directory usually has a number of architecture-specific subdirectories, such as the following (on an Intel architecture system):
$ ls RPMS
athlon
i386
i486
i586
i686
noarch
By default, Red Hat Linux systems expect RPMs to be built in the /usr/src/redhat directory.
Note
This directory is obviously specific to Red Hat Linux. On other Linux distributions, you'll likely see other directories.
Within the /usr/src/redhat directory, you’ll see the subdirectories listed in Table 9-1, as follows:
$ ls /usr/src/redhat
BUILD
RPMS
SOURCES
SPECS
SRPMS
At first, it seems rather odd to be using a system directory to build RPMs. But remember that the RPM system was originally built to create Linux distributions. You can also change the default directories by modifying your rpmrc settings.
Cross Reference
See Chapter 21 for more on the use of the rpmrc settings.
For now, it is easiest to just change to the /usr/src/redhat directory and work from this location. To start, you will need to change ownership or permissions on these files so you can build RPMs while logged in as a normal user.
Warning
Do not build RPMs while logged in as root. Mistakes in building packages can have serious consequences if you are logged in as root.
To build RPMs, you really need only two things:
*Your sources in the SOURCES directory
*Your spec file in the SPECS directory
You can place all the source files directly in the /usr/src/redhat/SOURCES directory. In most cases, however, it is easier to create a tarball of the sources you want to build and place the tarball file in the /usr/src/redhat/SOURCES directory. The RPM specifications for commands necessary to extract the sources from such a file are trivial. Furthermore, the tarball, when extracted, should create a subdirectory specific to your package. This keeps your source code separate from other packages that also have source code in the SOURCES directory.
The best strategy is to start in a directory of your own making, create the tarball file from the sources, and then copy the tarball file to the /usr/src/redhat/SOURCES directory.
The convention for these tarball files is package-version.tar.gz. For example:
jikes-1.17.tar.gz
Place a file like this into the /usr/src/redhat/SOURCES directory. This file should include all the sources, all the build scripts, and any documentation you want to install as part of the package.
The spec file, short for specification file, defines all the actions the rpmbuild command should take to build your application, as well as all the actions necessary for the rpm command to install and remove the application. Each source RPM should have the necessary spec file for building a binary RPM.
The spec file is a text file. The normal naming convention is to name the file with the package name and a .spec filename extension. For example, the jikes package spec file would be named jikes.spec.
Inside the spec file, format the information on the package using a special syntax. This syntax defines how to build the package, version numbers, dependency information, and everything else you can query about a package. This syntax differs slightly depending on the sections in the spec file. The following sections describe these spec file sections and the necessary syntax in each section.
The introduction section contains information about the package, the type of information shown with the rpm -qi command. For example:
Summary: java source to bytecode compiler
%define version 1.17
Copyright: IBM Public License, http://ibm.com/developerworks/oss/license10.html
Group: Development/Languages
Name: jikes
Prefix: /usr
Provides: jikes
Release: 1
Source: jikes-%{version}.tar.gz
URL: http://ibm.com/developerworks/opensource/jikes
Version: %{version}
Buildroot: /tmp/jikesrpm
%description
The IBM Jikes compiler translates Java source files to bytecode. It
also supports incremental compilation and automatic makefile generation,
and is maintained by the Jikes Project:
http://ibm.com/developerworks/opensource/jikes/
In this example, you can see the Source: definition of a compressed tar archive associated with a particular version number. This also names a Buildroot: setting that defines where the files will get built into a working program. You can see the description of the package that will get printed with the rpm –qi command.
Note
You can further divide this first section into the preamble and other areas. For simplicity, I grouped all introductary parts of a spec file into one introduction section.
This example comes from a real-world RPM spec file. It does not follow all the rules for creating RPMs. This example:
*Should not explicitly provide jikes, the name of the package.
*Should not include a Copyright tag, as this tag is deprecated.
*Uses a %define for the version when the rpmbuild command can create a version macro for you.
The prep section, short for prepare, defines the commands necessary to prepare for the build. If you are starting with a compressed tar archive (a tarball) of the sources, the prep section needs to extract the sources.
For example:
%prep
%setup -q
The prep section starts with a %prep statement.
This example uses the %setup RPM macro, which knows about tar archives, to extract the files. In most cases, this will be all you need in your spec file prep section.
The spec file build section contains the commands to build the software. Usually, this will include just a few commands, since most of the real instructions appear in the Makefile. For example:
%build
./configure CXXFLAGS=-O3 --prefix=$RPM_BUILD_ROOT/usr
make
The build section starts with a %build statement.
The commands shown for this build section run the configure script, covered in the previous section on Linux build tools, and then run the make command with the default maketarget. If things unfold as they should, this procedure builds the software.
The spec file install section holds the commands necessary to install the newly built application or library. In most cases, your install section should clean out the Buildroot directory and run the make install command. For example:
%install
rm -fr $RPM_BUILD_ROOT
make install
The install section starts with an %install statement.
The clean section cleans up the files that the commands in the other sections create:
%clean
rm -rf $RPM_BUILD_ROOT
The clean section starts with a %clean statement
Finally, the files section lists the files to go into the binary RPM, along with the defined file attributes. For example:
%files
%defattr(-,root,root)
/usr/bin/jikes
%doc /usr/doc/jikes-%{version}/license.htm
%doc /usr/man/man1/jikes.1*
The files section starts with a %files statement
The %doc macro marks certain files as documentation. This allows the RPM to distinguish the files holding documentation from the other files in the RPM.
Cross Reference
This example skips the install and uninstall script sections, as well as a verification section. There are also no triggers defined in this RPM spec file. All of these topics are covered in Chapters 10 and 11.
Once you have written your spec file, and placed the files in the SOURCES and SPECS directories under /usr/src/redhat, you’ll see files like the following:
$ ls –CF /usr/src/redhat/*
/usr/src/redhat/BUILD:
/usr/src/redhat/RPMS:
athlon/ i386/ i486/ i586/ i686/ noarch/
/usr/src/redhat/SOURCES:
jikes-1.17.tar.gz
/usr/src/redhat/SPECS:
jikes.spec
/usr/src/redhat/SRPMS:
That is, with a clean system and no other RPMs being built, you'll see a spec file in /usr/src/redhat/SPECS and the sources in /usr/src/redhat/SOURCES. In this example, the sources are in a compressed tar archive. (For this, the RPM spec file, jikes.spec needs to have a command in the prep section to extract the files.)
You should now be ready to build an RPM.
To build RPMs with the rpmbuild command, use the following basic syntax:
rpmbuild -bBuildStage spec_file
The -b option tells rpmbuild to build an RPM. The extra BuildStage option is a special code that tells the rpmbuild command how far to go when building. Table 9-2 lists these options:
Table 9-2 Options for building with rpmbuild
Option | Usage |
-ba | Build all, both a binary and source RPM |
-bb | Build a binary RPM |
-bc | Build (compile) the program but do not make the full RPM, stopping just after the %build section |
-bp | Prepare for building a binary RPM, and stop just after the %prep section |
-bi | Create a binary RPM and stop just after the %install section |
-bl | Check the listing of files for the RPM and generate errors if the buildroot is missing any of the files to be installed |
-bs | Build a source RPM only |
Note
See chapter 12 for advanced options you can use with rpmbuild.
For example, to set up all the necessary files and prepare for building, run the following command:
rpmbuild –bp specfile
This example runs through the %prep section, and stops immediately after this section. With the jikes package, for example, you’ll see a result like the following:
$ rpmbuild -bp /usr/src/redhat/SPECS/jikes.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.72435
+ umask 022
+ cd /usr/src/redhat/BUILD
+ LANG=C
+ export LANG
+ cd /usr/src/redhat/BUILD
+ rm -rf jikes-1.17
+ /usr/bin/gzip -dc /usr/src/redhat/SOURCES/jikes-1.17.tar.gz
+ tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd jikes-1.17
++ /usr/bin/id -u
+ '[' 500 = 0 ']'
++ /usr/bin/id -u
+ '[' 500 = 0 ']'
+ /bin/chmod -Rf a+rX,g-w,o-w .
+ exit 0
After running this command, the source files are extracted into the /usr/src/redhat/BUILD directory, under the jikes-1.17 subdirectory. Using a subdirectory keeps the sources for this package from intermixing with the sources for other packages.
Running a directory listing on the /usr/src/redhat/BUILD/jikes-1.17 subdirectory shows what the spec file %prep section commands have done. For example:
$ ls -1 /usr/src/redhat/BUILD/jikes-1.17
acinclude.m4
aclocal.m4
AUTHORS
ChangeLog
config.guess
config.sub
configure
configure.in
COPYING
depcomp
doc
INSTALL
install-sh
jikes.spec
Makefile.am
Makefile.in
missing
mkinstalldirs
NEWS
README
src
TODO
Note
From these sources, you see a configure script. The configure script gives a good indication of how the software needs to be built. This example also shows a README file. You know what to do with these files.
The actual source code is in the /usr/src/redhat/BUILD/jikes-1.17/src directory. The user documentation is stored in the /usr/src/redhat/BUILD/jikes-1.17/doc directory.
To build a binary RPM, use the –bb option to the rpmbuild command. For example:
$ rpmbuild -bb /usr/src/redhat/SPECS/jikes.spec
Warning
Don’t build packages when you are logged in as the root user. Log in as a normal user instead. This is to limit the damage caused to your system if the spec file or the Makefile contains errors that delete system files, for example. If you are logged in as the root user, you will have permission to perform these destructive acts. If you are logged in as a normal user, though, these RPM spec file and Makefile errors will fail to run, because you don’t have permission to modify system files.
This command results in a lot of output, most coming from the configure script. (This script examines the C programming environment on your system.) When the rpmbuild command completes, you’ll see the binary RPM in the proper subdirectory of the RPMS directory. You can see the RPM with a directory listing, for example:
$ls /usr/src/redhat/RPMS/i386:
jikes-1.17-1.i386.rpm
To stop execution just after the %install section, use a command like the following:
rpmbuild –bi specfile
For example:
# rpmbuild -bi /usr/src/redhat/SPECS/jikes.spec
To build a source RPM out of the files you have (in this case a tar archive of the sources and the spec file), use a command like the following:
rpmbuild –bs specfile
For example:
$ rpmbuild -bs /usr/src/redhat/SPECS/jikes.spec
When done, you’ll see the source RPM in the /usr/src/redhat/SRPMS directory:
$ ls /usr/src/redhat/SRPMS
jikes-1.17-1.src.rpm
To clean out the files created by building these RPMs, use the --clean option to the rpmbuild command:
rpmbuild --clean specfile
For example:
$ rpmbuild --clean /usr/src/redhat/SPECS/jikes.spec
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.21908
+ umask 022
+ cd /usr/src/redhat/BUILD
+ rm -rf jikes-1.17
+ exit 0
Cross Reference
Chapter 12 covers a number of addition options for the rpmbuild command that you can use to customize the build.