Creating an x86_64 RPM of Boost 1.43.0 for CentOS 5

Boost C++ Libraries

This morning I decided that it's better to make an RPM of Boost 1.43.0 and install it than to try and package this stuff on my own. So I started out on what looks to be a long and painful journey. In the end, I'll have this as a record of what to do correctly and in what order. I'll have thankfully edited out all the errors and re-dos to come up with something that really explains what I've done.

At least I hope it's going to turn out that way.

Laying the Foundation of RPM Building

First, let's figure out what we need to build an RPM. Pretty simple: a place to do it. So I created a build directory and set up everything for a build:

  $ cd ~/vendor
  $ mkdir rpm
  $ cd rpm
  $ mkdir BUILD RPMS SOURCES SPECS SRPMS
  $ cd RPMS
  $ mkdir athlon i386 i486 i586 i686 x86_64 noarch

Then in my home directory, I created the file .rpmmacros that contained:

  %_topdir /home/rbeaty/vendor/rpm

where clearly, the point of the .rpmmacros file is to tell RPM where it's supposed to look for things as it goes about it's business. This is a huge load off my mind as I now can build in peace and not have to worry about deploying until I'm 100% sure it's ready to go.

At this point, I need the sources.

Getting the Sources in the Right Place

One of the tricks I'm using is to base this build off the boost-1.33.1 SRPM spec that I can get from CentOS. So I need to get the source RPM for the older version from CentOS 5's site:

  $ cd ~
  $ wget http://mirror.anl.gov/pub/centos/5/os/SRPMS/boost-1.33.1-10.el5.src.rpm

and then I can "install it" into the building location with:

  $ rpm -i boost-1.33.1-10.el5.src.rpm

At this point, I don't need boost-1.33.1-10.el5.src.rpm any longer.

If I go into the $RPM_BUILD_ROOT as we'll call it in this process (and it happens to be called that in the scripts) we can then:

  $ cd ~/vendor/rpm/SOURCES

and we'll see the contents of the source tree. Not bad for a few simple steps! Now we need to get the latest version of boost and place it here as well. With a simple:

  $ wget http://sourceforge.net/projects/boost/files/boost/1.43.0/
         boost_1_43_0.tar.bz2/download

(all one line) we will get the latest version of the code into the SOURCES directory as: boost_1_43_0.tar.bz2. It turns out that the bzip version of the file is important as the spec file expects to see it and we don't want to disappoint (or unnecessarily modify) it.

Update the Spec File for Boost 1.43.0

I decided to go a "minimal impact" plan on the spec file. I needed to change a few things. First, the version of Boost that I'm building. The spec file is in the SPECS directory in the main rom directory. The simple differences are:

  1. %define tarball_name boost_1_33_1
  2.  
  3. Name: boost
  4. Summary: The Boost C++ Libraries
  5. Version: 1.33.1
  6. Release: 10%{?dist}

becomes:

  1. %define tarball_name boost_1_43_0
  2.  
  3. Name: boost
  4. Summary: The Boost C++ Libraries
  5. Version: 1.43.0
  6. Release: 1%{?dist}

and since I've built it already I knew I didn't need a library I didn't have on this box, so I could comment it out. If you don't need to do this, even better.

  1. BuildRequires: libicu-devel
  2. Obsoletes: boost-doc <= 1.29.2
  3. Obsoletes: boost-python <= 1.29.2

becomes:

  1. #BuildRequires: libicu-devel
  2. Obsoletes: boost-doc <= 1.42.0
  3. Obsoletes: boost-python <= 1.42.0

In the %package section, I needed to change what this obsoletes:

  1. %package devel
  2. Summary: The Boost C++ headers and development libraries
  3. Group: System Environment/Libraries
  4. Requires: boost = %{version}-%{release}
  5. Obsoletes: boost-python-devel <= 1.32.2
  6. Provides: boost-python-devel = %{version}-%{release}

becomes:

  1. %package devel
  2. Summary: The Boost C++ headers and development libraries
  3. Group: System Environment/Libraries
  4. Requires: boost = %{version}-%{release}
  5. Obsoletes: boost-python-devel <= 1.42.0
  6. Provides: boost-python-devel = %{version}-%{release}

Then, in the %prep section, I commented out the patches that I didn't think needed to be made as it was running fine for me as-is.

  1. %prep
  2. rm -rf $RPM_BUILD_ROOT
  3.  
  4. %setup -n %{tarball_name} -q
  5. %patch0 -p0
  6. %patch1 -p0
  7. %patch2 -p0
  8. %patch3 -p0
  9. %patch4 -p0
  10. %patch5 -p0
  11. %patch6 -p0
  12. %patch7 -p0
  13. %patch8 -p0

becomes:

  1. %prep
  2. rm -rf $RPM_BUILD_ROOT
  3.  
  4. %setup -n %{tarball_name} -q
  5. #%patch0 -p0
  6. #%patch1 -p0
  7. #%patch2 -p0
  8. #%patch3 -p0
  9. #%patch4 -p0
  10. #%patch5 -p0
  11. #%patch6 -p0
  12. #%patch7 -p0
  13. #%patch8 -p0

Finally, the %build section could be drastically simplified due to the new build tools in boost:

  1. %build
  2. BOOST_ROOT=`pwd`;
  3. # build jam
  4. ./bootstrap.sh
  5.  
  6. # build boost with bjam
  7. ./bjam

and then completely commented out the %check section as I have no need of running any tests on boost - it is what it is.

Building and Verifying

Now that I have the spec file modified, I can build the RPMs:

  $ cd ~/vendor/rpm/SPECS
  $ rpmbuild -bb boost.spec

when this is all said and done, you should have the RPMs in the RPMS directory in the main 'rpm' directory - organized by the machine architecture.

To verify the contents of the RPMs, simply go into the directory and have a look at one:

  $ cd ~/vendor/rpm/RPMS/x86_64
  $ rpm -q -p boost-devel-1.43.0-1.x86_64.rpm

What you'll see is all the files that are in the RPM and it's just what you need.

Going for the Whole Burrito

If I want to build the i386 RPMs as well, I need to do two things. First, I need to edit the spec file to tell Boost to build 32-bit and to put the libs in the right place:

  1. %define tarball_name boost_1_43_0
  2. %define _libdir %{_exec_prefix}/lib
  3.  
  4. Name: boost
  5. Summary: The Boost C++ Libraries
  6. Version: 1.43.0
  7. Release: 1%{?dist}

and:

  1. %build
  2. BOOST_ROOT=`pwd`;
  3. # build jam
  4. ./bootstrap.sh
  5.  
  6. # build boost with bjam as 32-bit
  7. ./bjam address-model=32

and then I need to build the rpm with a slightly different command:

  $ cd ~/vendor/rpm/SPECS
  $ rpmbuild -bb --target i386 boost.spec

Of course, now that I think about it, it'd be just as easy to have two spec files - one for 64-bit and the other for 32-bit and then have two commands that build their RPMs, etc. Not a horrible situation at all, really.