A great way to live life is to keep packages in RPM's, set up your own SRPMS and use yum. To this end, here are my notes on building rpms. Most, if not all of this methodology was stolen from Tim Pickering, who maintained an RPM collection (that I inherited in 2009 when he fled the country) for the MMT at The MMT RPM repository
In a nutshell, you get the tarball for the package you want to fuss with, keep it pristine, and write a specfile, possibly keeping any changes you make separate as patches, and perhaps augmenting the tarball with some config files as needed.
If you are going to be diving deeply into this (and there seems to be no middle ground in the package building game), take a look at the Fedora packaging guidelines on the Fedora Project wiki.
yum install rpm-build rpm-signI have been bitten several times by not installing the "rpm-sign" package. You only need it if you want to sign rpms, but if you neglect to install it and use the --sign switch to rpmbuild, you get a bizarre error about your rpm file being missing. In fact it is not your rpm file that is missing, but whatever file is needed to sign the rpm. You have been warned. This package didn't exist until recently, then fedora for some reason split these things out into their own package.
Once this is done, there are 3 things you will need to set up before you dive in and start building rpms:
Some people also have a SPECS directory, in which case spec files get placed there, while the tarball and patches go into SOURCES, thus far I am happy to omit this and have the whole works in SOURCES.
The directories RPMS and SRPMS can be links to places in your web site documentroot if you are making these things publicly available.
include: /usr/lib/rpm/rpmrc macrofiles: /usr/lib/rpm/macros:/usr/lib/rpm/%{_target}/macros:/etc/rpm/macros.specspo:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros
This is pretty big, so I provide it as a link. I got this from Tim Pickering, who got it long ago from Mike Harris at Red Hat, and I make the file available at this link: .rpmmacros
There is absolutely no reason to do this if you only use rpms internally, but if you are offering them to other people, and especially if RPM's you are building are being hosted on sites you do not control, then you really ought to be signing them.
To do this, you have to set up your own GPG digital signature. This really is not all that hard. GPG was already part of my fedora install. I have the details on all of this at:
If you are starting with a source RPM, you could put it into the SRPMS directory. This is probably the most reasonable thing to do, but beware. If you rebuild the source RPM and neglect to increment the version number in the spec file, this source RPM will be overwritten. Of course you will never do that.
If you are confident that you don't need to fiddle with anything, you can go straight from the source RPM to a binary RPM via:
cd SRPMS rpmbuild --rebuild yada.src.rpmThis is just the thing if you are rebuilding a driver for a new kernel and are absolutely sure that no kernel API changes affect your driver (as if THAT ever happens). Most of the time, you will need to fiddle, and the first step is to unpack the source RPM as follows:
cd SRPMS rpm -i package.ver.src.rpmThis will unbundle the source rpm and put its contents into the right places (as dictated by the settings in .rpmrc and .rpmmacros). In general, everything goes to a newly minted directory under SOURCES with a name like SOURCES/package-ver. This directory will include the spec file, the pristine tarball, and any patches.
I was once innocent about how things work from this point. I used rpmbuild -bp to unpack the tarball (this unbundled it, placing it under the BUILD directory). I then made changes to a few of these files, and then issued the rpmbuild -bb to build a trial package. This threw away all of my changes when it began the process by once again unpacking the pristine tarball. This did not make me happy, but such is the price of education. (We are also getting ahead of ourselves.)
What should I have done? Well I should have either gone through the process of unpacking twice (described below) and using diff to generate a patch file or I should have made my changes and regenerated a new tarball. In any event my working tree should NOT be kept under BUILD, this should be left alone as a place for rpmbuild to do its work.
Before building, I cd to SOURCES/package-ver and do one or more of the following.
You could consider putting the following aliases in your .bashrc:
Let's say you are working on the xephem package.
One tree (the pristine sources) you could call xephem-3.7.3-ORIG.
The other (the one you hack around in) you just call xephem-3.7.3.
What I do to achieve this is:
cd SOURCES/xephem-3.7.3 rpmbuild -bp xephem.spec cd ../BUILD mv xephem-3.7.3 xephem-3.7.3-ORIG cd SOURCES/xephem-3.7.3 rpmbuild -bp xephem.spec
You may find yourself working on a package that already has a patch file. You could apply that patch and treat the patched sources as your reference pristine sources. By doing this, you would be working up a set of changes from those patched sources to whatever you ultimately need, thus creating a second independent patch file.
In a case like this, I prefer to just have one patch file, so I want to create a truly pristine source tree. In a case like this, I go into the spec file and comment out the patch command in the %prep section, then use rpmbuild -bp to expand the original sources. After doing this, I uncomment the patch command and then use rpmbuild -bp to produce my working sources,with the patch applied.
Once you do this, you run make inside the BUILD/xephem-3.7.3 tree and hack to your hearts delight. But when you are done, be sure to save this work somehow, because if you do any rpmbuild command after making edits, you will delete and overwrite all of your work!.
When everything looks good, you make the patch via:
cd BUILD diff -Naur xephem-3.7.3-ORIG xephem-3.7.3 >xephem.patchWhat ends up in the source RPM that you are building is the pristine tarball and your diff. You can have many diffs if you are that crazy (or if there is hackery from various sources that you want to keep segregated). What makes the most sense though is to apply all your diffs and hacking to your source tree and then generate just one diff that reflects the sum total of what needs to change and distribute that.
The spec file needs to indicate (in the %prep section) that your diff needs to be applied.
If you are the package author, there is no reason to have anything to do with diffs. You control the sources and can make the pristine sources do the right thing.
Until then, perhaps the best thing to do is to grab the source RPM for some package that you think might be similar to what you want to work with and take a look at the spec file and/or use it as a starting point for what you want to do.
rpmrebuild -ep package.rpmThis in my case launched the "vim" editor with what looked a lot like a condensed spec file for me to edit. I was able to delete and modify dependencies and change the name of the RPM. Then when I exit the editor session, it rebuilds the rpm. Curiously, it places the result into my usual RPM build area, but it tells you the full path where it places it, so all that is necessary is to pay attention. It seemed to work great to fix a dependency issue for a package that was impossible to rebuild from the source RPM for various reasons.
The Gnu debugger (gdb) was enhanced to allow debugging information to be read from separate files (it used to be the case that an executable had to be specially built with certain compiler switches to include debug information). The rpmbuild program (actually the RPM macros) has been set up to generate this information and place it into a separate "debuginfo" package whenever a package is built. Details about how this is done may be found in the files in /usr/lib/rpm, in particular /usr/lib/rpm/find-debuginfo.sh.
This behavior can be suppressed by adding the following to your ~/.rpmmacros file:
%debug_package %{nil}(The string %define debug_package %{nil} is mentioned in some documentation, but that is apparently in error).
%define __strip /bin/trueThis fix is the least intrusive and is probably the best. Another fellow redefined a larger macro as follows:
%define __spec_install_port /usr/lib/rpm/brp-compressThis eliminates more than just the stripping, just how much more you can evaluate by inspecting the unmolested value of this macro via:
rpm --eval %__spec_install_post
cd /repodir createrepo .This creates the all important repodata file, which is a bunch of XML describing the repository.
Note that yum seems to cache information for some amount of time. If you modify a package, put the new version in your repository, do the createrepo thing to rebuild your repodata, then try to update a machine, it may frustrate you by insisting your package is up to date when you know it is not. What will solve this is:
yum clean metadata
You can use the big hammer and do yum clean all, but this may be overkill (or not). Overkill does have it's place, and sometimes caching sucks.
There are also some books. an ancient classic (but still quite useful) is the book: Maximum RPM. As of 2009, many inexpensive used copies are available, other than that it is out of print.
Adventures in Computing / [email protected]