Wednesday, March 5, 2008

Beginning Your Spec File For Building Linux RPM's.

Hello Again,

This is a continuation of yesterdays post on doing the initial build of your software as the first step toward creating your own Linux RPM. Today we're going to continue on that path with our software package (cleverly named PACKAGE-3.2-1 ;) and move on to the next step in the RPM creation process; the creation of the specification file (which I'll refer to as the "spec file" from here on out) and its basic structure.

For the purposes of our example, we won't be including every single option you can include in a spec file, but we'll touch on all the required ones, and a few that might make your life a bit easier :)

We'll create our spec file by simply opening it up as a new file in our favorite editor. The spec file is simply a plain text file, describing our RPM's attributes, that we'll be supplying to the "rpmbuild" command later on. We'll look at the spec file, line by line, for our soon-to-be-completed package. We'll call it PACKAGE.spec

The first section is what I like to call the "header section," although I don't know that it's ever actually referred to as that. It looks like the following

Summary: The World Famous PACKAGE software
Version: 3.2
Release: 1
Copyright: Gnu Public License
Group: Applications
Source0: PACKAGE-3.2-1.tar.gz
Prefix: /usr/local
Provides: PACKAGE3, PACKAGE-devel, bunk
Requires: PACKAGE1, db
Packager: Mike Tremell
# %define _topdir /users/me/softbuilds/rpm
PACKAGE 3.2-1 Standard Build
%define PACKAGEDIR %{prefix}

The lines in this section are defined as follows:

Summary - This line should be a descriptive summary of your RPM package, in short form. It shouldn't be too wordy, but you can make it as long as you want.

Name - This is simply the name of your package. It must match the source package's name (which we created in /usr/src/packages/SOURCES/ in yesterday's post on setting up the initial build for your RPM. It will later be used (with the Version and Release keyword values appended) by rpmbuild to determine what source file it should look for in /usr/src/packages/SOURCES

Version - The version of your software. Again this must be exactly the same version of the source package you're building from.

Release - The release of the software. This, again, must be exactly the same as the release you're building from. Using the "Name," "Version," and "Release" variables, rpmbuild will surmise that we want to build our RPM from PACKAGE-3.2-1.tar.gz in /usr/src/packages/SOURCES. Note: The Release variable is required and (for whatever reason) cannot be an empty value. Thus we put in the obligatory 1 for our new build of the generic PACKAGE software. Whatever you're building will probably have a release number.

Copyright - Just attribution for the package and/or package source's author(s)

Group - This identifies our package as belonging to the "Applications" package group in Linux.

Source0 - The name (Yes, this is redundant ;) of the source package in /usr/src/packages/SOURCES. As the name implies, you can have more than one source in certain circumstances. Note that there is also a "Patch0," etc, declaration that you can use to specify diff files you may need to include, but that's beyond the scope of our exercise.

Prefix - The root under which the RPM will install itself. Note: You need to include the Prefix declaration if you want your RPM package to be "relocatable." If your package is not relocatable, all installs will always install to the same place. If your package is relocatable, it allows the user or administrator to change the prefix, or root install directory, of the RPM when they run the "rpm" command to install it!

Provides - What your RPM will "provide" once it is installed. This is mainly for rpm's dependency checking. You can have your package provide anything, but it's best to have it provide only useful values. This variable isn't necessary if your software package isn't providing anything significant and/or doesn't have another package that's dependant on it.

Requires - The RPM packages your RPM package needs to have installed on your system before it will install correctly. In our example, PACKAGE will not install correctly (it will fail the dependency check) if some version of the "db" (Berkeley Database) RPM isn't already installed on our system.

URL - The location where a user can download the latest version of the RPM source. Not necessary, but can be helpful.

Packager - The name of the guy (or gal) who put together the RPM. Again, not necessary unless you're seeking notoriety ;)

# %define _topdir /users/me/softbuilds/rpm - Note that this line is commented out for our build, since we're going with the system defaults. However, comments in spec files work just like comments in shell scripts, so if you wanted to change the top level directory for your RPM structure, you could do it by redefining the _topdir variable (In this case, simply by removing the comment). You may need to create its required BUILD, BUILDROOT, RPMS, SOURCES, SPECS and SRPMS subdirectories manually. This option is useful if you're trying to do a build as a regular user and don't have the system privilege that will allow you to manipulate your server's main RPM package working directories :)

%description - Just like the summary above, but should be more descriptive. Also, you should add your description on a new line following the %description declaration (unlike all the others). "rpmbuild" will spew error messages if you put your description's value on the same line as the variable. You can actually include "one" word on the same line as the %description variable, but the rest of your description must be below that line. It should also be noted that you can have multiple %description declarations, which is useful if you're building multiple RPM's from one spec file (although that's deeper than we want to go for now).

%define - This directive can be used over and over again. It's simple format is: %define variable_name value. You can call the variable name you define here using the %{} notation. For instance:

%define mydir /usr/local/bin

Would allow you to reference /usr/local/bin, at any point (from the point of definition on) in your spec file as %{mydir}

Tomorrow, we'll check out the next, and final section of the RPM spec file and use "rpmbuild" to create our RPM package!


, Mike