this was supposed to be such a simple thing to write, but
once i started getting feedback on how to build RPMs "properly,"
this document took on a life of its own, and eventually morphed
into how to build RPMs in general.

  i think it's pretty well a done deal, and i'm interested in
any comments, criticisms, corrections, etc.  and now, i'm going
to make more coffee, lie on the couch, and look at all the
snow outside the living room window.  then go back to work
on my perl course.  later.

rday
* Overview -- building RPMs

  This document describes, using a concrete example, how to
build simple binary, noarch and source RPMS.

  A binary RPM file would typically have a file name like
"niftyprogs-3.4-2.i386.rpm," identifying it as an RPM
for the ix86 architecture.  Such an RPM would normally contain
some compiled binary executables, and would automatically
install them in directories like /bin or /usr/bin, or maybe
/usr/local/bin, /opt/bin or something like that.

  A non-architecture-dependent (or "noarch") RPM is a simpler
package and would typically be used to distribute non-binary-
program related files and directories such as text files,
audio or video files, font files or even arch-independent
script programs such as shell or Perl programs.  Both of these
kinds of RPMs might also contain the standard overhead of 
documentation files like a README or LICENSE file and the like.

  Finally, in either case, you might want to create the
corresponding source RPM, which will allow others to examine
the way you built your binary or noarch, and to rebuild it
themselves.

  This document focuses on how to, step by step, build the
simpler noarch RPM but, toward the end, shows how easy it
is to extend this example to handle binary RPMs as well.

  Before we start, I'll assume that you're already familiar with
how to use the "rpm" command to do basic things like install, 
examine and remove RPMs.  In addition, if you haven't already, you
should install the "rpm-build" RPM, which is essential for rolling 
your own RPMs.  (For basic RPM management, you should use
the "rpm" command, but for creating RPMs, you should use the
newer "rpmbuild" command.)

  Finally, there are all kinds of ways to make RPM building
outrageously complicated, but I'm going to try to keep things
simple with examples that will handle the majority of folks'
needs.  If there's a more sophisticated feature that I think 
you might want to know about, I've added several appendices  
so as to not break up the flow.

* The hypothetical scenario

  Let's start by covering in detail how to build a noarch RPM
that contains graphics files and some documentation.

  Imagine that, as employee Fred Berferd of Pics 'r' Us, Inc, 
you've been told to create a noarch RPM out of a collection of
images of various cats, along with the accompanying documentation
files README and ARTISTS that came with those images.

  In addition, just to make things a little more interesting,
all RPMs built at this company must also contain the standard
corporate LICENSE documentation file, as well a corporate
logo image file "picsrus.jpg".  All of this represents the entire 
contents of the new RPM.

  Since this will be the company's very first cat-pic-related RPM,
it will have the designations:

  package name: catpics
  version: 1.0
  release: 1

which suggests that the final RPM should have the name
catpics-1.0-1.noarch.rpm.  You've been told to build this RPM file 
so that, when the customer installs it on their system, it will
unload files and directories in the locations:

  /usr/local/catpics/<cat image files>  # including picsrus.jpg
  /usr/share/doc/catpics-1.0/{README, ARTISTS, LICENSE}

So, let's start building catpics-1.0-1.noarch.rpm.

* The RPM building directory structure

  If you're using Red Hat Linux, there is already a pre-defined
directory structure to support building your own RPMs.  If you
look under /usr/src/redhat, what you'll find is a number of
subdirectories that are used for the original source files for
the RPM, for the build phase, for creating the installation
directory structure and so on.

  However, since this directory is available only to root and
it's considered a hanging offense to build new RPMs as root,
you're *strongly* encouraged, as a normal user, to duplicate
that directory structure under your home directory.  Pick a
reasonable top-level name (say, "rpm"), and create those
duplicates:

  $ cd
  $ mkdir -p rpm/{SOURCES,SPECS,BUILD,RPMS,SRPMS}
  $ mkdir -p rpm/RPMS/{i386,i586,i686,noarch}
  $ mkdir rpm/tmp       # to be explained shortly
  
  In order of when you'll use these directories, here's what
