Just a quick note on how to build RPMs
setting up build environment
RPMs should be built from a ”’standard user”’ account, ”’not root”’. This saves a lot of trouble when something goes wrong during package preparation/installation and keeps the build environment clean.
Here’s how to setup build environment in your home directory:
mkdir -p ~/build/{BUILD,RPMS,S{OURCES,PECS,RPMS}}
These directories are for:
BUILD – that’s the place where your source package will get untargzipped, patched and compiled
RPMS – will contain your RPMS when done
SOURCES – upload all source .tar.gz’s and your patches here
SPECS – .spec files with instructions on how to build your packages
SRPMS – source RPMS, a bit more about them below
Now you need to tell rpm-build where to look for these directories:
echo “%_topdir $HOME/build” > ~/.rpmmacros
and finally you need to install some software:
sudo yum install rpm-build redhat-rpm-config mock
(Keep in mind, that the list above is not complete as it doesn’t contain any compilers, libtools, automakes etc, that might be required to actually build your source package.)
and create a ’special’ user for the mock package (this is to allow fakeroot builds):
sudo useradd -M -d / -s /sbin/nologin mockbuild
building from SRPMs (easy!)
SRPMS (source RPMS) contain the .spec file and all necessary source files and patches needed to build a binary package. This can be usefull if there’s no binary package available for your platform but there’s a source one available for a similar one (redhat.srpms to build packages for centos).
One way to build a binary package from a source one is to:
rpmbuild –rebuild package-1.0.src.rpm
This will do all the magic and (hopefully) put a binary package in build/RPMS/$arch/
Other way is to install (as user, it will put all sources and patches to build/SOURCES and the spec file to build/SPECS) the source package first and then use rpmbuild:
rpm -i package-1.0.src.rpm
rpmbuild -ba ~/build/SPECS/package-1.0.spec
According to the documentation you can build RPMs from .tar.gzs if they contain a .spec file. You would do it by using -ta option for rpmbuild instead of -ba.
building from source
This means creating your own package from scratch. There’s how to do it:
First see if the package builds from source without any tweaking. Check if it (or the resulting package you want built) requires any special options to be passed to either ./configure or make. Also at this point think of any modifications to the original source code you’d like to have (changes in default config files, additional modules compiled in or removed from the package etc etc).
If you do need some changes done, this is a good time to make all the patches.
Make a clean and untouched copy of the untargzipped package:
tar xvfz moosoft-1.0.tar.gz
cp -Rvp moosoft-1.0 moosoft-1.0.orig
now make all the required changes in the moosoft-1.0 directory and generate patch or a set of patches:
diff -uNr moosoft-1.0.orig moosoft-1.0 > moosoft-1.0.bigpatch.patch
# or:
diff -uNr moosoft-1.0.orig/etc/moo.conf moosoft-1.0/etc/moo.conf >
moosoft-1.0.config.patch
diff -uNr moosoft-1.0.orig/doc/ moosoft-1.0/doc >
moosoft-1.0.documentation.patch
# etc… to generate multiple patches
Copy these patches and the original moosoft-1.0.tar.gz file to ~/build/SOURCES.
The last thing to do is to prepare a recipe for rpmbuild how to build your package. Create moosoft-1.0.spec file in ~/build/SPECS:
# _____________________________
# (__) / \
# (oo) ( This is an example .spec file )
# /-------\/ --'\_____________________________/
# / | ||
#* ||----||
# ^^ ^^
####
# package preamble
# one line description of the package
Summary: Very important Unix tool
Name: moo
Version: 1.0
# this marks the internal release version: moo-1.0-1.666.x86_64.rpm
Release: 1.666
License: BSD
# group you want your package in, mostly for GUI package browsers
# some example groups used by vendors:
# http://www.rpmfind.net/linux/RPM/Groups.html
Group: Networking/Daemons
# your name for example
Packager:
#
Source: http://full.url.to.the/package/%{name}-%{version}.tar.gz
Source1: moo.init
# list all your patches here:
Patch0: moo-1.0.etc.patch
Patch1: moo-1.0.documentation.patch
# list all packages required to build this package
BuildRequires: openssl-devel
Provides:
# list all packages that conflict with this one:
Conflicts: bse
BuildRoot: %{_tmppath}/%{name}-%{version}-build
####
# full length description
%description
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eros elit,
pretium eu vestibulum vel, blandit vel nisl. Fusce mattis volutpat
pellentesque. Etiam sit amet magna eget dui faucibus rutrum. Aliquam a ligula
erat. Proin metus tortor, sollicitudin et accumsan quis, hendrerit non leo.
Curabitur egestas neque sed nulla vulputate vel bibendum sapien tristique.
Vivamus malesuada, magna et semper iaculis, magna lorem adipiscing erat, vel
euismod enim nulla vel tortor. Vestibulum accumsan placerat sagittis. Sed
commodo pretium lectus et dignissim. Ut nec orci tellus.
#####
# this prepares a fresh build directory in ~/build/BUILD, useful macros here
# are:
# %setup - cleans any previous builds and untargzips the source
# %patch - applies patches
# any other commands here are executed as standard sh commands
%prep
%setup
%patch
%patch1
./configure --enable-something --with-something-else
#####
# this tells rpmbuild how to build your package, rpmbuild runs it as a sh
# script
%build
make
#####
# all the steps necessary to install your package into $RPM_BUILD_ROOT
# first step is to clear $RPM_BUILD_ROOT
%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
#install all files under RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
# now you can remove uneeded stuff
rm -f $RPM_BUILD_ROOT{_prefix}/sbin/rc.moo
#####
# NOTE: this section is optional
# commands run just before the package is installed
%pre
/usr/sbin/useradd -c "moo user" -r -s /bin/false -u 666 -d / moo 2> /dev/null
|| :
#####
# NOTE: this section is optional
# commands run before uninstalling the software
%preun
/sbin/service moo stop > /dev/null 2>&1
/sbin/chkconfig --del moo
#####
# NOTE: this section is optional
# commands run after installing the package
%post
/sbin/chkconfig -add moo
touch /var/log/moo
#####
# NOTE: this section is optional
# commands run after unistalling the package
%postun
/sbin/service moo stop
/usr/sbin/userdel moo
#####
# list all the files that are part of the package. If a file is not in the
# list rpmbuild won't put it in the package
# see below on how to automate the process of creating this list.
# some useful macros here:
# %doc filename - installs filename into /usr/share/doc/moo-1.0/
# %doc /path/to/filename - installs filename into /path/to/filename and marks
# it as being documentation
# %config /etc/config_file - similar for configuration files
# %attr(mode, user, group) file - lets you specify file attributes applied
# during installation, use - if you want to use defaults
%files
/usr/bin/moo
/usr/sbin/moomoo
# this will package the dir and all directories inside it
/example/of/a/dir
# this will package only the 'dir' directory
%dir /example/of/a/dir
#####
# document changes between package releases
%changelog
* Wed Jul 8 2009 Your Name Here
- another version of the package
* Mon Jul 6 2009 Your Name Here
- initial version of the package
To get the list of all installed files do
rpmbuild -bi ~/build/SPECS/moo-1.0.spec
this will go through prep, build and install steps of the spec file and install all files under $RPM_BUILD_ROOT, which in this case should be /var/tmp/moo-1.0-build.
ls -R1 /var/tmp/moo-1.0-build
and use the output to populate the %files section
Now the package can be build by running:
rpmbuild -ba ~/build/SPECS/moo-1.0.spec
building with modules
Sometimes it’s helpful to split one package into multiple modules. Here’s an example .spec file for a library, it will produce two packages: libmoo (with the shared objects provided by the library) and libmoo-devel (with all headers and static libraries)
# _____________________________
# (__) / \
# (oo) ( This is an example .spec file )
# /-------\/ --'\_____________________________/
# / | ||
#* ||----||
# ^^ ^^
####
# package preamble
# one line description of the package
Summary: An Example library
Name: libmoo
Version: 1.0
# this marks the internal release version: libmoo-1.0-1.666.x86_64.rpm
Release: 1.666
License: BSD
# group you want your package in, mostly for GUI package browsers
# some example groups used by vendors:
# http://www.rpmfind.net/linux/RPM/Groups.html
Group: Development/Libraries
# your name for example
Packager:
#
Source: http://full.url.to.the/package/%{name}-%{version}.tar.gz
# list all your patches here:
Patch0: moo-1.0.etc.patch
Patch1: moo-1.0.documentation.patch
# list all packages required to build this package
BuildRequires: openssl-devel
Provides:
# list all packages that conflict with this one:
Conflicts: bse
BuildRoot: %{_tmppath}/%{name}-%{version}-build
####
# changes in the preamble for libmoo-devel package
%package devel
Summary: libmoo development files and headers
Group: Development/Libraries
# -devel requires the main package
Requires: %name = %version
####
# full length description
%description
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eros elit,
pretium eu vestibulum vel, blandit vel nisl. Fusce mattis volutpat
pellentesque. Etiam sit amet magna eget dui faucibus rutrum. Aliquam a ligula
erat. Proin metus tortor, sollicitudin et accumsan quis, hendrerit non leo.
Curabitur egestas neque sed nulla vulputate vel bibendum sapien tristique.
Vivamus malesuada, magna et semper iaculis, magna lorem adipiscing erat, vel
euismod enim nulla vel tortor. Vestibulum accumsan placerat sagittis. Sed
commodo pretium lectus et dignissim. Ut nec orci tellus.
####
# full description of the -devel package
%description devel
static libraries and headers for libmoo
#####
# this prepares a fresh build directory in ~/build/BUILD, useful macros here
# are:
# %setup - cleans any previous builds and untargzips the source
# %patch - applies patches
# any other commands here are executed as standard sh commands
%prep
%setup
%patch
%patch1
./configure --enable-something --with-something-else
#####
# this tells rpmbuild how to build your package, rpmbuild runs it as a sh
# script
%build
make
#####
# all the steps necessary to install your package into $RPM_BUILD_ROOT
# first step is to clear $RPM_BUILD_ROOT
%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
#install all files under RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
# now you can remove uneeded stuff
rm -f $RPM_BUILD_ROOT{_prefix}/sbin/rc.moo
#####
# NOTE: this section is optional
# commands run just before the package is installed
%pre
/usr/sbin/useradd -c "moo user" -r -s /bin/false -u 666 -d / moo 2> /dev/null
|| :
#####
# NOTE: this section is optional
# commands run before uninstalling the software
%preun
/sbin/service moo stop > /dev/null 2>&1
/sbin/chkconfig --del moo
#####
# NOTE: this section is optional
# commands run after installing the package
%post
/sbin/ldconfi
#####
# NOTE: this section is optional
# commands run after unistalling the package
%postun
/sbin/ldconfig
#####
# list all the files that are part of the package. If a file is not in the
# list rpmbuild won't put it in the package
# see below on how to automate the process of creating this list.
# some useful macros here:
# %doc filename - installs filename into /usr/share/doc/moo-1.0/
# %doc /path/to/filename - installs filename into /path/to/filename and marks
# it as being documentation
# %config /etc/config_file - similar for configuration files
# %attr(mode, user, group) file - lets you specify file attributes applied
# during installation, use - if you want to use defaults
%files
%defattr(-,root,root,0755)
%attr(755,root,root) %_prefix/lib/lib*.so.*
%doc INSTALL ChangeLog
#####
# separate list of files for the -devel modules
%files devel
%defattr(-,root,root,0755)
%attr(755,root,root) %_prefix/lib/lib*.so
%attr(644,root,root) %_prefix/lib/*.a
#exclude *.la files
%exclude %_prefix/lib/*.la
#####
# document changes between package releases
%changelog
* Wed Jul 8 2009 Your Name
- another version of the package
* Mon Jul 6 2009 Your Name
- initial version of the package
building the package with rpmbuild -ba libmoo-1.0.spec will produce two files:
libmoo-1.0-1.666.arch.rpm and libmoo-devel-1.0-1.666.arch.rpm