\documentclass{beamer}

%packages
\usepackage{beamerthemeMarburg}
\usepackage{pgf}
\usepackage{alltt}

%beamer
%\beamersetaveragebackground{black}

%definitions
\definecolor{grey}{rgb}{.5,.5,.5}
\definecolor{green}{rgb}{0,.67,0}
\definecolor{orange}{rgb}{.67,.33,0}
\definecolor{purple}{rgb}{.67,0,.67}
\definecolor{cyan}{rgb}{0,.67,.67}

%titlepage
\title{Building RPMs}
\author{Josko Plazonic\\Princeton University\\ \&\\ Thomas Uphill\\ Institute for Advanced Study}

\begin{document}

%\color{white}
\frame{\titlepage}

\frame{\tableofcontents}

% take a source rpm from i386 and rebuild and install on sparc.
\section{What is RPM?}

\begin{frame}
\frametitle{What is RPMs?}

RPM Package Manager\\\pause
Two types of RPM packages.\\\pause
\begin{itemize}
%\color{white}
\item binary\pause
\item source
\end{itemize}
\end{frame}%what is rpm

%What type of rpm is this?\\\pause
\begin{frame}
\frametitle{filenames}

\centerline{{\bf name} - {\bf version} - {\bf release} . {\bf arch} . {\bf rpm}}
\pause
\centerline{{\tt\bf tar} - {\bf 1.13.25} - {\bf 4.7.1} . {\bf i386} . {\bf rpm}}
\end{frame}%filenames

% convention only, the header contains the real information

\begin{frame}[containsverbatim]
{\bf rpm -qi tar}
\tiny
\begin{alltt}
Name        : tar                          Relocations: (not relocateable)
Version     : 1.13.25                           Vendor: Red Hat, Inc.
Release     : 4.7.1                         Build Date: Tue 10 Sep 2002 07:10:58 AM EDT
Install date: Thu 12 Dec 2002 06:14:11 PM EST      Build Host: stripples.devel.redhat.com
Group       : Applications/Archiving        Source RPM: tar-1.13.25-4.7.1.src.rpm
Size        : 273826                           License: GPL
Packager    : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
Summary     : A GNU file archiving program.
Description :
The GNU tar program saves many files together in one archive and can
restore individual files (or all of the files) from that archive. Tar
can also be used to add supplemental files to an archive and to update
or list files in the archive. Tar includes multivolume support,
automatic archive compression/decompression, the ability to perform
remote archives, and the ability to perform incremental and full
backups.

If you want to use tar for remote backups, you also need to install
the rmt package.

\end{alltt}

\end{frame}%header

\frame{\frametitle{RPM Structure}

\begin{tabular}{c|c|c|c}

{\color{orange}lead} & {\color{cyan}signature} & {\color{orange}header} & {\color{red}archive}\\[10pt]\hline
\uncover<2->{magic} & \uncover<3->{authenticity} & \uncover<4->{indexed data store} & \uncover<5->{payload}\\
& & & \uncover<5->{{\it(gzipped cpio)}}\\

\end{tabular}
}%rpm structure

\frame{\frametitle{Usage}
{\bf Installation}

\begin{tabular}{cll}

-i & install \\
-U & Update  & \color{grey} rpm -U tar-1.13.25-4.i386.rpm\\
-F & Freshen\\
-e & erase\\

\end{tabular}\pause

{\color{grey} rpm -Uvh tar-1.13.25-4.i386.rpm}\\
\pause
\hfill --nodeps \hfill --nofiles \hfill --nomd5 \hfill --noscripts \hfill
%dependancies, verify files, verify sig, postinstall scripts.
\pause

{\bf Query (-q)}

{\small Package Selection Options}

{\footnotesize
\begin{tabular}{cll}
-a & all & \color{grey} rpm -qa\\
-f & file & \color{grey} rpm -qf /bin/bash\\
-g & group & \color{grey} rpm -qg Development/Libraries\\
-p & rpm package & \color{grey} rpm -qp bash-2.04-1.2.i386.rpm\\
--whatprovides & pkgs that provide & \color{grey} rpm --whatprovides -q libgnome.so.32\\
--whatrequires &pkgs that require & \color{grey} rpm --whatrequires -q libgnome.so.32\\     
\end{tabular}
} 
}%usage
\frame{
{\bf Output options}

{\footnotesize
\begin{tabular}{cll}
-i & info & \color{grey} rpm -qi bash\\
-l & list files& \color{grey} rpm -qilp bash-2.04-1.2.i386.rpm\\
-R & on what depends & \color{grey} rpm -qR bash\\
--provides & what does it provide&\color{grey} rpm --provides -qR bash\\
\end{tabular}
}

}%usage2

