Product SiteDocumentation Site

Chapter 8. Creating RPMs: An Overview

8.1. Preparing to Build RPMs
8.1.1. Planning what you want to build
8.1.2. Gathering the software to package
8.1.3. Creating a reproducible build of the software
8.1.4. Planning for Upgrades
8.1.5. Outlining Any Dependencies
8.2. Building RPMs
8.2.1. Setting up the directory structure
8.2.2. Placing your sources into the directory structure
8.2.3. Creating the spec file
8.2.4. Building RPMs with the rpmbuild command
8.3. Verifying Your RPMS
8.4. Summary
This chapter covers:
Thus far in this book, all the commands presented have been used to manage or query packages. With this chapter, though, you start creating RPMs of your own. Even if you do not produce applications on your own, you may want to create RPM packages out of software you use, if only for the ease of management that the RPM system provides.
Creating RPMs allows you to create a consistent set of applications for use on all systems in your organization and easily manage those applications. You may create RPMs of applications developed in house or RPMs of applications developed elsewhere that you need to customize for your environment. Making RPMs of the customized applications reduces work and makes the customizations consistent.
This chapter introduces the RPM system from the point of view of creating RPMs and demonstrates the steps and planning necessary to make your own packages. As such, this chapter introduces the RPM-building topics covered in depth in the remaining chapters in this part.

Preparing to Build RPMs

The RPM-building task starts with gathering all the material you want to bundle into an RPM package and then defining the RPM directives to make your package. The final steps are to build and test an RPM. This sounds easy, and for the most part it is fairly straightforward.
The main problems arise when you try to define the many RPM directives for your package. In addition, some of the elements in an RPM can be complex, such as upgrade scripts.
The main tasks in building RPMs are:
1.Planning what you want to build
2.Gathering the software to package
3.Patching the software as needed
4.Creating a reproducible build of the software
5.Planning for upgrades
6.Outlining any dependencies
7.Building the RPMs
8.Testing the RPMs
The sections in this chapter cover the initial planning stages and provide an overview of the process of building RPMs. The remaining chapters in Part II go in depth into the process of building RPMs.

Planning what you want to build

The first step in the entire RPM-building process is simply to decide exactly what you want to make into an RPM. Is this an application, a programming library, a set of system configuration files, or a documentation package? If this is an application, is it customized or patched? Think these issues over and decide what you want to package as an RPM.
In most cases, you want to create both a source package and a binary package containing the built sources. You need a binary package because that holds the RPM you want to install on other systems. You need the source package so you can recreate the binary package at any time. And, if the sources get updated, you can quickly make a new binary RPM from the updated sources if you have already defined a source RPM.
Most packages start with a source RPM, although you have the option to skip making a source RPM. It is a good idea to make the source RPM, however, because it makes it easier to reproduce the final binary RPM. Once of the key goals of the RPM system is to allow for reproducible builds, and making source RPMs is just one step to help towards this goal.
Creating a source RPM also allows you to transfer the entire set of sources for a package to another system, since the source RPM is just one file and it contains all the program sources along with the instructions, called a spec file, for building the binary RPM. Furthermore, creating a source RPM makes it easier to create binary RPMs on different processor architectures or different versions of Linux.
Note
Not all programs are portable to multiple-processor architectures. But many Linux programs can simply be recompiled on another architecture to make a binary program for that architecture. That's because there are a lot of common APIs for Linux applications and because most programs are not processor dependent. This is not true of all programs, so your mileage may vary.
Source packages are not that hard to make, and they provide a single package, and single file, that holds all the sources necessary to build your binary package. In addition, once you have a source RPM, it is very easy to build a binary RPM.
Binary packages are likely the real reason you want to make an RPM. You can package an application, a programming library, or almost anything you want. Armed with a binary RPM, you can transfer one file to another machine and install the application there, taking full advantage of the RPM system.

Gathering the software to package