they represent:

  SOURCES: Where you'll gather your initial collection of files,
           in some format, from which to build the eventual RPM.
           In our case, we'll start with all of the cat image
           files, plus the accompanying README and ARTISTS files.

  SPECS:   Where you'll create the "spec" file for the new RPM,
           which defines (among many other things) information about 
           the new RPM, how to build it, what files it should contain
           and where those files should be installed on the target
           host.

  BUILD:   This is the actual "build" directory, where the original
           sources may be processed to generate even more files to
           be added to the new RPM.  If you're building a noarch
           RPM, there may in fact be nothing to build, since you
           have all the files you need already.

           If, however, you're building a binary RPM from program
           sources, this is where you'd set up the source files and
           a Makefile, and create the object files and eventual
           executables.  Hence, the directory name "BUILD".

  tmp:     A temporary directory, under which you'll typically create
           the "build root" for the new RPM.  This is where you'll
           create a directory structure which contains all of the
           files and directories to be added to the new RPM, in
           exactly the directory structure they should be installed
           on the target host.

           In other words, once you finish the stage of "build"ing
           all of the files that should go in the new RPM, the
           build root will represent precisely their target directory
           structure.

  RPMS:    Where new RPMs will be placed for your inspection and
           approval.  New noarch RPMs will be placed in RPMS/noarch,
           new binary RPMs will go in RPMS/i386, and so on.

  Finally, you can force the "rpm" and "rpmbuild" commands to 
use this directory structure by creating the configuration file
~/.rpmmacros, with the contents:

  %_topdir      /home/fred/rpm
  %_tmppath     /home/fred/rpm/tmp

  So let's start discussing each stage of the RPM build in detail.

* Building the tarball

  Your first job is to copy into the SOURCES directory the initial
set of files to create this new RPM.  The most common format for 
your source files is a "tarball" -- a gzipped tar archive.  Tarballs
are common since they represent a convenient way to ship an entire
set of source files, plus the "rpmbuild" command has some shortcuts
for handling tarballs automatically.

  Given the RPM you're trying to build, tradition suggests that you
name your tarball catpics-1.0.tar.gz, or catpics-1.0.tgz for short.
One possibility for its contents (assuming a collection of four cats)
might be:

  $ tar tvzf catpics-1.0.tgz
  catpics-1.0/
  catpics-1.0/pics/
  catpics-1.0/pics/jones.jpg
  catpics-1.0/pics/xena.jpg
  catpics-1.0/pics/clarence.jpg
  catpics-1.0/pics/elliott.jpg
  catpics-1.0/ARTISTS
  catpics-1.0/README

  Things to notice about the tarball:

  - It should have a top-level directory name that matches the RPM
    name and version that you plan to build.

  - It contains all of the files that the artists or photographers
    were responsible for supplying.

  - Most importantly, the location of the files in the tarball do
    *not* have to match their eventual location in the new RPM.
    Between extracting the files from the SOURCES directory and
    adding them to the build root, you have the freedom to change
    their locations to match the eventual directory structure.

    Specifically, the location of any documentation files like 
    README don't have to match their final location.  In fact,
    there is a tradition of putting doc files just under the 
    top-level directory in the tarball as the RPM-building
    process has a shortcut for dealing with doc files that are
    placed here.

  One final point:  You'll notice the absence of the corporate
LICENSE file or corporate picsrus.jpg file in the tarball.
Think of the tarball as what the artists or photographers were
required to supply for the new RPM; whether there are extra
files or images that have to be added for the eventual RPM
is a problem for you, the RPM builder, not the artists.
All this means is that, while the initial tarball is a 
wonderful way to get the initial contents of the RPM, it
may not represent the complete final results -- you may have
to get extra input from other sources to satisfy things like
corporate policy.

  All right, now that you have your tarball, it's time to design