\frame{\frametitle{\bf Verify (-V)}

\begin{tabular}{cl}

S & file Size\\
M & Mode\\ %permission and type
5 & md5sum \\
D & device major/minor\\
L & readlink path\\
U & user ownership\\
G & group ownership\\
T & modification time\\
\end{tabular}

{\bf Signature Checking}

\hfill -K \hfill --checksig \hfill
}% verify

\section{SPEC file}
\begin{frame}[containsverbatim]
\frametitle{SPEC file}
\begin{itemize}
%\color{white}
\item {\color{purple}\%define}
\item header
\color{green}
\item \%description
\item \%prep
\item \%build
\item \%install
\item \%pre
\item \%post
\item \%preun
\item \%postun
\item \%files
\item \%changelog
\end{itemize}

\end{frame}

\begin{frame}[containsverbatim]
%like a makefile
\tiny 
\begin{alltt}
\color{orange}Summary: 
Name:
Version: 
Release:
\end{alltt}

\begin{alltt}
{\color{orange}Source[n]:} {\color{purple}[http://][ftp://]hostname/filename.tar.gz}
{\color{orange}Patch[n]:} {\color{purple}filename.patch}
{\color{orange}BuildRequires:} {\color{grey}\em packages required to build}
{\color{orange}Buildroot:} {\color{purple}\%\{}{\color{cyan}_tmppath}{\color{purple}\}/\%\{}{\color{cyan}name}{\color{purple}\}-\%\{}{\color{cyan}version}{\color{purple}\}}{\color{grey}-root}
\end{alltt}

\begin{alltt}
{\color{green}\%description}
Description of package
one line of whitespace to terminate

{\color{green}\%changelog}
* {\color{red}Date} Who {\color{purple}<email>} {\color{red}version}
- Notes
\end{alltt}

\end{frame}%building

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%prep}

{\tiny
\begin{alltt}
{\color{green}\%prep}
{\color{purple}\%setup} {\color{orange}-q}
{\color{purple}\%patch[n] -p1} [{\color{orange}-b}filename]
\end{alltt}
}
Unpack files, patch tree as necessary.\\
Make directories for later.\\
bash syntax legal in this section, when rpmbuild runs, it takes this section of the spec out and runs it as an sh script.\\
\end{frame}

\begin{frame}[containverbatim]
\frametitle{rpm-tmp.[pid]}
{\tiny
\begin{alltt}
{\color{blue}\#!/bin/sh}

  {\color{cyan}RPM\_SOURCE\_DIR}={\color{red}"/home/uphill/source/SOURCES/ieee80211"}\\
  {\color{cyan}RPM\_BUILD\_DIR}={\color{red}"/home/uphill/source/BUILD/i386"}\\
  {\color{cyan}RPM\_OPT\_FLAGS}={\color{red}"-O2 -g -pipe -m32 -march=i386 -mtune=pentium4"}\\
  {\color{cyan}RPM\_ARCH}={\color{red}"i386"}\\
  {\color{cyan}RPM\_OS}={\color{red}"linux"}\\
  {\color{orange}export} {\color{cyan}RPM\_SOURCE\_DIR RPM\_BUILD\_DIR RPM\_OPT\_FLAGS RPM\_ARCH RPM\_OS}\\
  {\color{cyan}RPM\_DOC\_DIR}={\color{red}"/usr/share/doc"}\\
  {\color{orange}export} {\color{cyan}RPM\_DOC\_DIR}\\
  {\color{cyan}RPM\_PACKAGE\_NAME}={\color{red}"ieee80211"}\\
  {\color{cyan}RPM\_PACKAGE\_VERSION}={\color{red}"1.2.16"}\\
  {\color{cyan}RPM\_PACKAGE\_RELEASE}={\color{red}"\%\{mrelease\}\_2.6.9\_42.0.3.EL"}\\
  {\color{orange}export} {\color{cyan}RPM\_PACKAGE\_NAME RPM\_PACKAGE\_VERSION RPM\_PACKAGE\_RELEASE}\\
  {\color{cyan}RPM\_BUILD\_ROOT}={\color{red}"/tmp/ieee80211-1.2.16-1.PU\_IAS.2-root"}\\
  {\color{orange}export} {\color{cyan}RPM\_BUILD\_ROOT}\\


  {\color{orange}set} -x\\
  {\color{orange}umask} {\color{red}022}\\
  {\color{orange}cd} /home/uphill/source/BUILD/i386\\
\end{alltt}
}%tiny
{\it Sets all variables, expands \%{variable}'s.\\
Good place to spot errors\\
}
\end{frame}
\begin{frame}[containsverbatim]
\frametitle{\color{green}\%build}

{\tiny
\begin{alltt}
{\color{green}\%build}
{\color{cyan}\%ifos} OS
{\color{cyan}\%else}
{\color{cyan}\%endif}
{\color{purple}\%define} optflags \$VARIABLE -DTHIS
{\color{cyan}for} i {\color{cyan}in} this that them
{\color{cyan}do}
    something
{\color{cyan}done}
{\color{purple}export} THIS=that
{\color{purple}\%configure} {\color{orange}--obscureoption}
{\color{orange}make} CFLAGS=this
\end{alltt}
}
{\em Simplest build section}
{\tiny\begin{alltt}
{\color{green}\%build}
{\color{purple}\%configure}
{\color{orange}make}
\end{alltt}
}%tiny
{\it Do the compilation only here, don't install things\\
{\tt rpmbuild -bc} stops at this stage}
\end{frame}

%% setup -q  (uncompress, untar, setup the buildroot
%% patch, normal patch options

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%install}

{\it Create and directories, make symlinks, make copies, move files}

{\tiny
\begin{alltt}
{\color{green}\%install}
{\color{orange}make} prefix={\color{purple}\$\{}{\color{cyan}RPM_BUILD_ROOT}{\color{purple}\}\%\{}{\color{cyan}_prefix}{\color{purple}\}}
     bindir=\
     ...
     {\color{orange}install}
{\color{orange}mkdir} there
{\color{orange}ln} this that
{\color{orange}install} 0644 newfile
\end{alltt}
}%tiny

{\em Simplest Install section}
{\tiny
\begin{alltt}
{\color{purple}\%makeinstall}
\end{alltt}
}%tiny
{\it Move all files into {\color{purple}\$}{\color{cyan}RPM\_BUILD\_ROOT}}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%pre}
Anything that needs to be done before this package is installed.\\
Create a group or user that is needed by this package.\\
{\tiny\begin{alltt}
{\color{green}\%pre}
/usr/sbin/groupadd {\color{orange}-g} 38 ntp 2> /dev/null {\color{purple}||} :
/usr/sbin/useradd {\color{orange}-u} 38 {\color{orange}-g} 38 {\color{orange}-s} /sbin/nologin {\color{orange}-M -r -d} /etc/ntp ntp 2>/dev/null {\color{purple}||} :
\end{alltt}}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%post}
Anything you want to happen after installation
Install info pages, rebuild a database, start a daemon just installed, etc....
{\tiny\begin{alltt}
{\color{green}\%post}
/sbin/install-info {\color{orange}--delete} /usr/info/thispackage.info.gz /usr/info/dir
/sbin/ldconfig
/sbin/chkconfig {\color{orange}--add} thispackage
\end{alltt}}

