Saturday, April 25, 2009

Building RPM packages for Fedora

Here's a quickie tutorial on how to build rpm packages for Fedora. I was going to checkout Tribler and build an rpm package for it but installing Tribler on F10 box was such royal pain in the ass that I've given up on it, well at least until Fedora 11 hits the ftp sites next month.

Tribler is your friendly next-generation bleeding-edge p2p tool. And it sounds awesome too based from the web site description. Unfortunately, it's too bleeding-edge for me :-( I wanted to check out an alternative to bittorrent since the TPB trial didn't go well for the operators of the site (they've just been handed a guilty verdict) but it looks like I have to wait it out until most of these next-generation bittorrent tools mature.

In any case Tribler is such a pain because one of the package it requires is python-apsw (*sigh* they had choose this package when there are other more established and well-supported interface to SQLite and nope it's not package as Python eggs either which would have been too easy for the developers).

So ok, I don't mind building it manually, but python-apsw requires sqlite-3.6.12 version. F10 only shipped sqlite-3.5.9, you can upgrade it of course, but sqlite is used by a number of packages, so upgrading it might have some unforseen consequences down the road.

Anyways, I digress. Since I've already put up the time and effort in learning how to build rpm packages, I might as well build something that I can blog about (my cheatsheet for future projects).

First off, best practice for building rpm state that you do it as regular user _not_ as root. We'll package the nano text editor since it's small and nifty utility. Also, I'm assuming that you have Internet connection.

Step1:

Download nano-2.0.9.tar.gz package (the latest as of this writing) from:

http://www.nano-editor.org/download.php


Step2:

Install the development tools required to build the rpm packages (here you need to be root unless you've setup a sudo account).

# yum -y groupinstall "Development Tools"
# yum -y install rpmdevltools
# yum -y install rpm-build

Also, make sure to uninstall the nano package.

# yum -y remove nano

Step3:

Setup the rpm work tree

$ cd ~/
$ rpmdev-setuptree rpmbuild

Note: The rpmdev-setuptree will create the ~/.rpmmacros file and the rpmbuild directory. And inside the rpmbuild directory, you should see the following subdirectories:
  • BUILD is where the actual build process takes place.
  • RPMS is where you can find the rpm package file if your build is successul.
  • SOURCES is where you put the nano source you've downloaded.
  • SPECS is where you create the nano.spec file
  • SRPMS is where you can find the source rpm package if your build is successful.
Step4:

Move the nano source file to the ~/rpmbuild/SOURCES directory.

In your ~/.rpmmacros file, add the following settings:

%packager Your_Name_Here plus email address
%vendor Your_Fictitious_Vendor_Here

Step5:

Create the nano.spec file below. Now this is the tricky part since this is where most of the magic happens when creating rpm packages. A lot of the settings here are pretty cryptic.

$ cd ~/rpmbuild/SPEC
$ rpmdev-newspec nano

The rpmdev-newspec will create the nano.spec file which will serve as your template spec file, fill in the blanks and you're set.

For clarity of steps, I've put the content of nano.spec file further below.

Step6:

Create the rpm package using the following steps:

Build the package, this is the "%build" stage in the nano.spec file.

$rpmbuild -bc nano.spec

If you got a clean build, the last line in the output is "+ exit 0", run the "%install" part of nano.spec file.

$rpmbuild -bi nano.spec

If everything build cleanly, you can then create the source and rpm file.

$rpmbuild -ba nano.spec

Actually, if you're pretty sure that your spec file is written correctly, you can proceed directly to "rpmbuild -ba nano.spec". I used "-bc" and "-bi" switch to catch any errors/problems in my spec file.

You should now have source rpm package in your ~/rpmbuild/SRPMS and the binary rpm package at ~/rpmbuild/RPMS/i386 directory.

Success!!

Step7:

Install the nano rpm package (if you haven't done so, remove the default nano package installed on your system, and run this command as root):

$ su -
# yum remove nano
# cd /home/
# yum localinstall ~/rpmbuild/RPMS/i386/nano-2.0.9-1.fc10.i386.rpm --nogpgcheck
# rpm -qi nano

Sweet!

Note: since we didn't signed our rpm package, we need to use --nogpgcheck.

Here's the content of nano.spec file. Ignore the line number, I use it as reference in describing the settings:
  1. Name: nano
  2. Version: 2.0.9
  3. Release: 1%{?dist}
  4. Summary: GNU nano is a small text editor in Linux
  5. Group: Applications/Editors
  6. License: GPLv2+
  7. URL: http://wwww.nano-editor.org/
  8. Source0: nano-2.0.9.tar.gz
  9. BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release})

  10. BuildRequires: ncurses-devel, autoconf, gettext-devel, groff
  11. Requires(post): /sbin/install-info
  12. Requires(preun): /sbin/install-info

  13. %description
  14. GNU nano is a small and friendly text editor.

  15. %prep
  16. %setup -q

  17. %build
  18. %configure --enable-all
  19. make

  20. %install
  21. rm -rf %{buildroot}
  22. make DESTDIR="%{buildroot}" install
  23. rm -f %{buildroot}%{_infodir}/dir

  24. %find_lang %{name}

  25. %post
  26. /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir
  27. exit 0

  28. %clean
  29. make clean
  30. rm -rf %{buildroot}

  31. %files -f %{name}.lang
  32. %defattr(-,root,root,-)
  33. %doc AUTHORS BUGS COPYING ChangeLog INSTALL NEWS README THANKS TODO
  34. %{_bindir}/*
  35. %{_mandir}/man*/*
  36. %lang(fr) %{_mandir}/fr/man*/*
  37. %{_infodir}/nano.info*
  38. %{_datadir}/nano

  39. %changelog
  40. * Fri May 8 2009 Fedora Release
  41. - First build of nano
Line1 and line2/4/5/6 are self-exlanatory.
Line3: refers to release number of the package. The %{?dist} is macro that translate into nano-2.0.9-1.<fc10>i386. So basically %{?dist} is translated in to the name and version of your distro.
Line5: The list of valid groups can be found at /usr/share/doc/rpm-4.6.0/GROUPS
Line8: refers to where you can find the source file for nano. This is the ~/rpmbuild/SOURCES directory
Line9: This is the directory where 'build' happens. This directory is created on the fly in /var/tmp.
Line11: Dependencies you need to compile your source file.
Line12: Scriptlet to run after you install nano. Basically, this is the utility you use when you install an Info file from the source into your system.
Line13: Scriptlet to run before it uninstall itself.
Line18/19: Basically untar the nano source file into the BUILD directory. The -q option means to stay quiet (do not show output to the screen).
Line21-23: set the configuration and then run 'make' (compile the software).
Line25-28: This where 'packaging' of rpm happens.
Line30: refers to the /usr/share/locale directory where nano.mo files will be installed
Line32: Scriptlet to install the info and man pages to the appropriate directory.
Line36-38: Remove all the directory created during the 'build' process. In this case, the %{buildroot} refers to the directories created in ~/rpmbuild/BUILDROOT.
Line40: These are the binary files, documentation, config, etc that you want your rpm package to install on your system.
Line41: Default attributes/permission of files. The first '-' refers to file permission, the first 'root' refers to owner of the file, second 'root' refers to group owner, and second '-' refers to directory permission.
Line43-47: Directory where your binaries/man pages will be installed.
Line49-51: This is the log file that shows up when you run "rpm -q --changelog nano"

As usual, there are heaps of tutorials on how to build rpm packages. You can find the most definitive guide here. But I've mostly used Fedora-specific tutorials found here, here, and here.

1 comment:

ugyen said...

hi gene,
this is ugyen. nice blog on open source. now i know how to build RPM packages.

Would love to see more post on different topic.

well i solved the problem on vncserver and yum repository that i asked you in the email.

Before i ask you, first i will check your blog.

thanks gene.
keep it up