your spec file.

* The spec file
** What's a spec file?

  The "spec" file for a new RPM (whose name is typically
<package>.spec or, in our case, "catpics.spec") contains, 
among other things, the name and version of the RPM you're 
building, along with corporate information and detailed steps 
describing the sources, how to build those sources and how to 
package the resulting files to create the new RPM.
  
  More specifically, the spec file starts with a "preamble"
describing the properties of the new RPM, followed by the
instructions for the "%prep", "%build", "%install" and "%clean"
stages, as well as the "%files" section which lists precisely
which files you want to add to the RPM and where -- we'll
cover these stages one at a time.
  
  Technically, the spec file can be created anywhere, but it's
traditional to create it in your SPECS directory.  If, at any 
time, you want to see the spec file in its entirety, see 
the listing for "catpics.spec" in Appendix A.)

** The preamble

  Consider a possible preamble for our catpics-1.0 RPM at 
the beginning of the spec file:

----- begin preamble -----
  Summary: CatPics, a collection of feline images
  Name: catpics
  Version: 1.0
  Release: 1
  Copyright: GPL
  Group: Amusements/Graphics
  Source: ftp://ftp.picsrus.com/pub/%{name}-%{version}.tgz
  URL: http://www.picsrus.com/pub/pics/catpics.html
  BuildArch: noarch
  BuildRoot: %{_tmppath}/%{name}-root
  Vendor: Pics R Us, Inc.
  Packager: Fred Berferd <[EMAIL PROTECTED]>
  Requires: ee

  %description
  This package contains CatPics, just a collection of 
  feline images in various graphics formats, along with
  some documentation and corporate info files.
----- end preamble -----

  The preamble represents the information someone can see if
they query the eventual RPM with:

  $ rpm -qpi catpics-1.0-1.noarch.rpm

Some of these values should be obvious; some observations about
the rest:

  - The Group value should be one of the values from the file
    /usr/share/doc/rpm-4.0.3/GROUPS.  Strictly speaking, it 
    doesn't *have* to be, but you're strongly encouraged to use
    one of those combinations.

  - The Source value represents two things:  the full name points
    at the tarball's location on the Internet, while only the last
    component of that pathname represents the name of the tarball
    in the SOURCES directory.  So, really, it's only that last
    component that matters here.  Similarly, the URL value is
    not essential, and is a pointer to documentation for the package
    available on the 'Net, if anyone wants to go hunting for it.

  - BuildRoot represents the location where you plan on building
    the directory structure that will ultimately match the final
    structure in the RPM -- where things will go when the RPM is
    installed on the target host.

    As shown above, it's traditional to put all new build roots
    in the ~/rpm/tmp directory, in a subdirectory matching the name
    of the package.  In our case, this RPM's build root will be the
    directory ~/rpm/tmp/catpics-root, and it will be your job to
    copy under that directory what you want as the eventual file
    and directory layout of the final RPM.

  The rest of the preamble is fairly straightforward, and even 
