860 lines
43 KiB
Plaintext
860 lines
43 KiB
Plaintext
RPM HOWTO
|
||
|
||
RPM at Idle
|
||
|
||
Donnie Barnes
|
||
|
||
Red Hat, Inc.
|
||
|
||
djb@redhat.com
|
||
|
||
|
||
Copyright © 1999 by Red Hat, Inc.
|
||
Revision History
|
||
Revision V3.0 3 November 1999
|
||
|
||
|
||
This document and its contents are copyright protected. Redistribution of
|
||
this document is permitted as long as the content remains completely intact
|
||
and unchanged. In other words, you may reformat and reprint or redistribute
|
||
only.
|
||
|
||
-----------------------------------------------------------------------------
|
||
Table of Contents
|
||
1. Introduction
|
||
2. Overview
|
||
3. General Information
|
||
3.1. Acquiring RPM
|
||
3.2. RPM Requirements
|
||
|
||
|
||
4. Using RPM
|
||
5. Now what can I really do with RPM?
|
||
6. Building RPMs
|
||
6.1. The Spec File
|
||
6.2. The Header
|
||
6.3. Prep
|
||
6.4. Build
|
||
6.5. Install
|
||
6.6. Cleaning your system
|
||
6.7. Optional pre and post Install/Uninstall Scripts
|
||
6.8. Files
|
||
6.9. Changelog
|
||
|
||
|
||
7. Building It
|
||
7.1. The Source Directory Tree
|
||
7.2. Test Building
|
||
7.3. Generating the File List
|
||
7.4. Building the Package with RPM
|
||
7.5. Testing It
|
||
7.6. What to do with your new RPMs
|
||
7.7. What Now?
|
||
|
||
|
||
8. Multi-architectural RPM Building
|
||
8.1. Sample spec File
|
||
8.2. Optflags
|
||
8.3. Macros
|
||
8.4. Excluding Architectures from Packages
|
||
8.5. Finishing Up
|
||
|
||
|
||
|
||
1. Introduction
|
||
|
||
RPM is the RPM Package Manager. It is an open packaging system available for
|
||
anyone to use. It allows users to take source code for new software and
|
||
package it into source and binary form such that binaries can be easily
|
||
installed and tracked and source can be rebuilt easily. It also maintains a
|
||
database of all packages and their files that can be used for verifying
|
||
packages and querying for information about files and/or packages.
|
||
|
||
Red Hat, Inc. encourages other distribution vendors to take the time to look
|
||
at RPM and use it for their own distributions. RPM is quite flexible and easy
|
||
to use, though it provides the base for a very extensive system. It is also
|
||
completely open and available, though we would appreciate bug reports and
|
||
fixes. Permission is granted to use and distribute RPM royalty free under the
|
||
GPL.
|
||
|
||
More complete documentation is available on RPM in the book by Ed Bailey,
|
||
Maximum RPM. That book is available for download or purchase at [http://
|
||
www.redhat.com] www.redhat.com.
|
||
-----------------------------------------------------------------------------
|
||
|
||
2. Overview
|
||
|
||
First, let me state some of the philosophy behind RPM. One design goal was to
|
||
allow the use of "pristine" sources. With RPP (our former packaging system of
|
||
which none of RPM is derived), our source packages were the "hacked" sources
|
||
that we built from.
|
||
|
||
Theoretically, one could install a source RPP and then make it with no
|
||
problems. But the sources were not the original ones, and there was no
|
||
reference as to what changes we had to make to get it to build. One had to
|
||
download the pristine sources separately. With RPM, you have the pristine
|
||
sources along with patches that we used to compile from. We see this as a big
|
||
advantage. Why? Several reasons. For one, if a new version of a program comes
|
||
out, you don't necessarily have to start from scratch to get it to compile
|
||
under RHL. You can look at the patch to see what you might need to do. All
|
||
the compile-in defaults are easily visible this way.
|
||
|
||
RPM is also designed to have powerful querying options. You can do searches
|
||
through your entire database for packages or just certain files. You can also
|
||
easily find out what package a file belongs to and where it came from. The
|
||
RPM files themselves are compressed archives, but you can query individual
|
||
packages easily and quickly because of a custom binary header added to the
|
||
package with everything you could possibly need to know contained in
|
||
uncompressed form. This allows for fast querying.
|
||
|
||
Another powerful feature is the ability to verify packages. If you are
|
||
worried that you deleted an important file for some package, just verify it.
|
||
You will be notified of any anomalies. At that point, you can reinstall the
|
||
package if necessary. Any config files that you had are preserved as well.
|
||
|
||
We would like to thank the folks from the BOGUS distribution for many of
|
||
their ideas and concepts that are included in RPM. While RPM was completely
|
||
written by Red Hat, Inc., its operation is based on code written by BOGUS (PM
|
||
and PMS).
|
||
-----------------------------------------------------------------------------
|
||
|
||
3. General Information
|
||
|
||
3.1. Acquiring RPM
|
||
|
||
The best way to get RPM is to install Red Hat Linux. If you don't want to do
|
||
that, you can still get and use RPM. It can be acquired from [ftp://
|
||
ftp.redhat.com/pub/redhat/code/rpm] ftp.redhat.com.
|
||
-----------------------------------------------------------------------------
|
||
|
||
3.2. RPM Requirements
|
||
|
||
RPM itself should build on basically any Unix-like system. It has been built
|
||
and used on Tru64 Unix, AIX, Solaris, SunOS, and basically all flavors of
|
||
Linux.
|
||
|
||
To build RPMs from source, you also need everything normally required to
|
||
build a package, like gcc, make, etc.
|
||
-----------------------------------------------------------------------------
|
||
|
||
4. Using RPM
|
||
|
||
In its simplest form, RPM can be used to install packages:
|
||
rpm -i foobar-1.0-1.i386.rpm
|
||
|
||
|
||
The next simplest command is to uninstall a package:
|
||
rpm -e foobar
|
||
|
||
|
||
One of the more complex but highly useful commands allows you to install
|
||
packages via FTP. If you are connected to the net and want to install a new
|
||
package, all you need to do is specify the file with a valid URL, like so:
|
||
rpm -i ftp://ftp.redhat.com/pub/redhat/rh-2.0-beta/RPMS/foobar-1.0-1.i386.rpm
|
||
|
||
|
||
Please note, that RPM will now query and/or install via FTP.
|
||
|
||
While these are simple commands, rpm can be used in a multitude of ways. To
|
||
see which options are available in your version of RPM, type:
|
||
rpm --help
|
||
|
||
|
||
You can find more details on what those options do in the RPM man page, found
|
||
by typing:
|
||
man rpm
|
||
|
||
-----------------------------------------------------------------------------
|
||
|
||
5. Now what can I really do with RPM?
|
||
|
||
RPM is a very useful tool and, as you can see, has several options. The best
|
||
way to make sense of them is to look at some examples. I covered simple
|
||
install/uninstall above, so here are some more examples:
|
||
|
||
* Let's say you delete some files by accident, but you aren't sure what you
|
||
deleted. If you want to verify your entire system and see what might be
|
||
missing, you would do:
|
||
rpm -Va
|
||
|
||
|
||
* Let's say you run across a file that you don't recognize. To find out
|
||
which package owns it, you would do:
|
||
rpm -qf /usr/X11R6/bin/xjewel
|
||
|
||
|
||
The output would be sometime like:
|
||
xjewel-1.6-1
|
||
|
||
|
||
* You find a new koules RPM, but you don't know what it is. To find out
|
||
some information on it, do:
|
||
rpm -qpi koules-1.2-2.i386.rpm
|
||
|
||
|
||
The output would be:
|
||
Name : koules Distribution: Red Hat Linux Colgate
|
||
Version : 1.2 Vendor: Red Hat Software
|
||
Release : 2 Build Date: Mon Sep 02 11:59:12 1996
|
||
Install date: (none) Build Host: porky.redhat.com
|
||
Group : Games Source RPM: koules-1.2-2.src.rpm
|
||
Size : 614939
|
||
Summary : SVGAlib action game with multiplayer, network, and sound support
|
||
Description :
|
||
This arcade-style game is novel in conception and excellent in execution.
|
||
No shooting, no blood, no guts, no gore. The play is simple, but you
|
||
still must develop skill to play. This version uses SVGAlib to
|
||
run on a graphics console.
|
||
|
||
|
||
* Now you want to see what files the koules RPM installs. You would do:
|
||
rpm -qpl koules-1.2-2.i386.rpm
|
||
|
||
|
||
The output is:
|
||
/usr/doc/koules
|
||
/usr/doc/koules/ANNOUNCE
|
||
/usr/doc/koules/BUGS
|
||
/usr/doc/koules/COMPILE.OS2
|
||
/usr/doc/koules/COPYING
|
||
/usr/doc/koules/Card
|
||
/usr/doc/koules/ChangeLog
|
||
/usr/doc/koules/INSTALLATION
|
||
/usr/doc/koules/Icon.xpm
|
||
/usr/doc/koules/Icon2.xpm
|
||
/usr/doc/koules/Koules.FAQ
|
||
/usr/doc/koules/Koules.xpm
|
||
/usr/doc/koules/README
|
||
/usr/doc/koules/TODO
|
||
/usr/games/koules
|
||
/usr/games/koules.svga
|
||
/usr/games/koules.tcl
|
||
/usr/man/man6/koules.svga.6
|
||
|
||
|
||
|
||
These are just several examples. More creative ones can be thought of really
|
||
easy once you are familiar with RPM.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6. Building RPMs
|
||
|
||
Building RPMs is fairly easy to do, especially if you can get the software
|
||
you are trying to package to build on its own. We assume here that you know
|
||
how to build software from source. If you don't you probably shouldn't be
|
||
starting with this document.
|
||
|
||
The basic procedure to build an RPM is as follows:
|
||
|
||
* Get the source code you are building the RPM for to build on your system.
|
||
|
||
* Make a patch of any changes you had to make to the sources to get them to
|
||
build properly.
|
||
|
||
* Make a spec file for the package.
|
||
|
||
* Make sure everything is in its proper place.
|
||
|
||
* Build the package using RPM.
|
||
|
||
|
||
Under normal operation, RPM builds both binary and source packages.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.1. The Spec File
|
||
|
||
We'll begin with discussion of the spec file. Spec files are required to
|
||
build a package. The spec file is a description of the software along with
|
||
instructions on how to build it and a file list for all the binaries that get
|
||
installed.
|
||
|
||
You'll want to name your spec file according to a standard convention. It
|
||
should be the package name-dash-version number-dash-release number-dot-spec.
|
||
This will ensure that if you install multiple source RPMs for different
|
||
versions of the same package that at least the spec files remain intact.
|
||
|
||
Here is a small spec file (eject-2.0.2-1.spec):
|
||
Summary: A program that ejects removable media using software control.
|
||
Name: eject
|
||
Version: 2.0.2
|
||
Release: 3
|
||
Copyright: GPL
|
||
Group: System Environment/Base
|
||
Source: http://metalab.unc.edu/pub/Linux/utils/disk-management/eject-2.0.2.tar.gz
|
||
Patch: eject-2.0.2-buildroot.patch
|
||
BuildRoot: /var/tmp/%{name}-buildroot
|
||
|
||
%description
|
||
The eject program allows the user to eject removable media
|
||
(typically CD-ROMs, floppy disks or Iomega Jaz or Zip disks)
|
||
using software control. Eject can also control some multi-
|
||
disk CD changers and even some devices' auto-eject features.
|
||
|
||
Install eject if you'd like to eject removable media using
|
||
software control.
|
||
|
||
%prep
|
||
%setup -q
|
||
%patch -p1 -b .buildroot
|
||
|
||
%build
|
||
make RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
|
||
|
||
%install
|
||
rm -rf $RPM_BUILD_ROOT
|
||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||
mkdir -p $RPM_BUILD_ROOT/usr/man/man1
|
||
|
||
install -s -m 755 eject $RPM_BUILD_ROOT/usr/bin/eject
|
||
install -m 644 eject.1 $RPM_BUILD_ROOT/usr/man/man1/eject.1
|
||
|
||
%clean
|
||
rm -rf $RPM_BUILD_ROOT
|
||
|
||
%files
|
||
%defattr(-,root,root)
|
||
%doc README TODO COPYING ChangeLog
|
||
|
||
/usr/bin/eject
|
||
/usr/man/man1/eject.1
|
||
|
||
%changelog
|
||
* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com>
|
||
- auto rebuild in the new build environment (release 3)
|
||
|
||
* Wed Feb 24 1999 Preston Brown <pbrown@redhat.com>
|
||
- Injected new description and group.
|
||
|
||
[ Some changelog entries trimmed for brevity. -Editor. ]
|
||
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.2. The Header
|
||
|
||
The header has some standard fields in it that you need to fill in. There are
|
||
a few caveats as well. The fields must be filled in as follows:
|
||
|
||
* Summary: This is a one line description of the package.
|
||
|
||
* Name: This must be the name string from the rpm filename you plan to use.
|
||
|
||
* Version: This must be the version string from the rpm filename you plan
|
||
to use.
|
||
|
||
* Release: This is the release number for a package of the same version
|
||
(ie. if we make a package and find it to be slightly broken and need to
|
||
make it again, the next package would be release number 2).
|
||
|
||
* Copyright: This line tells how a package is copyrighted. You should use
|
||
something like GPL, BSD, MIT, public domain, distributable, or
|
||
commercial.
|
||
|
||
* Group: This is a group that the package belongs to in a higher level
|
||
package tool or the Red Hat installer.
|
||
|
||
* Source: This line points at the HOME location of the pristine source
|
||
file. It is used if you ever want to get the source again or check for
|
||
newer versions. Caveat: The filename in this line MUST match the filename
|
||
you have on your own system (ie. don't download the source file and
|
||
change its name). You can also specify more than one source file using
|
||
lines like:
|
||
Source0: blah-0.tar.gz
|
||
Source1: blah-1.tar.gz
|
||
Source2: fooblah.tar.gz
|
||
|
||
|
||
These files would go in the SOURCES directory. (The directory structure
|
||
is discussed in a later section, "The Source Directory Tree".)
|
||
|
||
* Patch: This is the place you can find the patch if you need to download
|
||
it again. Caveat: The filename here must match the one you use when you
|
||
make YOUR patch. You may also want to note that you can have multiple
|
||
patch files much as you can have multiple sources. ] You would have
|
||
something like:
|
||
Patch0: blah-0.patch
|
||
Patch1: blah-1.patch
|
||
Patch2: fooblah.patch
|
||
|
||
|
||
These files would go in the SOURCES directory.
|
||
|
||
* Group: This line is used to tell high level installation programs (such
|
||
as Red Hat's gnorpm) where to place this particular program in its
|
||
hierarchical structure. You can find the latest description in /usr/doc/
|
||
rpm*/GROUPS. The group tree currently looks something like this:
|
||
Amusements/Games
|
||
Amusements/Graphics
|
||
Applications/Archiving
|
||
Applications/Communications
|
||
Applications/Databases
|
||
Applications/Editors
|
||
Applications/Emulators
|
||
Applications/Engineering
|
||
Applications/File
|
||
Applications/Internet
|
||
Applications/Multimedia
|
||
Applications/Productivity
|
||
Applications/Publishing
|
||
Applications/System
|
||
Applications/Text
|
||
Development/Debuggers
|
||
Development/Languages
|
||
Development/Libraries
|
||
Development/System
|
||
Development/Tools
|
||
Documentation
|
||
System Environment/Base
|
||
System Environment/Daemons
|
||
System Environment/Kernel
|
||
System Environment/Libraries
|
||
System Environment/Shells
|
||
User Interface/Desktops
|
||
User Interface/X
|
||
User Interface/X Hardware Support
|
||
|
||
|
||
* BuildRoot: This line allows you to specify a directory as the "root" for
|
||
building and installing the new package. You can use this to help test
|
||
your package before having it installed on your machine.
|
||
|
||
* %description It's not really a header item, but should be described with
|
||
the rest of the header. You need one description tag per package and/or
|
||
subpackage. This is a multi-line field that should be used to give a
|
||
comprehensive description of the package.
|
||
|
||
|
||
-----------------------------------------------------------------------------
|
||
6.3. Prep
|
||
|
||
This is the second section in the spec file. It is used to get the sources
|
||
ready to build. Here you need to do anything necessary to get the sources
|
||
patched and setup like they need to be setup to do a make.
|
||
|
||
One thing to note: Each of these sections is really just a place to execute
|
||
shell scripts. You could simply make an sh script and put it after the %prep
|
||
tag to unpack and patch your sources. We have made macros to aid in this,
|
||
however.
|
||
|
||
The first of these macros is the %setup macro. In its simplest form (no
|
||
command line options), it simply unpacks the sources and cd's into the source
|
||
directory. It also takes the following options:
|
||
|
||
* -n name will set the name of the build directory to the listed name. The
|
||
default is $NAME-$VERSION. Other possibilities include $NAME, ${NAME}$
|
||
{VERSION}, or whatever the main tar file uses. (Please note that these
|
||
"$" variables are not real variables available within the spec file. They
|
||
are really just used here in place of a sample name. You need to use the
|
||
real name and version in your package, not a variable.)
|
||
|
||
* -c will create and cd to the named directory before doing the untar.
|
||
|
||
* -b # will untar Source# before cd'ing into the directory (and this makes
|
||
no sense with -c so don't do it). This is only useful with multiple
|
||
source files.
|
||
|
||
* -a # will untar Source# after cd'ing into the directory.
|
||
|
||
* -T This option overrides the default action of untarring the Source and
|
||
requires a -b 0 or -a 0 to get the main source file untarred. You need
|
||
this when there are secondary sources.
|
||
|
||
* -D Do not delete the directory before unpacking. This is only useful
|
||
where you have more than one setup macro. It should only be used in setup
|
||
macros after the first one (but never in the first one).
|
||
|
||
|
||
The next of the available macros is the %patch macro. This macro helps
|
||
automate the process of applying patches to the sources. It takes several
|
||
options, listed below:
|
||
|
||
* # will apply Patch# as the patch file.
|
||
|
||
* -p # specifies the number of directories to strip for the patch(1)
|
||
command.
|
||
|
||
* -P The default action is to apply Patch (or Patch0). This flag inhibits
|
||
the default action and will require a 0 to get the main source file
|
||
untarred. This option is useful in a second (or later) %patch macro that
|
||
required a different number than the first macro.
|
||
|
||
* You can also do %patch# instead of doing the real command: %patch # -P
|
||
|
||
* -b extension will save originals as filename.extension before patching.
|
||
|
||
|
||
That should be all the macros you need. After you have those right, you can
|
||
also do any other setup you need to do via sh type scripting. Anything you
|
||
include up until the %build macro (discussed in the next section) is executed
|
||
via sh. Look at the example above for the types of things you might want to
|
||
do here.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.4. Build
|
||
|
||
There aren't really any macros for this section. You should just put any
|
||
commands here that you would need to use to build the software once you had
|
||
untarred the source, patched it, and cd'ed into the directory. This is just
|
||
another set of commands passed to sh, so any legal sh commands can go here
|
||
(including comments).
|
||
|
||
Important Your current working directory is reset in each of these sections
|
||
to the toplevel of the source directory, so keep that in mind. You
|
||
can cd into subdirectories if necessary.
|
||
|
||
The variable RPM_OPT_FLAGS is set using values in /usr/lib/rpm/rpmrc. Look
|
||
there to make sure you are using values appropriate for your system (in most
|
||
cases you are). Or simply don't use this variable in your spec file. It is
|
||
optional.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.5. Install
|
||
|
||
There aren't really any macros here, either. You basically just want to put
|
||
whatever commands here that are necessary to install. If you have make
|
||
install available to you in the package you are building, put that here. If
|
||
not, you can either patch the makefile for a make install and just do a make
|
||
install here, or you can hand install them here with sh commands. You can
|
||
consider your current directory to be the toplevel of the source directory.
|
||
|
||
The variable RPM_BUILD_ROOT is available to tell you the path set as the
|
||
Buildroot: in the header. Using build roots are optional but are highly
|
||
recommended because they keep you from cluttering your system with software
|
||
that isn't in your RPM database (building an RPM doesn't touch your
|
||
database...you must go install the binary RPM you just built to do that).
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.6. Cleaning your system
|
||
|
||
It's a good idea to always make sure there is a clean build root before
|
||
building a package a second time on a system. The %clean macro will help with
|
||
that. Simply put the proper commands there to blow away a former build root.
|
||
Anal, err, careful folks may want to test that RPM_BUILD_ROOT wasn't set to /
|
||
before doing something this volatile.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.7. Optional pre and post Install/Uninstall Scripts
|
||
|
||
You can put scripts in that get run before and after the installation and
|
||
uninstallation of binary packages. A main reason for this is to do things
|
||
like run ldconfig after installing or removing packages that contain shared
|
||
libraries. The macros for each of the scripts is as follows:
|
||
|
||
* %pre is the macro to do pre-install scripts.
|
||
|
||
* %post is the macro to do post-install scripts.
|
||
|
||
* %preun is the macro to do pre-uninstall scripts.
|
||
|
||
* %postun is the macro to do post-uninstall scripts.
|
||
|
||
|
||
The contents of these sections should just be any sh style script, though you
|
||
do not need the #!/bin/sh.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.8. Files
|
||
|
||
This is the section where you must list the files for the binary package. RPM
|
||
has no way to know what binaries get installed as a result of make install.
|
||
There is NO way to do this. Some have suggested doing a find before and after
|
||
the package install. With a multiuser system, this is unacceptable as other
|
||
files may be created during a package building process that have nothing to
|
||
do with the package itself.
|
||
|
||
There are some macros available to do some special things as well. They are
|
||
listed and described here:
|
||
|
||
* %doc is used to mark documentation in the source package that you want
|
||
installed in a binary install. The documents will be installed in /usr/
|
||
doc/$NAME-$VERSION-$RELEASE. You can list multiple documents on the
|
||
command line with this macro, or you can list them all separately using a
|
||
macro for each of them.
|
||
|
||
* %config is used to mark configuration files in a package. This includes
|
||
files like sendmail.cf, passwd, etc. If you later uninstall a package
|
||
containing config files, any unchanged files will be removed and any
|
||
changed files will get moved to their old name with a .rpmsave appended
|
||
to the filename. You can list multiple files with this macro as well.
|
||
|
||
* %dir marks a single directory in a file list to be included as being
|
||
owned by a package. By default, if you list a directory name WITHOUT a
|
||
%dir macro, EVERYTHING in that directory is included in the file list and
|
||
later installed as part of that package.
|
||
|
||
* %defattr allows you to set default attributes for files listed after the
|
||
defattr declaration. The attributes are listed in the form (mode, owner,
|
||
group) where the mode is the octal number representing the bit pattern
|
||
for the new permissions (like chmod would use), owner is the username of
|
||
the owner, and group is the group you would like assigned. You may leave
|
||
any field to the installed default by simply placing a - in its place, as
|
||
was done in the mode field for the example package.
|
||
|
||
* %files -f <filename> will allow you to list your files in some arbitrary
|
||
file within the build directory of the sources. This is nice in cases
|
||
where you have a package that can build it's own filelist. You then just
|
||
include that filelist here and you don't have to specifically list the
|
||
files.
|
||
|
||
|
||
The biggest caveat in the file list is listing directories. If you list /usr/
|
||
bin by accident, your binary package will contain every file in /usr/bin on
|
||
your system.
|
||
-----------------------------------------------------------------------------
|
||
|
||
6.9. Changelog
|
||
|
||
This is a log of what changes occurred when the package is updated. If you
|
||
are modifying an existing RPM it is a good idea to list what changes you made
|
||
here.
|
||
|
||
The format is simple. Start each new entry with a line with a * followed by
|
||
the date, your name, and your email address. The date should appear in the
|
||
same format that is output by:
|
||
date +"%a %b %d %Y"
|
||
|
||
|
||
The rest of the section is a free text field, but should be organized in some
|
||
coherent manner.
|
||
-----------------------------------------------------------------------------
|
||
|
||
7. Building It
|
||
|
||
7.1. The Source Directory Tree
|
||
|
||
The first thing you need is a properly configured build tree. This is
|
||
configurable using the /etc/rpmrc file. Most people will just use /usr/src.
|
||
|
||
You may need to create the following directories to make a build tree:
|
||
|
||
* BUILD is the directory where all building occurs by RPM. You don't have
|
||
to do your test building anywhere in particular, but this is where RPM
|
||
will do it's building.
|
||
|
||
* SOURCES is the directory where you should put your original source tar
|
||
files and your patches. This is where RPM will look by default.
|
||
|
||
* SPECS is the directory where all spec files should go.
|
||
|
||
* RPMS is where RPM will put all binary RPMs when built.
|
||
|
||
* SRPMS is where all source RPMs will be put.
|
||
|
||
|
||
-----------------------------------------------------------------------------
|
||
7.2. Test Building
|
||
|
||
The first thing you'll probably want to to is get the source to build cleanly
|
||
without using RPM. To do this, unpack the sources, and change the directory
|
||
name to $NAME.orig. Then unpack the source again. Use this source to build
|
||
from. Go into the source directory and follow the instructions to build it.
|
||
If you have to edit things, you'll need a patch. Once you get it to build,
|
||
clean the source directory. Make sure and remove any files that get made from
|
||
a configure script. Then cd back out of the source directory to its parent.
|
||
Then you'll do something like:
|
||
diff -uNr dirname.orig dirname > ../SOURCES/dirname-linux.patch
|
||
|
||
|
||
This will create a patch for you that you can use in your spec file. Note
|
||
that the "linux" that you see in the patch name is just an identifier. You
|
||
might want to use something more descriptive like "config" or "bugs" to
|
||
describe why you had to make a patch. It's also a good idea to look at the
|
||
patch file you are creating before using it to make sure no binaries were
|
||
included by accident.
|
||
-----------------------------------------------------------------------------
|
||
|
||
7.3. Generating the File List
|
||
|
||
Now that you have source that will build and you know how to do it, build it
|
||
and install it. Look at the output of the install sequence and build your
|
||
file list from that to use in the spec file. We usually build the spec file
|
||
in parallel with all of these steps. You can create the initial one and fill
|
||
in the easy parts, and then fill in the other steps as you go.
|
||
-----------------------------------------------------------------------------
|
||
|
||
7.4. Building the Package with RPM
|
||
|
||
Once you have a spec file, you are ready to try and build your package. The
|
||
most useful way to do it is with a command like the following:
|
||
rpm -ba foobar-1.0.spec
|
||
|
||
|
||
There are other options useful with the -b switch as well:
|
||
|
||
* p means just run the prep section of the specfile.
|
||
|
||
* l is a list check that does some checks on %files.
|
||
|
||
* c do a prep and compile. This is useful when you are unsure of whether
|
||
your source will build at all. It seems useless because you might want to
|
||
just keep playing with the source itself until it builds and then start
|
||
using RPM, but once you become accustomed to using RPM you will find
|
||
instances when you will use it.
|
||
|
||
* ido a prep, compile, and install.
|
||
|
||
* b prep, compile, install, and build a binary package only.
|
||
|
||
* abuild it all (both source and binary packages).
|
||
|
||
|
||
There are several modifiers to the -b switch. They are as follows:
|
||
|
||
* --short-circuit will skip straight to a specified stage (can only be used
|
||
with c and i).
|
||
|
||
* --clean removes the build tree when done.
|
||
|
||
* --keep-temps will keep all the temp files and scripts that were made in /
|
||
tmp. You can actually see what files were created in /tmp using the -v
|
||
option.
|
||
|
||
* --test does not execute any real stages, but does keep-temp.
|
||
|
||
|
||
-----------------------------------------------------------------------------
|
||
7.5. Testing It
|
||
|
||
Once you have a source and binary rpm for your package, you need to test it.
|
||
The easiest and best way is to use a totally different machine from the one
|
||
you are building on to test. After all, you've just done a lot of make
|
||
install's on your own machine, so it should be installed fairly well.
|
||
|
||
You can do an rpm -e packagename on the package to test, but that can be
|
||
deceiving because in building the package, you did a make install. If you
|
||
left something out of your file list, it will not get uninstalled. You'll
|
||
then reinstall the binary package and your system will be complete again, but
|
||
your rpm still isn't. Make sure and keep in mind that just because you do a
|
||
rpm -ba package, most people installing your package will just be doing the
|
||
rpm -i package. Make sure you don't do anything in the build or install
|
||
sections that will need to be done when the binaries are installed by
|
||
themselves.
|
||
-----------------------------------------------------------------------------
|
||
|
||
7.6. What to do with your new RPMs
|
||
|
||
Once you've made your own RPM of something (assuming its something that
|
||
hasn't already been RPM'ed), you can contribute your work to others (also
|
||
assuming you RPM'ed something freely distributable). To do so, you'll want to
|
||
upload it to [ftp://ftp.redhat.com] ftp.redhat.com.
|
||
-----------------------------------------------------------------------------
|
||
|
||
7.7. What Now?
|
||
|
||
Please see the above sections on Testing and What to do with new RPMs. We
|
||
want all the RPMs available we can get, and we want them to be good RPMs.
|
||
Please take the time to test them well, and then take the time to upload them
|
||
for everyone's benefit. Also, please make sure you are only uploading freely
|
||
available software. Commercial software and shareware should not be uploaded
|
||
unless they have a copyright expressly stating that this is allowed. This
|
||
includes ssh, pgp, etc.
|
||
-----------------------------------------------------------------------------
|
||
|
||
8. Multi-architectural RPM Building
|
||
|
||
RPM can now be used to build packages for the Intel i386, the Digital Alpha
|
||
running Linux, and the Sparc (and others). There are several features that
|
||
make building packages on all platforms easy. The first of these is the
|
||
"optflags" directive in the /etc/rpmrc. It can be used to set flags used when
|
||
building software to architecture specific values. Another feature is the
|
||
"arch" macros in the spec file. They can be used to do different things
|
||
depending on the architecture you are building on. Another feature is the
|
||
"Exclude" directive in the header.
|
||
-----------------------------------------------------------------------------
|
||
|
||
8.1. Sample spec File
|
||
|
||
The following is part of the spec file for the "fileutils" package. It is
|
||
setup to build on both the Alpha and the Intel.
|
||
Summary: GNU File Utilities
|
||
Name: fileutils
|
||
Version: 3.16
|
||
Release: 1
|
||
Copyright: GPL
|
||
Group: Utilities/File
|
||
Source0: prep.ai.mit.edu:/pub/gnu/fileutils-3.16.tar.gz
|
||
Source1: DIR_COLORS
|
||
Patch: fileutils-3.16-mktime.patch
|
||
|
||
%description
|
||
These are the GNU file management utilities. It includes programs
|
||
to copy, move, list, etc, files.
|
||
|
||
The ls program in this package now incorporates color ls!
|
||
|
||
%prep
|
||
%setup
|
||
|
||
%ifarch alpha
|
||
%patch -p1
|
||
autoconf
|
||
%endif
|
||
%build
|
||
configure --prefix=/usr --exec-prefix=/
|
||
make CFLAGS="$RPM_OPT_FLAGS" LDFLAGS=-s
|
||
|
||
%install
|
||
rm -f /usr/info/fileutils*
|
||
make install
|
||
gzip -9nf /usr/info/fileutils*
|
||
|
||
.
|
||
.
|
||
.
|
||
|
||
|
||
-----------------------------------------------------------------------------
|
||
|
||
8.2. Optflags
|
||
|
||
In this example, you see how the "optflags" directive is used from the /etc/
|
||
rpmrc. Depending on which architecture you are building on, the proper value
|
||
is given to RPM_OPT_FLAGS. You must patch the Makefile for your package to
|
||
use this variable in place of the normal directives you might use (like -m486
|
||
and -O2). You can get a better feel for what needs to be done by installing
|
||
this source package and then unpacking the source and examine the Makefile.
|
||
Then look at the patch for the Makefile and see what changes must be made.
|
||
-----------------------------------------------------------------------------
|
||
|
||
8.3. Macros
|
||
|
||
The %ifarch macro is very important to all of this. Most times you will need
|
||
to make a patch or two that is specific to one architecture only. In this
|
||
case, RPM will allow you to apply that patch to just one architecture only.
|
||
|
||
In the above example, fileutils has a patch for 64 bit machines. Obviously,
|
||
this should only be applied on the Alpha at the moment. So, we add an %ifarch
|
||
macro around the 64 bit patch like so:
|
||
%ifarch axp
|
||
%patch1 -p1
|
||
%endif
|
||
|
||
|
||
This will insure that the patch is not applied on any architecture except the
|
||
alpha.
|
||
-----------------------------------------------------------------------------
|
||
|
||
8.4. Excluding Architectures from Packages
|
||
|
||
So that you can maintain source RPMs in one directory for all platforms, we
|
||
have implemented the ability to "exclude" packages from being built on
|
||
certain architectures. This is so you can still do things like
|
||
rpm --rebuild /usr/src/SRPMS/*.rpm
|
||
|
||
|
||
and have the right packages build. If you haven't yet ported an application
|
||
to a certain platform, all you have to do is add a line like:
|
||
ExcludeArch: alpha
|
||
|
||
|
||
to the header of the spec file of the source package. Then rebuild the
|
||
package on the platform that it does build on. You'll then have a source
|
||
package that builds on an Intel and can easily be skipped on an Alpha.
|
||
-----------------------------------------------------------------------------
|
||
|
||
8.5. Finishing Up
|
||
|
||
Using RPM to make multi-architectural packages is usually easier to do than
|
||
getting the package itself to build both places. As more of the hard packages
|
||
get built this is getting much easier, however. As always, the best help when
|
||
you get stuck building an RPM is to look a similar source package.
|