From: Kurt B. Kaiser (kbk@shore.net)
Subject: Building Binary RPM Packages from Source RPMs mini-HOWTO 
View: Complete Thread (4 articles)  
Original Format 
Newsgroups: linux.redhat.rpm
Date: 2002-02-01 23:05:19 PST 
 

Thanks to the help I've received from this group, I've been successful in
building a number of binary RPMs from the associated source RPMs.

Although this is a straightforward procedure in most cases, it is not well
documented, and at least in my case there was considerable initial confusion
about what was going on.

As an RPM newbie, I found that I had to do a lot of reading, including a good
part of Maximum RPM, before I had learned enough to feel that I really
understood the procedure.

I wrote a mini-HOWTO based on my experiences.  

I would greatly appreciate any corrections or suggestions that the group may
have to offer.

Regards, KBK

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

BUILDING BINARY RPM PACKAGES FROM SOURCE RPMS mini-HOWTO

Kurt B. Kaiser  kbk@shore.net  
Version 0.11  28 Jan 2002

0. Introduction.  While binary RPMs provide a convenient way to upgrade
   software, it often happens that the desired version has dependencies or
   other incompatibilities with the target system, and the desired binary RPM
   cannot be installed.  In that case, it is better to build the binary RPM on
   the target system from the source RPM. 

   Also, it is sometimes desirable to make small changes to the software
   prior to installation.  An example would be to add support to ghostscript
   for a specific printer.

   The existing RPM documentation is oriented either towards simple
   installation of binary RPMs or towards building RPMs from the original
   source archives.  Learning enough to reliably create binary RPMs from source
   RPMs involves assimilating a large part of the rather extensive
   documentation on RPMs.  

   The purpose of this HOWTO is to provide a concise guide to this essentially
   straightforward procedure.

   To avoid the risks associated with building RPMs as root, this procedure
   requires root permissions only when installing the binary RPM.

1. Create an .rpmmacros file to instruct rpm to build in a directory off your
   home directory. (This version of .rpmmacros could also be placed in
   /etc/skel/.bashrc)
   
        cd
        cat < .rpmmacros
        %HOME       %{expand:%%(cd; pwd)}
        %_topdir    %{HOME}/rpm
        EOF

2. Create the rpm directory structure in your home directory:

        mkdir rpm
        cd rpm
        mkdir BUILD RPMS SOURCES SPECS SRPMS
        cd

3. Download the .src.rpm to your home directory.

4. Install the source RPM.  rpm will place the source tar archives and patches
   in ~/rpm/SOURCE and the spec file, foo.spec, will be in located in
   ~/rpm/SPECS:

        rpm -i foo-1.0.0-1.src.rpm

5. Unpack the tarfiles into the BUILD tree and apply the patches in
   SOURCE to the BUILD tree, with a record of the steps taken saved in bp.log:
        
        cd rpm/SPECS
 rpm -bp foo.spec   &> bp.log

   (At this point see Appendix A for suggestions on how to make small changes
   to the sources prior to building the package.)

6. Build the binary .rpm package (Note 1):

        rpm -bb --clean foo.spec  &> bb.log

   Always inspect the bb.log to assure that the build was error-free!

7. Install the binary .rpm package, updating the RPM database:

        cd ~/rpm/RPMS/i386      (for 386 architecture)
        su
        rpm -Uvh foo-1.0.0-1.i386.rpm
        exit

8. Clean up the rpm/ directories.  Cleaning can be done with rm commands or the
   SOURCE and SPEC directories can be cleaned out with:

        cd ~/rpm/SPEC
        rpm --rmsource foo.spec  (This switch could be added in the -bb step)
        rm foo.spec

9. If no changes are required in the sources, and now that you understand
   the process, steps 4 through 6 can be done in one step by calling RPM with
   the --rebuild switch:

        rpm --rebuild foo-1.0.0-1.src.rpm  &> rebuild.log


APPENDIX A - SOURCE MODIFICATION
================================

There are times when it is necessary to make changes to the sources before
building the binary RPM.  If the changes are extensive, the best method is to
create a patch file and add it to the SOURCE directory and the .spec file. The
techniques for doing that are beyond the scope of this HOWTO.

However, small changes can easily be made by using echo and sed commands in the
.spec file.

The policy when building RPMs is that changes should not be made to the
original "pristine" source archives.  Instead, patch files and the .spec file
are used to modify the BUILD tree during the build process, and the .spec file
can also tailor the installation.

A1. Study the code in the BUILD tree and the ..../SPEC/foo.spec file until it
    becomes clear how the build works and what changes are necessary  :-)