demonstrates a simple package prerequisite -- you can require
that the "ee" package be installed on the target host before
this RPM can be installed.

  (Short aside: you're allowed to have more than one Source
directive if your sources for this new RPM are coming from more
than one location but, as I said, I'd like to keep this simple.)

  And now, on with the actual construction.

** The script variables (a huge footnote, really)

  Given that the rest of the spec file represents commands to be
run that will unload, process and build a new RPM, it's worth
pointing out that, at this point, the following variables are now
available to use in any of these upcoming steps (shown with their
values for our example):

  RPM_PACKAGE_NAME              catpics
  RPM_PACKAGE_VERSION           1.0
  RPM_PACKAGE_RELEASE           1
  RPM_ARCH                      i386
  RPM_OS                        linux
  RPM_SOURCE_DIR                /home/fred/rpm/SOURCES
  RPM_BUILD_DIR                 /home/fred/rpm/BUILD
  RPM_BUILD_ROOT                /home/fred/rpm/tmp/catpics-root

If you want to refer to any of them, you can use either, for
example, ${RPM_BUILD_ROOT} or just $RPM_BUILD_ROOT.

  One important note here: Don't confuse the "build directory" 
with the "build root" -- the build directory is where the tarball 
will be unloaded and processed, while the "build root" is where 
you will construct, piece by piece, an exact image of the files 
and directories to be contained in the RPM.  (It's unfortunate that 
this directory was called the "build root" -- calling it the
"install root" would have made much more sense.)

  Now, on to the first stage -- the "%prep" stage.

** The %prep stage

  The purpose of the %prep stage is simply to gather into the
appropriate "build" directory all of the sources you'll need
to build the new RPM.  Each new RPM should get its own build
subdirectory under the main build directory so this suggests
that, while the main build directory for all RPMs is 
~fred/rpm/BUILD (or ${RPM_BUILD_DIR} for short), the catpics-specific 
build directory will be ${RPM_BUILD_DIR}/catpics-1.0.

  Given that the purpose of the %prep stage is to unload the
catpics source into the corresponding build directory, we
could, if we wanted, do this manually with something like:

  %prep
  cd ${RPM_BUILD_DIR}
  rm -rf catpics-1.0                    # remove old version??
  gzip -dc ${RPM_SOURCE_DIR}/catpics-1.0.tgz | tar xvf -
  cd catpics-1.0                        # enter new dir

The end result of the above is that we end up at the top level
of a directory containing the contents of the catpics-1.0 tarball,
ready to start the build stage.

  However, unloading from a tarball is such a common procedure
that you can use the shortcut macro "%setup" in one of two ways:

  %prep
  %setup                # regular setup or ...
  %setup -q             # ... quiet setup

In either case, the end result is the same, and you end up in
the catpics build directory, looking at the contents of the
catpics tarball:

  pics/jones.jpg
  pics/xena.jpg
  pics/clarence.jpg
  pics/elliott.jpg
  ARTISTS
  README

At this point, you've done the prep and can move on to the
"build" stage, except for one possible complication.

  Notice that we're still missing the corporate LICENSE file
and corporate graphics file from the catpics build directory.
If we really want *all* of the necessary source here in the
build directory before we go any further, we can just add
a couple of appropriate "cp" statements to the %prep stage,
as in:

  %prep
  %setup -q
  cp /etc/LICENSE .
  cp /etc/picsrus.jpg pics

I'm not suggesting that this is a common thing to do, or
even that it's the right way to do it.  (In fact, if you need
to get your source from several different locations, the proper
way to do it is to use several Source directives.)  I'm just
demonstrating how you can be as particular as you want in 
the %prep stage in terms of collecting all of the necessary
source.

  In any event, now that you've finished prepping, it's on to
the %build stage of the spec file.

** The %build stage (CHANGE)

  Given that you're currently in the build directory for the
catpics RPM, this stage is where you'd do any "building" of
additional files that need to go in the new RPM.

  In the case of a binary RPM where you have to compile 
executables, this is where you would run things like "configure"
and "make" and "make install" to get the new executables --
hence the reason it's called a "build" directory.  In other
words, this is the stage where you have to somehow create
the contents of the new RPM that don't come directly from the
tarball.

  In our case, since we have all the contents we need and
have nothing to build, our entire build stage could be
nothing more than:

  %build
  exit 0

And since we didn't have to build anything, we can head right
into the "%install" stage.

  (Side note:  Even if we're building a noarch RPM, there are
always trivial things we might want to do in the build stage.
We might create a hidden timestamp file showing when this RPM 
was built by running something like:

  date > ./.TIMESTAMP

  It's also possible to copy the non-tarball LICENSE and
picsrus.jpg files in this stage rather than the %prep stage.
The end result is the same but, again, I'm just throwing this
in to demonstrate that you can customize this stage as well.

  Admittedly, these are pretty trivial examples, but they
demonstrate that, if there's anything you need to do to create
additional RPM contents that don't come directly from the tarball,
this is the place to do it.)

  Now, on to the %install stage.

