-->
Page 247
Page 248
In this chapter, we will explore one of RPM's more interesting capabilities: the capability to create subpackages.
Very simply put, a subpackage is one of several package files created from a single spec file. RPM has the ability to create a main package, along with one or more subpackages. Subpackages can also be created without the main package. It's all up to the package builder.
If all the software in the world followed the usual "one source, one binary" structure, there would be no need for subpackages. After all, RPM handles the building and packaging of a program into a single package file just fine.
But software doesn't always conform to this simplistic structure. It's not unusual for software to support two or more different modes of operation. A client/server program, for example, comes in two flavors: a client and a server.
And it can get more complicated than that. Sometimes software relies on another program so completely that the two cannot be built separately. The result is often several packages.
Although it is certainly possible that some convoluted procedure could be devised to force these kinds of software into a single-package structure, it makes more sense to let RPM manage the creation of subpackages. Why? From the package builder's viewpoint, the main reason to use subpackages is to eliminate any duplication of effort.
When using subpackages, there's no need to maintain separate spec files and endure the resulting headaches when new versions of the software become available. By keeping everything in one spec file, new software versions can be quickly integrated, and every related subpackage can be rebuilt with a single command.
But that's enough of the preliminaries. Let's see how subpackages are created.
Throughout this chapter, we'll be constructing a spec file that will consist of a number of subpackages. Let's start by listing the spec file's requirements:
Page 249
Every spec file starts with a preamble. In this case, the preamble will contain the following tags:
Name: foo Version: 2.7 Release: 1 Source: foo-2.7.tgz CopyRight: probably not Summary: The foo app, and the baz library needed to build it Group: bogus/junque %description This is the long description of the foo app, and the baz library needed to build it...
As you can see, there's nothing different here: This is an ordinary spec file so far. Let's delve into things a bit more and see what we'll need to add to this spec file to create the subpackages we require.
The creation of subpackages is based strictly on the contents of the spec file. This doesn't mean that you'll have to learn an entirely new set of tags, conditionals, and directives in order to create subpackages, however. In fact, you'll only need to learn one.
The primary change to a spec file is structural and starts with the definition of a preamble for each subpackage.
When we introduced RPM package building in Chapter 10, "The Basics of Developing with RPM," we said that every spec file contains a preamble. The preamble contains a variety of tags that define all sorts of information about the package. In a single-package situation, the preamble must be at the start of the spec file. The spec file we're creating will have one there, too.
When you're creating a spec file that will build subpackages, each subpackage also needs a preamble of its own. These subpreambles need only define information for the subpackage when that information differs from what is defined in the main preamble. For example, if we wanted to define an installation prefix for a subpackage, we would add the appropriate prefix tag to that subpackage's preamble. That subpackage would then be relocatable.
Page 250
In a single-package spec file, nothing explicitly identifies the preamble other than its position at the top of the file. For subpackages, however, we need to be a bit more explicit. So we use the %package directive to identify the preamble for each subpackage.
The %package directive actually performs two functions. As mentioned, it is used to denote the start of a subpackage's preamble. It also plays a role in forming the subpackage's name. For example, let's say the main preamble contains the following name tag:
name: foo
Later in the spec file, there is a %package directive:
%package bar
This would result in the name of the subpackage being foo-bar.
In this way, it's easy to see the relationship of the subpackage to the main package (or to other subpackages, for that matter). Of course, this naming convention might not be appropriate in every case. So there is an option to the %package directive for just this circumstance.
The -n option is used to change the final name of a subpackage from mainpackage-subpackage to subpackage. Let's modify the %package directive in our earlier example to be
%package -n bar
The result is that the subpackage name would be bar instead of foo-bar.
Let's apply some of our newly found knowledge to the spec file we're writing. Here's the list of subpackages we need to create:
Since our package name is foo, and since the %package directive creates subpackage names by prepending the package name, the %package directives for the foo-server and foo-client subpackages would be written as
%package server
and
%package client