A2. To add files to the package, tar them up and place the tar archive in the
    SOURCE directory.  Add another Source line (the 5th in this case) to
    foo.spec:

 Source4: morefiles.tar.gz

A3. Then add commands after the %setup macro, but before the %build script, to
    install the files into the BUILD tree.  In this case, The contents of the
    archive will be added to the ~/rpm/BUILD/foo-1.0.0-1/src directory:
    
 tar xzvf %{SOURCE4} -C src

A4. You can now add commands to the .spec file to make changes to the Makefile
    (or any other file in the BUILD tree).  Use echo with >> to append lines to
    the end of a file, and sed to make changes in the middle of a file.  Study
    .spec files to see examples of how to do this.

A5. Add comments to the top of the %changelog script (with the date in the
    proper format) describing the changes which have been made.

A6. Change the Release tag in the .spec file: e.g. 1 to 1a.  An alpha suffix is
    recommended for changes not made by the package owner.

A7. Repeat the rpm -bp command, inspect the new BUILD tree, and iterate until
    you get the BUILD tree the way you want it.

A8. Test the install (Note 2):

        rpm -bi --short-circuit foo.spec  &> bi.log

A9. If all is well, you will want to build both a binary RPM and a new source
    RPM:

        rpm -ba foo.spec  &> ba.log

    Always inspect the ba.log to be sure that everything completed without
    error.


NOTES 
===== 

1. If the .src.rpm was not designed to install in a "staging area," i.e. make
   its working install in a world-writable location like /var/tmp (by setting
   the Buildroot macro in the .spec file), it may be necessary to do -bi, -bb,
   -bs, and -ba as the root user :-( .  Always check the bX.log to make sure
   rpm completed without errors!  If it is necessary to go root, use

        su -p   

   to preserve the environment set by .rpmmacros.  Otherwise, rpm will be
   looking in /usr/src/redhat/SOURCES for its files!  (It will also be
   necessary to do the cleanup as root.)  

   The install phase of a .src.rpm build is only used to set up the
   configuration which will be packaged in the binary .rpm, and really should
   be deleted after the .rpm is created.  It is not intended to be the system
   install, since the RPM database is not updated.  Nonetheless, sometimes this
   install is done in standard locations like /usr/bin and not properly
   removed.

   Troubleshooting hint: GNU make supports using the DESTDIR variable to
   specify a staging area, and a typical %install script command is

        make DESTDIR=$BUILD_ROOT install

   Another approach is to use the %makeinstall macro in the %install script.

2. If problems are experienced with -bi, it may be useful to do a compile first
   with -bc. The --short-circuit switch is helpful when building big source
   packages since it avoids going back to the unpack stage each time -bc or -bi
   is run.

3. Installing software from a .src.rpm has several advantages over building
   from source using the traditional ./configure, make, make install approach.
   First, the RPM database is maintained, allowing query, upgrade, and
   uninstall.  Second, if changes to the source are made via the .spec file and
   patch files as suggested, an audit trail can be established which lives with
   the revised .src.rpm, not in some private revision control system.  However,
   the audit trail is not as rigorous as cvs, and it is up to the maintainer to
   leave a proper record of the changes made, particularly in the .spec file.

4. For further documentation, consult the RPM-HOWTO, the RPM man page, the book
   _Maximum RPM_ by Ed Bailey, and the www.rpm.org web site.  Much of this
   documentation is rather out of date, so also review the files in your
   /usr/lib/rpm-x.x.x and also the /usr/src/rpm/macros file.  Searching the
   linux.redhat.rpm group on groups.google.com is helpful if all else fails.


ACKNOWLEDGEMENTS
================ 

The documentation at www.rpm.org, the participants on rpm-list@redhat.com
(usenet linux.redhat.rpm) and particularly:

John Thompson showed the way and got me started on .src RPMs
Ned Ulbricht clarified how to install source RPMs and build without being root
Jim Knoble provided a relocatable way of creating the .rpmmacros file

Any errors are my responsibility and due to my lack of understanding of what
these people tried to explain to me.  Corrections and suggestions will be
appreciated.

HISTORY
=======

27 Jan 2002 - Kurt B. Kaiser - Initial Release
        Building Binary RPM Packages from Source RPMs mini-HOWTO


COPYING
=======

(C) 2002 Kurt B. Kaiser

Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU Free Documentation License, Version 1.1 or any later version
published by the Free Software Foundation; there are no Invariant Sections, no
Front-Cover Texts and no Back-Cover Texts.