Whether you are writing your own software or merely packaging software found elsewhere, the next step is to gather the software you want to bundle into an RPM. This includes the applications or libraries you want to package, as well as the program source code.
In general, you’ll be doing one of three things:
*Packaging your own software
*Packaging someone else’s software
*Packaging someone else’s stuff after first customizing or patching the software
In all cases, you need to gather the software together and decide whether you want everything to go into one bundle or a number of bundles.
As covered in Chapter 1, Introduction to RPM , a major tenet of the philosophy behind RPM is to start with pristine—unmodified--sources. You may need to patch or customize the sources for your environment, but you can always go back to the original sources.
Starting with pristine sources provides a number of advantages, including the following:
*You clearly separate any changes you have made to the software from the original software.
*You make it easier to get an upgrade of the original sources, since your changes are cleanly separated from the original sources. With each new release of the software, you can determine which of your changes, if any, are still needed. This is especially important if you are packaging an application created by another organization into an RPM.
*You have a reproducible way to recreate everything in the package. Since you start with unmodified sources, you can always go back to the beginning of the process and start again. Thus, your RPMs don’t depend on any actions taken beforehand, such as patching, that you may later forget to do because the steps are not automated as part of the RPM-building process.
Start with pristine sources; then patch as needed. A patch is an automated set of modifications to the source code. Use the diff command to build a patch and the patch command to apply the patch (that is, to modify the source code). Keep the original sources separate from any patches you need to make the software work in your environment.
Cross Reference
See the online manual pages for the patch and diff commands for more information on how to create and apply a patch.

Creating a reproducible build of the software

The RPM system will automate the steps to create an application, as long as you configure the RPM with the proper steps, such as which make targets to run. Unfortunately, configuring the proper steps is not always easy. So before trying to make an RPM, you need to figure out how to build the application or library you plan to package into an RPM. Once you have figured out how to build the application or library, you can set up a reproducible build. The RPM system can then automate this build.
To build the software, you’ll need to use a variety of Linux tools. The specific tools you need depend largely on where the original software came from. The following sections outline some of the more common techniques for preparing and building Linux software.

Unpacking Software

Many applications are downloaded in compressed tar format, often called a tarball. A tarball is merely an archive file built by the tar command that has been compressed, usually using the gzip command.
In most cases, these files have a name such as the following:
filename.tar.gz
filename.tgz
filename.tar.Z
For the first two cases, use the gunzip command to unzip the file; then use the tar command to extract the file, for example:
$ gunzip filename.tgz
$ tar xf filename.tar
Note
In the case of a file name ending in .Z, use the uncompress program instead of gunzip.
Once you have unpacked the sources, start looking around at the files.

Reading the README

Many applications come with a very handy file named README, or something similar, such as README.txt. As the name implies, you should read this file. The README file answers some of the most common questions about a particular application.
Note
You really should read any file named README or any variant of README.
Other useful files include those named INSTALL or some close variant. Read these files, too. Usually, the README or the INSTALL file will tell you what you need to do to build the software.
Once you have extracted the source code files and read all the available documentation, the next step is to build, usually compile, the application or library.

Building Programs with Linux Build Tools

Most applications or libraries need to be built into executable programs or compiled archived libraries. This process of building can be as simple as just compiling, but is usually more involved. Most Linux applications and libraries use a build tool called make to manage the building of the source code and creation of the executable programs. The make command uses a file, normally named Makefile, that contains the rules for building the software. You will usually find a Makefile in each directory in the source code
Each Makefile contains a set of targets that define things that make can build. Each target defines the commands to run to build a particular thing (make targets are purely arbitrary, although some conventions are usually followed). Some combination of the targets results in a built application. The make program runs the targets that you specify on the command line, or the Makefile rules indicate it needs to run based on the targets you specify on the command line.
You need to tell make the target to build the application or library you want to package into an RPM. Each target is defined within the Makefile. The conventional make targets to build and install a program are:
make
make install
When you call the make command without the name of a target, make builds the default target, named all. This target usually compiles the program or library. The install target should install the program.
Note
The names of these make targets are conventions shared by many but not all programs. Other common targets include clean, which should clean up any files built.
The commands in the Makefile may be specific to a given system. For example, the traditional command for compiling C programs is cc, short for C Compiler. You may have the gcc command (GNU C Compiler) instead. The options passed to the C compiler may differ depending on the architecture of the system. Other commands may exist but be located in different locations. SUSE Linux, for example, puts a lot of programs in /opt.
Note
These system-dependent issues mostly apply to various versions of Unix. Most modern Linux systems are fairly similar. Because many packages, such as sendmail, have a long UNIX history, you’ll find all sorts of complications in the Makefiles or many Makefiles provided with many applications. If we could just convince everyone to give up all non-Linux operating systems, this task would be much simpler.
Because the Makefiles are platform specific, a number of tools have been developed to create the proper Makefile, usually by running a program that knows about your system's architecture. The simplest of these tools is the manual approach. You may download a program and find files such as Makefile.amiga, Makefile.solaris, and Makefile.linux. You need to copy the file for your system architecture to the name Makefile.
The following sections discuss other tools for creating Makefiles.

