include("site.inc"); $template = new Page; $template->initCommon(); $template->displayHeader(); ?>
Most of the package information you need to enter into a spec file fleshes out the information you can query for a given package, such as the name, version, and release information, along with a longer description and a one-line summary.
This gets a little more complicated when you set build locations, name source files, and name patches. The following sections cover how to specify the package information.
The first part of the spec file defines macros (covered in the section "Defining Spec File Macros"), and describes the package. Starting with the basics, you need a name, version, and release. You also should provide a longer description. For legal reasons, you may need to include ownership and copyright information.
The most important part of the package description is the NVR, or Name-Version-Release information, because this information is so crucial for the RPM system to compare versions and track dependencies.
Set the name with the Name: directive. For example:
Name: myapp
The name should not contain any spaces or other whitespace characters such as tabs or newlines. Remember, RPM files are named, by default, name-version-release.rpm, or name-version-release-architecture.rpm, so use valid characters for file names.
The version number is used in version comparisons. The RPM comparison algorithm is fairly complex, but can get fooled by strange version numbers. So, your best bet is to stick to dotted numerics, such as 1.5 or 2.3.1.1.4 or 1.0. Version numbers such as these will compare best from within the RPM system. For example:
Version: 1.1.2
You cannot use a dash in the version number, as RPM uses the dash to separate the Name-Version-Release elements. You can use a dash in the package name, though.
The release number should start at 1 for the first RPM you build for a given version of the package, and count up from there. For example:
Release: 1
The release differentiates newer updates of the RPM itself, even if the underlying application hasn’t changed. (The application may be compiled with different compiler options, though.) For most usage, simply start at 1 and each time you modify the spec file and recreate the package, increment the release number.
If the version number is not enough to allow for comparisons, for example, if the version numbering scheme has changed radically between releases, you can define an Epoch: directive. For example:
Epoch: 3
If you renumber your versions, use an Epoch setting to clarify the version history. For example, Sun Microsystems went from SunOS 4.1 to Solaris 2. The Epoch: helps RPM properly handle strange version number changes. Define the Epoch: as a whole number such as 1, 2, or 3.
Warning
Avoid using the Epoch: directive if at all possible. It is far better to use a sane version-numbering scheme than to try to resolve the mess with epoch values. The main problems with using an epoch value are that epochs are hidden from users in most cases, and using epochs can lead to very strange-looking tasks such as a newer package with a version number that looks older than the older package.
The older Serial: directive also works similarly to the Epoch: directive. For example:
Serial: 6
Like the Epoch:, the Serial: directive should be a number that counts upward. Modern packages should use the Epoch: directive instead of Serial:, since Serial: has been deprecated for many, many rpm versions.
The Group: directive provides a classification for your packages. If at all possible, use a category name that already exists for other packages, such as System Environment/Shells for a Linux shell. For example:
Group: System Environment/Shells
Many graphical installation tools divide packages by these categories, so you want to fit into the existing group names if possible. (See Chapter 5 for more on querying group information from RPMs.) The official list of groups are located in the file /usr/share/doc/rpm-4.1/GROUPS for RPM 4.1, and in a similar location for other RPM versions.
The Distribution: directive is used by Linux distribution vendors such as Red Hat to identify that the package is part of a given distribution, or was built for a particular distribution. Most packages created outside of the Linux vendors don’t provide this directive.
Distribution: Red Hat Linux
The Icon: directive names an icon file stored in the RPM. The file format should be XPM or GIF, with an extension of .xpm or .gif, respectively. Some packaging tools will use this icon in a package display.
For legal reasons, you probably want to specify the organization behind the RPM, any copyright or licensing information, as well as a URL to find out more information. Even if you are not concerned about corporate legal issues, you may want to identify where the package came from. Use the following directives to provide this information.
The Vendor: directive names the company or organization behind an RPM. For example:
Vendor: The Really Cool Company
The URL: directive provides a URL to your company or organization home page, or perhaps to a URL for a particular application. For example:
URL: http://mycompany.yow/products/coolstuff
Similarly, the Packager: directive provides an optional name and e-mail address for the person who created the RPM:
Packager: Bob Marley <marley@reggae.com>
The License: and Copyright: directives provide legal information about your package. Older packages tended to use Copyright: as a statement of the package’s license, not copyright. For example:
Copyright: BSD
License: LGPL
Warning
The Copyright: directive is deprecated in favor of License:.
The Summary: directive provides a one-line short description of the package. You should not exceed much more than 50 characters when writing your summary. For example:
Summary: A program that does exactly what you want
Note
The Summary: directive of the spec file replaces the older Description: directive.
The %description section allows for longer text describing your package. Fill in as many lines as you need after the %description section. For example:
%description
This is a really cool package. It contains the really cool
program that provides a maximum return on investment,
or ROI, for achieving your crucial business objectives
utilizing world-class high-caliber componentized software
implemented with world-class quality and performance
metrics.
The %description section supports a limited amount of formatting. Blank lines are assumed to separate paragraphs. Some graphical user interface installation programs will reformat paragraphs into a nicer-looking font and change the display width.
Lines in the %description section that start with whitespace, such as a space or tab, will be treated as preformatted text and displayed as is, normally with a fixed-width font. The rpm command supports text formatting this way. Other rpm programs may not.
Spec files can announce that a package can run on more than one operating system or is tied to a particular version of a particular operating system.
For example, the Excludearch: directive states that a package should not be built on the given architecture or architectures. For example:
ExcludeArch: sparc s390 s390x
This example excludes the SPARC and S/390 mainframe architectures. You can provide more than one architecture in the directive, separated by spaces or commas.
Similarly, the Exclusivearch: directive states that a package can only be built on the given architecture or architectures. For example:
ExclusiveArch: i386 ia64 alpha
This example identifies the package as only working on the Intel i386, IA-64, and Alpha architectures.
The Excludeos: and Exclusiveos: directives restrict the operating system. For example:
Excludeos: windows
This example states that the package should not be built on Windows. In contrast, the Exclusiveos: directive names only the operating system or systems that the package can be built on. For example:
Exclusiveos: linux
Cross Reference
Chapters 19 and 20 cover RPMs on other versions of Linux and other operating systems, respectively.
RPM supports two build-related directories with very similar names, the build directory and the buildroot.
The build directory is the location where RPM actually builds the software, compiling source code, running the configure script, and so on. Normally, you do not need to worry about the build directory as the rpmbuild command properly changes to this directory as needed.
The buildroot, on the other hand, acts as a staging area that looks like the final installation directory. The name buildroot refers to the fact that the final installation directory is usually the root directory, /. The install section of the spec file (covered in the section "Installing the Software") installs files into the buildroot directory in the proper subdirectories, as if the files were really under the system root directory, /. This allows the buildroot directory to hold all the final installed files for a package, so you can see what will really be installed by the package.
You should always set the buildroot by defining a Buildroot: entry in your spec file. For example:
Buildroot: %{_tmppath}/%{name}-%{version}-root
This example sets the buildroot under the temporary directory named in the %_tmppath macro. The subdirectory is named based on the name and version of the package. For example, for a package named ypbind and a version 1.12, with a %_tmppath value of /tmp, the final buildroot directory would be:
/tmp/ypbind-1.12-root
Once you set a buildroot, your scripts run from the spec file and commands within the spec file can access the buildroot using the RPM_BUILD_ROOT environment variable. You normally need to access the RPM_BUILD_ROOT environment variable in the install section of the spec file (covered in the section "Installing the Software").
Note
You can override the buildroot with the --buildroot command-line parameter to the rpmbuild command.
The buildroot replaces the older, and now obsolete directive, Root:.
Most packages have one or more bundles of source code, which you need to name in the spec file. In most cases, you will have a compressed tar archive of source files. These may be files developed by your organization or downloaded from an Internet site. You can define one or more source tags, counting from 0. For example:
Source0: telnet-client.tar.gz
Source1: telnet-xinetd
Source2: telnet.wmconfig
In this example, Source0: refers to a compressed tar archive. The rpmbuild program will extract the files into the buildroot directory. The Source1: and Source2: directives name individual source files. You can name compressed tar archives or individual files as needed.
If you just have one Source directive, you can skip the 0. For example:
Source: telnet-client.tar.gz
You can also use FTP or HTTP URLs to name sources. For example:
Source0: ftp://ftp.somesite.yow/pub/linux/%{telnet_version}.tar.gz
Note
The URLs listed in source directives are for convenience and future reference only. RPM will not download these files.
The files named by the Source directives will get included into the source RPM. Sometimes you need to keep some sources out of the source RPM. This could be for proprietary sources you cannot ship, or simply due to size. The Nosource: directive tells RPM to skip a source file from the source RPM. For example:
NoSource: 0
This example means that the first source item should not be included in the package.
NoSource: 3
This example means that the third source item should not be included in the package. The NoPatch directive works similarly. In addition, do not place more than one number on any given NoSource or NoPatch directive.
Note
Using the Nosource: or NoPatch: directives, covered following, mean you are creating a source RPM that cannot be rebuilt unless you also have the sources or patches, respectively, that were used to create the original RPM.
If the package contains a Nosource: or Nopatch: directive, rpmbuild will use a file-name extension of .nosrc.rpm instead of .src.rpm.
Patches are named similar to sources, using a similar syntax. For example:
Patch1: telnet-client-cvs.patch
Patch2: telnetd-0.17.diff
Patch3: telnet-0.17-env.patch
Patch4: telnet-0.17-issue.patch
Patch5: telnet-0.17-sa-01-49.patch
Patch6: telnet-0.17-env-5x.patch
Patch10: telnet-0.17-pek.patch
Note that you can have Patch directives are not numbered sequentially, such as the Patch10: directive in this example. In addition, you must apply each patch manually using %patch directives.
The patch files may be individual files or compressed (with gzip) patch files.
Cross Reference
See the patch and diff online manual pages for more on patches.
Patches are important because they allow you to start with pristine sources, the source code for the original application. You can then apply patches as needed to get a working application, more clearly separating the work needed to create an RPM from the original application source code.
Cross Reference
Chapter 14 discusses packaging guidelines and best practices. Starting from pristine sources is one of the best practices.
Similar to the sources directives, you can define a Nopatch: directive, which defines a patch that is applied to the sources, but is not included in the source RPM.