\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%preun}
Anything you want to have happen before you uninstall the package.\\
Stop a daemon that is about to be removed.
{\tiny\begin{alltt}
{\color{green}\%preun}
/etc/init.d/sendmail stop >/dev/null 2>&1
/sbin/chkconfig {\color{orange}--del} sendmail
/usr/sbin/alternatives {\color{orange}--remove} mta /usr/sbin/sendmail.sendmail
\end{alltt}}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%postun}
Something that has to be done after files have been removed\\

{\tiny\begin{alltt}
{\color{green}\%postun}
/sbin/ldconfig

\end{alltt}}

\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%clean}
Remove any files used in building
{\tiny\begin{alltt}
{\color{green}\%clean}
{\color{orange}rm -rf} {\color{purple}\$}{\color{cyan}RPM_BUILD_ROOT}
\end{alltt}}

\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%files}
Files/Directories\\ default permissions/owner/group\\
Config files\\
Documentation\\[10pt]
{\tiny
\begin{alltt}
{\color{green}\%files}
{\color{purple}\%defattr(mode,owner,group)}
{\color{purple}\%doc} location/relative/to/build-root
{\color{purple}\%dir} directory
{\color{purple}\%config \%\{}{\color{cyan}_sysconfdir}{\color{purple}\}}configfile
\%files -f [filename]

\end{alltt}
}%tiny