imake

A program called imake is used mostly for X Window graphical applications, and typically older X Window applications. The imake command uses a file named Imakefile that contains rules used to build a platform-specific Makefile. This allows X Window applications, which run on many architectures and operating systems, to come with fairly generic build scripts.
When you see an Imakefile, use the following general set of commands to compileand install an application:
$ xmkmf
$ make
$ make install
These commands work for most X Window applications. The xmkmf command is a script that runs the imake command to create a Makefile. If the xmkmf command is not available or if this command does not work, you may need to run a command such as the following:
make Makefile
Or, if there are multiple directories of source code, try the following command:
make Makefiles
Cross Reference
For more on imake, see www.dubois.ws/software/imake-stuff/.

The configure script

Most Linux programs, especially server-side or command-line programs, use a script called configure. The configure script outputs a platform-specific Makefile.
If you see a script named configure in the source files, try the following commands to build and install the program:
$ ./configure
$ make
$ make install
The ./configure command runs the script in the local directory, which outputs a Makefile configured for your system. The make command builds the program and the make install command installs the program.
The configure script is created by a set of tools including automake and autoconf, which use generic files usually named configure.in and makefile.am, among other files, to create the generic configure script.
In many cases, you’ll need to pass parameters to the configure script. One of the most common parameters is --prefix, which tells the configure script the name of the starting directory from which to base all other paths. This is the root directory for building the application.
Cross Reference
For more on the configure system, autoconf, and automake, see www.airs.com/ian/configure/.

Building Perl modules

Perl is a scripting language used heavily on Linux systems, especially by administrators. Most Perl modules and packages use the following set of commands to create a system-specific Makefile and to build the module:
$ perl Makefile.PL
$ make
$ make test
$ make install
If you see a file named Makefile.PL, chances are these are the commands to run to build the application or module.
The goal of all these steps is to figure out how to make a reproducible build of the application or library you want to package in RPM format. Once you have a build, the next step is to plan for upgrades.

Planning for Upgrades

Any application or library you package in RPM format is likely to get upgraded sometime. When this happens, you’ll need to make a new RPM. This new RPM must handle not only installing the package, but also handling any upgrade issues. You need to think about the following issues:
*How to install the RPM for the new version of the software. Are there any necessary install scripts?
*How to remove the previous RPM package. If your package has an install script, then you may need an uninstall script to cleanly remove any changes made to the system by the install script. The RPM system handles the removal of the files in the package. You need to handle the task of undoing any changes made to the system during installation.
At this point in time, the main effort is to keep these issues in mind and plan ahead, since these issues will come up with any upgrade.

Outlining Any Dependencies

Often, the hardest task is getting make to build a program properly. One potential problem is assuring that all the dependencies are included. As you work with make, keep track of any other libraries that the program you are trying to build requires. These libraries will become dependencies when you get to the stage of making the RPM.
In most cases you do not want to include the dependencies in your RPM. Instead, each dependency should have its own RPM for each necessary library. In many cases, you should be able to find RPMs for these dependencies. Keep track of the packages that provide the dependencies.
After you have built the application, planned for upgrades and outlined dependencies, you can make an RPM.