Linux Step By Steps
Building Optimized RPMs on Fedora Core 2.
while maintaining compatibility with standard apt and yum repositories.

by Tim Wunder

Distro: Fedora Core 2 with updates from, and
Date Submitted: March 21, 2005

I use Fedora Core 2 as my current distro of choice, perhaps I'm a redhat whore, or perhaps I'm lazy. But Fedora Core 2 has pretty much met my needs since I installed it. And with apt4rpm and repositories such as KDE-redhat, ATrmps and FreshRPMS. it's pretty easy to maintain. The cost of that ease of maintenance? Precompiled packages.

I read all the talk of gentoo, and the benefits of compiling from source and all that, and I feel like I'm missing out on the real LINUX experience. But, what's a guy to do? I don't want to compile from source and end up losing that ease of configuration and updating I get by using apt4rpm. And compiling from source on an RPM distro can just wreak havoc on maintainability. Sure, there's checkinstall, but that's got its own issues. Grabbing the source for something like KDE, compiling it and installing it with checkinstall is a daunting task (yeah, I've done that). And then you run the risk of having all that hard work destroyed by your next 'sudo apt-get update && sudo apt-get distupgrade.'  

Well, the answer, I surmised, is to rebuild the SRPMs. But, I didn't want to just download 'em and execute an 'rpmbuild -ba <blah blah blah>.src.rpm, I wanted an "optimized" build. And I wanted to keep that beloved maintainability. And just for fun, I wanted to do this all as user, and not root. So, here's what I did:

RPM build environment
On redhat-based distros, like fedora core, the default RPM build environment is located in /usr/src/redhat. But, in order to build from SRPMs there, you need to be root, or at least have root priveledges. I wanted to do this as an ordinary user. So, I asked google how to do that, and hit this lovely reference at Dag Wiers website. In it is described how to set up your very own RPM build environment.

So, I created my build envoronment on a partition with lots of room, my /music partition. Yeah, music and SRPMs don't really go together, but, in the Linux world, we can adapt. I then created a ~/.rpmmacros file to tell rpm where this build environment can be found, and to set some defaults.
$ cat ~/.rpmmacros
%packager               Tim Wunder
%distribution           fedora core 2
%dist_tag               .2
%_topdir                /music/SRPMs/redhat

See that %dist_tag reference? That's what allows my RPMs to co-exist with the stock kde-redhat RPMs without apt-get stepping on them. See, without that, when building kdelibs from source, I'd build a package called kdelibs-3.4.0-1.1.kde, because kde-redhat's kdelibs spec file has a reference to :
Release: 1.1%{?dist_tag}.kde
And if my packages were built like that, apt-get would want to upgrade kdelibs next time I ran 'sudo apt-get update && sudo apt-get dist-upgrade.' So, I either have to edit every spec file I build from, set the dist_tag, or individually upgrade every pre-packaged update apt-get finds in the repositories I use. I chose to set the dist_tag.

Oh yes, the optimizations. I have a PC with an AMD Duron 1GHz processor. Well, all the fedora core 2 packages provided by the aforeentioned repositories are built for i386. There's a big difference between i386 and Duron. So I should be able to get a performance benefit from building for my architecture. Unfortunately, I hadn't the first clue about how to build "optimized" when I embarled on this lark. So, I asked someone who did know. Asked it on in fact. In the #linux-users channel. A good friend of Linux, and maintainer of the Linux-SxS website, doug, helped to find the proper settings to tell gcc (and g++) to build for my architecture. The magic environment variables are CFLAGS and CXXFLAGS. For a Duron, the optimizations I used are:
$ env|grep FLAGS
CXXFLAGS=-O3 -pipe -march=athlon-tbird -fexpensive-optimizations
CFLAGS=-O3 -pipe -march=athlon-tbird -fexpensive-optimizations
I placed the following in /etc/profile to ensure that every time I build something from source, or SRPM, it'd be optimized for my Duron processor:
# Added compile time optimizations 3/7/05 - tpw
export CFLAGS="-O3 -pipe -march=athlon-tbird -fexpensive-optimizations"
export CXXFLAGS="-O3 -pipe -march=athlon-tbird -fexpensive-optimizations"

So, now I have an environment that builds optimized RPMs from SRPMs provided by known repositories, that when installed, maintain compatibility with those repositories. But, to really put the icing on the cake, I found out how to build them so that I know that the RPMs are, indeed, the optimized versions. That is, the RPMs built get built as .athlon RPMs. The secret? A little setting in my ~/.rpmrc file called optflages:
$ cat .rpmrc
optflags: athlon -O3 -pipe -march=athlon-tbird -fexpensive-optimizations
That, and building the RPMs with --target=athlon as follows:
rpmbuild  -ba --target=athlon kdelibs.spec
Doing this allowed me to create .athlon kdelibs RPMs.
$ ll ../RPMS/athlon/kdelibs*
-rw-rw-r--  ... 18161743 Mar 20 00:26 ../RPMS/athlon/kdelibs-3.4.0-1.1.2.kde.athlon.rpm
-rw-rw-r--  ...  1928660 Mar 20 00:26 ../RPMS/athlon/kdelibs-debuginfo-3.4.0-1.1.2.kde.athlon.rpm
-rw-rw-r--  ...  1309724 Mar 20 00:26 ../RPMS/athlon/kdelibs-devel-3.4.0-1.1.2.kde.athlon.rpm
So far, I've done QT, kdelibs and kdebase, and there's a noticable difference in the response time of my desktop. My next task will be to try and do the same thing with a kernel SRPM, to see what difference that might make.

Ain't Linux fun?
If you have any questions about this process, or just wanna say hi, I tend to hang out on #linux-users on during the day, and sometimes on weekends. Fire up your favorite IRC client and join the channel. Feel free to e-mail me, too.