\end{frame}

\section{Working with SPECs}
\begin{frame}[containsverbatim]
\frametitle{Creating a SPEC}

 
vi ....

\end{frame}

\section{Simple SPEC}
\begin{frame}[containsverbatim]
Very simple package, unpack, configure, compile and install.
{\tiny
\begin{alltt}
{\color{orange}Summary:} An MPEG audio player.
{\color{orange}Name:} mpg321
{\color{orange}Version:} 0.2.10
{\color{orange}Release:} 2.PU_IAS.2
{\color{orange}License:} {\color{red}GPL}
{\color{orange}Group:} Applications/Multimedia
{\color{orange}Source:} {\color{purple}http://prdownloads.sourceforge.net/\%\{{\color{cyan}name}\}/\%\{{\color{cyan}name}\}-\%\{{\color{cyan}version}\}.tar.gz}
{\color{orange}Patch1:} mpg321-0.2.10-security.patch
{\color{orange}URL:} {\color{purple}http://mpg321.sourceforge.net/}
{\color{orange}Buildroot:} {\color{purple}\%\{{\color{cyan}_tmppath}\}/\%\{{\color{cyan}name}\}-\%\{{\color{cyan}version}\}-\%\{{\color{cyan}release}\}}-root
{\color{orange}BuildRequires:} libao-devel >= 0.8.0, libmad >= 0.14.2b


{\color{green}\%prep}
{\color{purple}\%setup} -q
{\color{purple}\%patch1} -p1

{\color{green}\%build}
{\color{purple}\%configure}
{\color{orange}make}

{\color{green}\%install}
{\color{purple}\%makeinstall}

\%clean
{\color{orange}rm -rf} \%\{{\color{cyan}buildroot}\}

{\color{green}\%files}
{\color{purple}\%defattr(-, root, root)
\%doc} AUTHORS BUGS ChangeLog COPYING HACKING NEWS README* THANKS TODO
\%\{{\color{cyan}_bindir}\}/*
\%\{{\color{cyan}_mandir}\}/man1/*
\end{alltt}
}%tiny
\end{frame}
\begin{frame}
\frametitle{Building}

{\it SPEC}\\
{\tiny
\tt {\color{orange}rpmbuild [-ba|-bb|-bc|-bi|-bl|-bp|-bs]} {\color{cyan}package.spec}\\
\tiny\tt {\color{orange}         [--target=\%\{}{\color{cyan}arch}{\color{orange}\}]}\\
}%tiny
\bigskip

{\it src.rpm}

{\tiny \tt {\color{orange}rpm --rebuild} {\color{cyan}package.src.rpm}
}%tiny
\end{frame}

\section{Advanced Topics}

\begin{frame}[containsverbatim]
\frametitle{Advanced Topics}

Creating dependencies
{\tiny
\begin{alltt}
{\color{orange}BuildRoot:} {\color{purple}\%\{}{\color{cyan}_tmppath}{\color{purple}\}/\%\{}{\color{cyan}name}{\color{purple}\}-\%\{}{\color{cyan}version}{\color{purple}\}}-build
{\color{orange}BuildRequires:} autoconf automake{\color{purple}>=}123 
{\color{orange}Requires:} gcc >= 2.96
\end{alltt}
}%tiny

Creating a list of files
{\tiny
\begin{alltt}
cat > files.list <<EOF
{\color{purple}\%\{}{\color{cyan}_bindir}{\color{purple}\}}/perl
{\color{purple}\%attr(}4711{\color{purple},root,root) \%\{}{\color{cyan}_bindir}{\color{purple}\}}/suidperl
EOF
{\color{green}\%files} {\color{orange}-f} files.list



\end{alltt}
}%tiny

\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Multiple Architectures}

{\tiny
\begin{alltt}
{\color{orange}Patch0:} alpha.patch 

{\color{cyan}\%ifarch} alpha
{\color{purple}\%patch0} {\color{orange}-p1}
{\color{cyan}\%endif}

{\color{orange}ExcludeArch:} sparc
\end{alltt}
}%tiny

\end{frame}

\section{Kernel Module RPMs}

\begin{frame}
\frametitle{Kernel Modules}
\begin{itemize}
%\color{white}
\item Modules out of tree
\item Modules in tree
\end{itemize}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{ieee80211 - out of tree}
{\tiny 
\begin{alltt}
{\color{blue}\# use kernel from command line if given, else, uname -r}
\%\{!?kernel: \%\{expand: \%\%define kernel \%(uname -r)\}\}
{\color{purple}\%define} kversion \%(echo {\color{purple}\%\{}kernel{\color{purple}\}} | sed -e s/smp// -)

{\color{blue}\# define a kernel version string to append to the package version}
{\color{purple}\%define} kernel\_ver\_str \%(echo {\color{purple}\%\{}kversion{\color{purple}\}} | tr -s '-' '\_')

{\color{blue}\# define major and minor revisions (some packages need this)}
{\color{purple}\%define} kmajor \%(echo {\color{purple}\%\{}kversion{\color{purple}\}} | cut -d'-' -f1)
{\color{purple}\%define} kminor \%(echo {\color{purple}\%\{}kversion{\color{purple}\}} | cut -d'-' -f2)

{\color{blue}# define the target}
{\color{cyan}\%ifarch} i386 i686
{\color{purple}\%define} arch i686
{\color{cyan}\%endif}
{\color{cyan}\%ifarch} x86_64
{\color{purple}\%define} arch x86_64
{\color{cyan}\%endif}
\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
This spec creates several RPMs\\
Create new packages with {\color{green}\%package} -n name\_of\_new\_package

{\tiny
\begin{alltt}
{\color{blue}\# modules package}
{\color{green}\%package} {\color{orange}-n} kernel-\%\{name\}
{\color{orange}Release:} \%\{mrelease\}_{\color{purple}\%\{}kernel_ver_str{\color{purple}\}}
{\color{orange}License:} Other
{\color{orange}Summary:} ieee80211 subsystem modules
{\color{orange}Group:} System Environment
{\color{orange}Requires:} kernel = {\color{purple}\%\{}kversion{\color{purple}\}}
{\color{orange}Provides:} kernel-module kernel-modules
\end{alltt}
}%tiny
Each {\color{green}\%package} requires a {\color{green}\%description} and {\color{green}\%files} section.\\
Can have specific {\color{green}\%pre, \%post, \%preun} and {\color{green}\%postun} sections.
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{\color{green}\%build}
To build, we need kernel source
{\tiny
\begin{alltt}
{\color{orange}BuildRequires:} kernel-devel
\end{alltt}
}%tiny
We copy the kernel source into the build directory and configure
{\tiny
\begin{alltt}
{\color{green}\%build}
{\color{cyan}\%ifarch} \%x86
{\color{orange}export} TARGET=i386-elf
{\color{cyan}\%endif}

{\color{cyan}\%ifarch} x86_64 ia32e
{\color{orange}export} TARGET=x86_64-elf
{\color{cyan}\%endif}
export TOOLPREFIX=`which gcc|sed -e's,gcc\$,,'`
echo \%\{kernel\} - \%\{kmajor\}
cp -ar /usr/src/kernels/\%\{kversion\}-\%\{arch\} .
cd \%\{kversion\}-\%\{arch\}
        ln -s . build
        perl -pi -e 's#\%\{kminor\}custom#\%\{kminor\}#' Makefile
        make oldconfig >/dev/null
cd ..

{\color{purple}\%define} ksrc `pwd`/\%\{kversion\}-\%\{arch\}
{\color{purple}\%define} kmodule_dir /lib/modules/\%\{kversion\}
\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
Create directories for modules to live in
{\tiny
\begin{alltt}
#modules should go here
mkdir -p \%\{buildroot\}\%\{kmodule_dir\}/updates/net/ieee80211
mkdir -p \%\{buildroot\}\%\{kmodule_dir\}smp/updates/net/ieee80211
\end{alltt}
}%tiny
Sometimes requires patching the Makefile for the modules.
{\tiny
\begin{alltt}
{\color{green}--- ieee80211-1.2.16/Makefile.rpmdemo    2007-01-04 21:51:15.000000000 -0500
+++ ieee80211-1.2.16/Makefile   2007-01-11 13:08:09.000000000 -0500}
{\color{orange}@@ -63,7 +63,7 @@}
 # Begin dual Makefile mode here.  First we provide support for when we
 # are being invoked by the kernel build system
 #
{\color{purple}-ifneq (\$(KERNELRELEASE),)}
{\color{cyan}+#ifneq (\$(KERNELRELEASE),)}
\end{alltt}
}%tiny
Use {\tt gendiff} to create patches.
{\tiny
\begin{alltt}
cp Makefile Makefile.rpmdemo
{\it edit Makefile}
cd ..
gendiff ieee80211-1.2.16 .rpmdemo >ieee80211-rpmdemo.patch
\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
{\tiny
\begin{alltt}
{\color{green}\%install}
echo Building SMP modules
{\color{orange}make} \(\backslash\)
        KSRC=\%\{ksrc\} \(\backslash\)
        KERNELRELEASE=\%\{kversion\}{\color{red}smp} \(backslash\)
        IEEE80211\_INC=\%\{{\color{cyan}buildroot}\}\%\{{\color{cyan}\_includedir}\}/ieee80211 \(\backslash\)
        KMISC=\%\{{\color{cyan}buildroot}\}\%\{kmodule\_dir\}{\color{red}smp}/net/ieee80211 \(\backslash\)
        DESTDIR=`pwd` \(\backslash\)
        {\color{orange}install}
\end{alltt}
}%tiny
Move modules into appropriate directory
{\tiny
\begin{alltt}
{\color{orange}mv} \%\{{\color{cyan}buildroot}\}\%\{kmodule\_dir\}smp/net/ieee80211/* \(\backslash\)
	\%\{{\color{cyan}buildroot}\}\%\{kmodule_dir\}smp/updates/net/ieee80211
\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
RHEL4 and earlier have separate smp kernels.\\
In RHEL5 and FC6, there is no uniprocessor kernel.
{\tiny
\begin{alltt}
cd \%\{kversion\}-\%\{arch\}
        make clean >/dev/null
        make oldconfig >/dev/null
        {\color{orange}sed -e '}{\color{red}s/CONFIG_SMP=.*/# CONFIG\_SMP is not set/}{\color{orange}' -i} .config
        {\color{orange}sed -e '}{\color{red}s/CONFIG_X86_SMP=.*/# CONFIG\_X86\_SMP is not set/}{\color{orange}' -i} .config
        {\color{orange}sed -e '}{\color{red}s/CONFIG_HOTPLUG_PCI=.*/# CONFIG\_HOTPLUG\_PCI is not set/}{\color{orange}' -i} .config
        {\color{orange}sed -e '}{\color{red}s/CONFIG_PROFILING=.*/# CONFIG\_PROFILING is not set/}{\color{orange}' -i} .config
        {\color{orange}sed -e '}{\color{red}s/CONFIG_OPROFILE=.*/# CONFIG\_OPROFILE is not set/}{\color{orange}' -i} .config
        {\color{orange}sed -e '}{\color{red}s/CONFIG_HIGHMEM64G=.*/# CONFIG\_HIGHMEM64G is not set/}{\color{orange}' -i} .config
{\color{orange}cd} ..
{\color{orange}make} clean
\end{alltt}
}%tiny
Then remove the smp from the make lines
{\tiny
\begin{alltt}
{\color{orange}make} \(\backslash\)
        KSRC=\%\{ksrc\} \(\backslash\)
        KERNELRELEASE=\%\{kversion\} \(\backslash\)
        IEEE80211_INC=\%\{{\color{cyan}buildroot}\}\%\{{\color{cyan}\_includedir}\}/ieee80211 \(\backslash\)
        KMISC=\%\{{\color{cyan}buildroot}\}\%\{kmodule\_dir\}/net/ieee80211 \(\backslash\)
        DESTDIR=`pwd` \(\backslash\)
        {\color{orange}install}
\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
{\tiny
\begin{alltt}
{\color{blue}# depmod required on the module rpms}
{\color{green}\%post} -n kernel-\%\{name\}
/sbin/depmod -ae {\color{purple}\%\{}kversion{\color{purple}\}}

{\color{green}\%post} -n kernel-smp-\%\{name\}
/sbin/depmod -ae {\color{purple}\%\{}kversion{\color{purple}\}}smp
\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{rocket - in tree}
Package to turn on a module not included by our distro\\
Copy source files from kernel source 
{\tiny
\begin{alltt}
{\color{orange}Source:} rocket.c
{\color{orange}Source1:} rocket_int.h
{\color{orange}Source2:} rocket.h
{\color{orange}Source3:} rocket.txt
\end{alltt}
}%tiny
No tar, tell {\color{purple}\%setup} to create directories\\
Copy files\\
Add module to makefile\\
{\tiny
\begin{alltt}
{\color{green}\%prep}
{\color{purple}\%setup} -c -n {\color{purple}\%\{}{\color{cyan}name}{\color{purple}\}-\%\{}{\color{cyan}version}{\color{purple}\}} -T
{\color{orange}cp} {\color{purple}\%\{}{\color{cyan}SOURCE0}{\color{purple}\}} .
{\color{orange}cp} {\color{purple}\%\{}{\color{cyan}SOURCE1}{\color{purple}\}} .
{\color{orange}cp} {\color{purple}\%\{}{\color{cyan}SOURCE2}{\color{purple}\}} .
{\color{orange}cp} {\color{purple}\%\{}{\color{cyan}SOURCE3}{\color{purple}\}} .
{\color{orange}echo} "{\color{red}obj-m += rocket.o}" > Makefile

\end{alltt}
}%tiny
\end{frame}

\begin{frame}[containsverbatim]
Use kernel-devel tree, tell Makefile that Modules are in the current directory ({\tt M=`pwd`})
{\tiny
\begin{alltt}
{\color{green}\%build}
buildmodule() \{
{\color{orange}rm -f} rocket.o *.mod.* *.ko
{\color{orange}make -C} /lib/modules/\%\{kversion\}{\color{cyan}\$1}/build M=`pwd` modules
{\color{orange}mkdir} build{\color{cyan}\$1}
{\color{orange}mv} rocket.ko build{\color{cyan}\$\{1\}}/rocket.ko
\}
buildmodule
\%if \%\{buildsmp\}
buildmodule smp
\%endif
\%if \%\{buildhugemem\}
buildmodule hugemem
\%endif
\end{alltt}
}%tiny

Move the built module {\tt *.ko} into a temporary build directory...copy in {\color{green}\%install}
\end{frame}

\begin{frame}[containsverbatim]
{\tiny
\begin{alltt}
{\color{green}\%install}
installmodule() \{
{\color{orange}mkdir -p} {\color{purple}\$}{\color{cyan}RPM_BUILD_ROOT}/lib/modules/\%\{kversion\}{\color{cyan}\$1}/\%\{minstalldir\}
{\color{orange}install -m} 644 build\$1/*.ko {\color{purple}\$}{\color{cyan}RPM_BUILD_ROOT}/lib/modules/\%\{kversion\}{\color{cyan}\$1}/\%\{minstalldir\}
\}
installmodule
\%if \%\{buildsmp\}
installmodule smp
\%endif
\%if \%\{buildhugemem\}
installmodule hugemem
\%endif
\end{alltt}
}%tiny
\end{frame}

\section{Summary}
\begin{frame}
\frametitle{Tips}
\begin{itemize}
%\color{white}
\item use \%{variable} as much as possible\\
use {\tt rpm --showrc} to see all variables.\\
use \%\{version\} instead of hard coding the version in the spec.
\item build from src, modify files as necessary, use {\tt gendiff} to create patch
\item always build as yourself, not root
\item Update {\color{green}\%changelog}
\end{itemize}
\end{frame}


\begin{frame}
\frametitle{Links}
\begin{itemize}
\small%\color{white}
\item RPM.org\\{\tt http://www.rpm.org}
\item RPM-HOWTO\\{\tt http://www.rpm.org/RPM-HOWTO}
\item Linux Documentation Project\\{\tt http://en.tldp.org/HOWTO/RPM-HOWTO}
\item Mandrake SPECS\\{\tt http://cvs.mandrakesoft.com/cgi-bin/cvsweb.cgi/SPECS}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Questions?}
\end{frame}
\end{document}
