The spec file is made up of several sections or blocks of code. For us to take a look at this, lets grab a source RPM and install it:
root@linuxbox ~/# wget http://rpms.5dollarwhitebox.org/clean/pLsearch/pLsearch-0.1.7-1.bjd.noarch/SRPMS/pLsearch-0.1.7-1.bjd.src.rpm root@linuxbox ~/# rpm -Uvh pLsearch-0.1.7-1.bjd.src.rpm 1: pLsearch ############################# [100%] root@linuxbox ~/# cd /usr/src/redhat/SPECS root@linuxbox SPECS/# ls pLsearch.bjd.spec
Now using your favorite editor (I use vim) open it up. The first section is known as the Preamble, and looks something like this:
Summary: pLsearch was created to assist System Administrators in their quest for grep'ing logs and other files for specific content
Name: pLsearch
Version: 0.1.7
Release: 1.bjd
Packager: BJ Dierkes \<wdierkes@5dollarwhitebox.org\>
Vendor: BJ Dierkes \<wdierkes@5dollarwhitebox.org\>
Copyright: GPL
Group: Utilities/System
Source0: http://superb-east.dl.sourceforge.net/sourceforge/plsearch/pLsearch-%{version}.tar.gz
Buildroot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: perl >= 5.8
Requires: perl >= 5.8
Requires: perl(File::Locate)
Requires: perl(Getopt::Long)
Requires: perl(PerlIO::gzip)
Patch0: pLsearch-0.1.7-sample.patchThis is all very straight forward. Some are optional (such as the Buildarch) and some are required. Allow me to explain a bit about each:
A few things should be touched on. First, either the Version or Release need to be incremented whenever the Spec file changes. Secondly, it is very important that you are accurate with the BuildRequires/Requires directives as this will help guarantee that the software will Build/Install properly on other systems.
After the preamble we move on to the next couple of sections. The following is a snippet out of the Spec file for pLsearch:
%prep
%setup -q
%patch0 -p1 -b .sample
%build
# Nothing to do here, but if it was a C program we would do the usual
# ./configure --with-option
# make DESTDIR=$RPM_BUILD_ROOT
#
%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
# Depending on the software, we might do make install here
mkdir -p ${RPM_BUILD_ROOT}%{_bindir}
install -o root -m 755 pLsearch ${RPM_BUILD_ROOT}%{_bindir}/pLsearch
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOTThe %prep section allows us to 'Prepare' for building. This will be anything from patching, to setting environment variables, to running a ./configure command. As this is a Spec for a Perl app there is no './configure' line or 'make' statements.
The %setup section is part of the %prep section. This is a basic example above where the source code is extracted to the BUILD directory, and then rpmbuild changes into the source directory (/usr/src/redhat/BUILD/pLsearch-0.1.7).
The macro '%patch0 -p1 -b .sample' is equivalent to the command 'cat patch-0.1.7-sample.patch | patch -p1 -b .sample'.
The %build section is where we build any necessary source code. As this is a Spec for a Perl app there is no './configure' line or 'make' statements.
Once the software is built we install any necessary files using the %install block. To keep things clean, the first thing we do is to 'rm -rf' the $RPM_BUILD_ROOT. Once that is done, we create any directories in the Build Root, and then install files to them. Here we are introduced to the use of some RPM macros such as %{_bindir}. The line '${RPM_BUILD_ROOT}%{_bindir}/pLsearch' equates to '/var/tmp/pLsearch-0.1.7/usr/bin/pLsearch'. We only install files to a temporary location when building RPMs. In the actual RPM, the $RPM_BUILD_ROOT prefix is removed and files are actually installed in the proper places.
Finally we want to clean up our mess with the %clean section. Here we generally just remove the $RPM_BUILD_ROOT.
On to the last group of sections:
%files
%{_bindir}/pLsearch
%doc README CHANGELOG
%changelog
* Thu Jan 18 2007 BJ Dierkes <wdierkes@5dollarwhitebox.org> - 0.1.7-1
- Beginning of spec buildThe %files section is used to specify the files that are packaged with the RPM. Any directories listed under a %files block will recursively include everything within the directory. However, if you just want to list the directory, use the '%dir' directive. NOTE: The most important thing is to only list directories and files that are installed by this package. Imagine the issues you might run into if you list '%dir %{_bindir}'... This package would try to claim '/usr/bin' on the target system, and I don't think I need to explain why that would be a bad thing.
The %doc directive installs the listed files to '%{_docdir}/%{name}-%{version}', or equally for this example '/usr/share/doc/pLsearch-0.1.7'.
One of the ultimately most important sections is the %changelog section. Any and all changes should be documented here. This section is often overlooked, however please make every effort to document your changes properly. Additionally, you will note that the date must be a specific format... any other format and you will receive errors.
So, just to bring everything together... the following is the complete Spec file for the pLsearch package:
Summary: pLsearch was created to assist System Administrators in their quest for grep'ing logs and other files for specific content
Name: pLsearch
Version: 0.1.7
Release: 1.bjd
Packager: BJ Dierkes <wdierkes@5dollarwhitebox.org>
Vendor: BJ Dierkes <wdierkes@5dollarwhitebox.org>
Copyright: GPL
Group: Utilities/System
Source0: http://superb-east.dl.sourceforge.net/sourceforge/plsearch/pLsearch-%{version}.tar.gz
Buildroot: %{_tmppath}/%{name}-%{version}-root
Buildarch: noarch
BuildRequires: perl >= 5.8
Requires: perl >= 5.8
Requires: perl(File::Locate)
Requires: perl(Getopt::Long)
Requires: perl(PerlIO::gzip)
Patch0: pLsearch-0.1.7-sample.patch
%description
pLsearch was written to assist SysAdmin's in grep'ing logs and other files for specific content, and then spitting it out in a pretty format which is generally easy on the eyes.
pLsearch uses the (s)locate database to search for specific files that the administrator wants to work with. It then accepts a query, and/or subquery, and/or inverted query which will then be used to grep through the located files for content. It is therefore a two way search. This is meant to be extremely useful for System Administration tasks such as attempting to track down exploitable FormMail applications that were being used to Send Spam as an open relay, or possibly used to search common files for a known exploits (such as "urldecode" in all files named "viewtopic.php" which is a well known phpBB exploit signature), etc.
%prep
%setup -q
%patch0 -p1 -b .sample
%build
# Nothing to do here, but if it was a C program we would do the usual
# ./configure --with-option
# make DESTDIR=$RPM_BUILD_ROOT
#
%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
# Depending on the software, we might do make install here
mkdir -p ${RPM_BUILD_ROOT}%{_bindir}
install -o root -m 755 pLsearch ${RPM_BUILD_ROOT}%{_bindir}/pLsearch
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%files
%{_bindir}/pLsearch
%doc README CHANGELOG
%changelog
* Thu Jan 18 2007 BJ Dierkes <wdierkes@5dollarwhitebox.org> - 0.1.7-1
- Beginning of spec build