** The %install stage

  Now that the %build stage has created (in the directory
${RPM_BUILD_DIR}/catpics-1.0) absolutely everything you need
to build the new RPM, the job of the %install stage is to
create, in yet *another* directory, an exact copy of the
files and directories, in their proper locations, of what
you want built into the new RPM.

  This new directory is called the "build root" of the new
RPM and is typically created under your RPM tmp directory.
In our case, the build root directory would be
~fred/rpm/tmp/catpics-1.0, whose value is, just in case you
need it, available in the variable ${RPM_BUILD_ROOT}.

  Your job, in the %install stage, is to copy step by step,
everything you want in the new RPM, based on its install
location relative to the root directory on down.

  Recall that we wanted the catpics RPM to install the 
following on the target host:

  /usr/local/catpics/<cat image files>  # including picsrus.jpg
  /usr/share/doc/catpics-1.0/{README,ARTISTS,LICENSE}

  Given the above, our entire %install section might be:
  
  %install
  rm -rf ${RPM_BUILD_ROOT} 
  mkdir -p ${RPM_BUILD_ROOT}/usr/local/catpics
  cp pics/* ${RPM_BUILD_ROOT}/usr/local/catpics

As you can see, the build root for this RPM should contain
everything you want in the new RPM, in its appropriate location
relative to the root directory.  Note that the eventual
directory structure does not have to match the way the files
and directories came out of the original tarball.  You clearly
have the flexibility to restructure the new RPM any way you
want.

  Note also that our %install stage didn't do anything with the
documentation files.  This is because doc files are considered
a special case, and can be treated separately in a later
section.  So, other than the missing doc files, we're pretty
much finished with the %install section.

  (Side note:  It's unfortunate that the directory we've been
populating is referred to officially as the "build root".
It would seem that the previous directory, whose name really
is "BUILD," would be better named the build root, while it
makes more sense to call this one the "install root".  But
it's too late now.)

  We're almost ready to build the new RPM -- only a couple
stages to go.

** The %clean stage

  When the RPM is eventually constructed, you have the
right to do some automatic cleanup by defining a %clean stage
here.  While you can clean as much as you want, the following
is a perfectly respectable example of cleaning:

  %clean
  rm -rf ${RPM_BUILD_ROOT}

Keep in mind that, while you define the %clean stage here, it's
not actually run until the end of a successful RPM construction.
So what's left?  Just the %files stage.

** The %files stage

  The final stage in our spec file, the %files stage, is used
to identify exactly which files and directories should be
copied from the build root into the new RPM.  Let me make
sure you understand this last statement.

  While the previous %install stage created a directory
structure for the new RPM under the build root, you have no
obligation to add *all* of these files and directories to
the RPM -- you can be selective about what gets added.
In other words, while it's a bad idea, you can be sloppy
and copy extraneous junk into the build root during the
%install stage -- you just don't need to select all of it 
for inclusion in the RPM.

  For our example, here's a respectable %files section:

  %files
  %defattr(-,root,root)
  /usr/local/catpics
  %doc README ARTISTS LICENSE

What does all this mean?

  First, you can, if you want, have a single %defattr directive,
which dictates the default permissions, owner and group you
want for the contents of the RPM.  A hyphen means that you'll
take the current value, whatever it is.

  Following the optional %defattr, you should list all of the
files and directories you want added to the RPM, using their
fully-qualified location as you want it on the target host.

  Finally, as you can see above, documentation files can be
treated specially.  Rather than having to explicitly copy
doc files into the build root, and select them here, you can
use the %doc directive, which will look for these files at 
the top of the build directory, and automatically install
these files in the appropriate documentation directory in 
the RPM (in your case, probably the default directory of
/usr/share/doc/catpics-1.0).  This is a convenient shortcut,
but remember that it means you have to have these files at
the top level of the build directory.

  This is clearly a simple example of a %files stage.  For more
possibilities, see Appendix B, and for more options regarding
just documentation files, see Appendix C.  And while you're there, 
you might just want to review the entire spec file in Appendix A.

* Building the noarch RPM

  Now that you've finally designed the "catpics.spec" file,
you can create the corresponding noarch RPM from it and the
corresponding tarball with:

  $ rpmbuild -bb catpics.spec

This command will, in order and following the steps in the 
spec file:
  
  1) unload the SOURCES tarball into the BUILD/catpics-1.0
     directory,

  2) copy a couple of extra generic company files to go
     with those source files, 

  3) install these files under the corresponding build root, 

  4) select using the contents of the %files stage what
     should be added to the new RPM, 

  5) place this new RPM in the RPMS/noarch directory, and 

  6) run the %clean stage to get rid of the build root

  Once you create this new RPM, you can examine its contents
with any of:

  $ rpm -qpi catpics-1.0-1.noarch.rpm           (preamble info)
  $ rpm -qpl catpics-1.0-1.noarch.rpm           (file list)
  $ rpm -qplv catpics-1.0-1.noarch.rpm          (long file list)

to make sure every file is there and seems to be in the right
location.  You now have a noarch RPM ready to ship to customers.

  By the way, in addition to just building the final RPM, you
have the ability to stop the build process and look at the 
intermediate stages.  See Appendix D, "Debugging using partial
builds."

* Building a binary RPM

  Once you get the hang of building a noarch RPM, it's a small
step to building a binary RPM, say "myprogs-1.0-1.i386.rpm",
which would contain some collection of compiled binary programs,
possibly along with some text files, documentation, configuration
files and so on.

  Most of what you've read here would be pretty much the same,
except that the %build stage would be responsible for taking the
program sources from the tarball, and compiling them to get the
corresponding binary executables.

  You could do these compiles yourself manually, making calls to
"gcc" perhaps.  However, if you carefully design the contents of
the tarball to include the sources, corresponding configure scripts
and Makefile based on the gnu "autoconf" utility, you might need to 
just run commands like "configure","make" and "make install".

  In fact, this is such a common operation that rpm defines
some common macros so that your entire %build and %install stages
might look like:

  %build
  %configure
  %make

  %install
  %makeinstall

As an example, the "%makeinstall" macro is equivalent to running
a "make install", and using the appropriate build root as the
install destination, exactly what you would want.

  To see exactly what these macros are equivalent to, examine
their definitions in the file /usr/lib/rpm/macros.

* Building a source RPM

  As a final possibility, you have the ability to build a source
RPM.  A source RPM typically consists of nothing more than the
source(s) and the corresponding spec file, which you can then
ship to someone else who has the right to unload your source(s)
and your spec file.

  Others might want to get your source RPM for a number of 
reasons:  to see the pristine, original sources that went into
your RPM, to see the design of your spec file, or because they
want to build the corresponding noarch or binary RPM but specify
a different destination directory or build it for a different
architecture.

  Given a spec file and the source(s), you can build a source
RPM in two ways:

  $ rpm -bs catpics.spec          (build just the source RPM)
  $ rpm -ba catpics.spec          (build both source and binary RPMs)

In either case, what you should end up with is a source RPM
with the name catpics-1.0-1.src.rpm in your SRPMS directory.

* Ongoing RPM maintenance issues

  As you collect more nifty cat images, you may want to release
newer versions of the Pics 'r' Us catpics RPM file.  There are
two standard ways to build and release updated versions of an
RPM.

  First, if you really change the contents of the RPM by adding,
for example, new images, you should increment the version number
and create the next generation: catpics-1.1-1.noarch.rpm.  If
it's a substantial change, you might consider going to the next
major version number of 2.0.

  On the other hand, sometimes you simply want to make a change
in the RPM build process.  Perhaps someone complains that the
default permissions or owner and group of one or more files in
the shipped RPM is incorrect.  In cases like this, it's 
acceptable to modify some attributes in the %files section of
the spec file, and just increment the release number, to get
catpics-1.0-2.noarch.rpm.

  In either case, if you plan on making regular enhancements
to an RPM, you should record these changes in a ChangeLog
documentation file that ships with the RPM.

* Building RPMs the quick and dirty way

  While all of this documentation has explained the proper
and societally acceptable ways to build RPMs, starting with 
the tarball and working through various stages in the spec
file, occasionally someone says, "I don't have time to 
RTFM!  My boss just gave me 10 minutes to create a catpics
RPM for a client, and I don't have a clue how RPMs work.
What do I do?!"

  If you've understood everything until now, it should be
obvious that all of the preliminary processing is to do
nothing more than create a directory structure under the
"build root" directory that rpmbuild will bundle into an
RPM.  

  If this is all you really care about, you can build a
quick-and-dirty RPM in a couple of easy steps.  First, 
collect all of the files you want in the RPM, and copy
them under a build root directory somewhere, making sure
that their full pathname represents their location in the
new RPM from the build root directory on down.  No tarball.
No build directory.

  Once you do this, the corresponding spec file will be
fairly skeletal -- the preamble (where you set BuildRoot to
point at the build root directory), plus a %files section
that lists all of the files and directories you want to 
get from the build root.

  There is no need for any other other stages, so you can
just make them "no-op"s by having all of the %prep, %build
and %install stages contain the single command "exit 0".
And that should do it.

  Note that, while this will technically work, you lose all
of the flexibility of building RPMs "the right way".  Also,
you clearly can't build a corresponding source RPM.  But 
when time is an issue, this will work in a pinch.

* Stuff we didn't talk about

  There's clearly a lot of advanced stuff we didn't cover here:

  - spec file install and uninstall scripts
  - spec file conditionals
  - building relocatable packages
  - signing packages
  - creating subpackages

and a whole lot more.  If you want to know more, read the online
"Maximum RPM" book.  If you get online, start at www.rpm.org
and take it from there.

* In closing

  If you have any questions or comments, or suggestions on how
to improve this document, email me at [EMAIL PROTECTED]

  This document is copyright Robert P. J. Day, 2001.  All rights
reserved.  You're welcome to distribute this freely, but you're not
free to start making modifications to it until I release the
final version under the GNU FDL license.

* Appendix A: The spec file

  The contents of the spec file "catpics.spec":

Summary: CatPics, a collection of feline images
Name: catpics
Version: 1.0
Release: 1
Copyright: GPL
Group: Amusements/Graphics
Source: ftp://ftp.picsrus.com/pub/%{name}-%{version}.tgz
URL: http://www.picsrus.com/pub/pics/catpics.html
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-root
Vendor: Pics R Us, Inc.
Packager: Fred Berferd <[EMAIL PROTECTED]>
Requires: ee


%description
This package contains CatPics, just a collection of 
feline images in various graphics formats, along with a
couple of documentation files.

%prep
%setup -q
cp /etc/LICENSE .
cp /etc/picsrus.jpg pics

%build
exit 0

%install
rm -rf ${RPM_BUILD_ROOT}

mkdir -p ${RPM_BUILD_ROOT}/usr/local/catpics
cp pics/* ${RPM_BUILD_ROOT}/usr/local/catpics
touch ${RPM_BUILD_ROOT}/BOGUS

%clean
# rm -rf ${RPM_BUILD_ROOT}

%files
%defattr(-,root,root)
/usr/local/catpics
%doc README ARTISTS LICENSE

* Appendix B: The %files section

  Recall the fairly simple %files section we used to define the 
contents of our new RPM:

  %files
  %defattr(-,root,root)
  /usr/local/catpics
  %doc README ARTISTS LICENSE

So what does all this mean?

  The basic structure of the %files section is, with the
exception of %doc lines, one file or directory name per line, 
fully qualified (that is, starting with a "/") relative to the 
build root that you were populating in the %install step.  
In short, you should list all files and directories with their 
full name just the way you want to see them installed on the 
target host.  By default, a directory name represents the entire 
(recursive) contents of that directory, and standard shell 
wildcarding is supported.  However, on top of all of this,
you can add some %files "directives" to further control the
inclusion process.

  First, the %files section can have at most one %defattr
directive which dictates the default permissions, owner and
group of all of the files, as in:

  %defattr(644,root,root)

If any of these fields is a hyphen, that means that that
value is taken as is from the file in the build root directory.

  In addition, on a per-line basis, you can override the
%defattr values with an individual %attr directive:

  %defattr(-,root,root)
  %attr(755,root,root) /usr/local/catpics

  Next, while a simple directory entry means the entire, 
recursive contents of that directory, you can restrict the
meaning to just the directory itself with the %dir directive,
as in:

  %dir %attr(755,root,root) /usr/local/catpics

If you choose to select just a directory entry this way,
this normally means you really did just want to copy the
empty directory, or you're going to continue and select
individual subfiles and subdirectories with more entries
in this section.  (Note that you can have multiple
directives on the same line.)

  As we already mentioned, you can tag documentation files
that happen to reside in the top level of the build directory
with the %doc directive.  This allows you to list just the
simple file names, as well as being able to put multiple
files on the same line:

  %doc README ARTISTS LICENSE

For more on what you can do with documentation files, you
can see Appendix C.

   Finally, you can also tag certain files as %config files,
which will be treated with particular care if such files would
overwrite files of the same name during the installation
process, as in:

  %config /etc/picsrus.conf
  

* Appendix C: Documentation files

  As you've already seen, certain files in the %files section
can be tagged as documentation files.  Depending on whether
these files were at the top of the build directory, you can
use the short form to list them, as in:

  %doc README ARTISTS

or, if those files were being installed as ordinary files,
you could also always list them using the regular, fully-
qualified format, as in:

  %doc /usr/local/catpics/docfile

But wait, there's more.

  Once a file has been tagged this way, you have the right
to list strictly the documentation files in any RPM with:

  $ rpm -qpld catpics-1.0-1.noarch.rpm

  And finally, if you're strapped for disk space, you 
(theoretically) have the right to install all *but* the
documentation files with the command:

  $ rpm -ivh --excludedocs catpics-1.0-1.noarch.rpm

(I say "theoretically" since, while this feature is officially
documented, I have yet to get it work that way.)

* Appendix D: Debugging using partial builds
  
  With both noarch and binary RPMs, it's possible to do only a
partial build so that you can check the intermediate results
in, for instance, the build or build root directories.  So rather
than doing a complete catpics RPM build with "rpmbuild -bb", 
you can do any of the following:

  $ rpmbuild -bp catpics.spec           (%prep stage only)
  $ rpmbuild -bc catpics.spec           (%prep, %build)
  $ rpmbuild -bi catpics.spec           (%prep, %build, %install)

A common usage is to use "-bi", then check the contents of
the build root directory to see if it matches what you expect
to see in the eventual RPM.

  While all of the above start with the initial %prep stage, you
can also jump directly to a stage and execute that stage only
with the "--short-circuit" option:

  $ rpmbuild -bc --short-circuit catpics.spec   (%build ONLY)
  $ rpmbuild -bi --short-circuit catpics.spec   (%install ONLY)

The --short-circuit is available only for the -bc and -bi
options, and could be useful if you've alread done a partial
build up to that point, and now just want to do the next
stage.

  It is unfortunate that the name --short-circuit was chosen
for this option, since what it really refers to is jumping
directly to a stage and processing only that stage.  This 
option would have been more meaningfully called something like
"--single-stage" or "--this-stage-only".

Reply via email to