Hello,
I've had a few people asking how to build Livna modules for development kernels, so here's the next guide
If I can, I'd like for this to be a massive howto so I'm going to reserve the next
3 posts, because I'll need them later on as I add to this... But in the mean while, I'll write the best part first - Rebuilding kernel modules!
Overview on the RPM format and specfiles in general
If you'd like some general information on RPM, or just a very good reference, please see this page:
http://www.rpm.org/RPM-HOWTO/
In short, when you build RPMS you get two of them:
- RPMs (called binary RPMS or binary packages)
- SRPMs (called source RPMS or source packages)
The normal RPMs contain the compiled files, meaning they're ready to be installed and used right away. This is what you want 99% of the time, and it's what for example 'yum' grabs when you install things. However, if you want to build your own RPMs, you're going to require those SRPMs because they contain the source files - non-compiled stuff - that you can modify if needed and use again to rebuild your own custom RPM.
All RPMS, both SRPMs and RPMs are built through spec files. A spec file is basically a special file with specific format and commands that define what your package is, what files it owns, what files are non-replaceable (configuration) files, which things to install where, it's name, etc. It's how RPM can keep track of everything so well. Learning the format of specfiles and how they work is crucial to building RPMs.
Specfiles
I'm going to show you the general outline of a specfile, and also show you the little bits and pieces that may not seem big, but if followed make it a Fedora Extras-acceptable package. Besides that, following the FE guidelines make a pretty clean and overall nice specfile, and therefore RPMs are build more cleanly.
I'm not sure about you, but I like seeing examples, it helps quite a bit when adapting to new things and concepts. You'll find that a lot of my example come from fwbackups, and feel free to even use my specfile as a base for yours if you'd like.
This the typical, minimal specfile:
Code:
Name:
Version:
Release: 1%{?dist}
Summary:
Group:
License:
URL:
Source0:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires:
Requires:
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc
%changelog
Name - Name of your package (Ususally same name as what you're packaging)
Version - The version of what you're packaging
Release - Your release. You use release to make changes to a package when the actual version doesn't change - ex. a new patch must be applied, a bug is fixed in the specfile, etc. This is why you always see the version format like this: [version]-[release] - eg 2.16-1, 2.16-2, so on - In both cases the packaged program is still version 2.16, but in the latter a bug was fixed or something else that requried a new package to be made. So the release tag was bumped up by one.
When you up the version, you set the 'Release' tag back to 1. The %{?dist} part just adds .fc# to the end of the release, where # is the fedora release it's built for.
Summary: - A very short summary of your package. Only a few words.
Group: - The group your package fits into. To see a full list of groups, type in a terminal:
Code:
cat `rpm -ql rpm | grep GROUPS$` | less
License: - The license of your package. Typically 'GPL'.
URL: - The URL of the program you're packaging, with the http:// prefix. For example, because fwbackups is now hosted at
http://www.diffingo.com, I could enter that there. If you decided to package your own Wine packages, then put
Code:
URL: http://www.winehq.com
Source0: - The source tarball for your package. It's better to have this as a full URL that works.
No broken links. For example:
Code:
Source0: http://www.diffingo.com/downloads/fwbackups/fwbackups-1.42.1.tar.gz
If you want a even cleaner spec, incorporate your Version tag into the Source0 tag by using %{version}. For example:
Code:
Source0: http://www.diffingo.com/downloads/fwbackups/fwbackups-%{version}.tar.gz
You can also add your own sources and add another Source line, like this:
Code:
Source1: MySourceTarballOrFile
Source2: MySourceTarballOrFileAgain
This is especially useful for adding in .desktop files (so that your program appears in the system menus) and also for applying patches not available in upstream.
*** Note: "Cleaner" specs won't really make a difference in terms of the package outputted - But it's much easier to be read by others and not to mention you'll thank yourself later when you need to edit the specfile again. ***
Patch0: - An optional tag that you can use to apply patches. In the same way as source, you can add more and more with Patch1 and Patch2. Note that after the Patch#: statement you need to reference a file or a %{Source#} that reffers to the patch file.
BuildRoot: Leave this tag as shown above. It's just the directory you're assigning RPM to use when actually building the RPM, and Fedora likes to have it formatted like that line.
BuildRequires: - What packages are needed to rebuild the SRPM of this package?
Requires: - What the package requires to run. Please note that there are
exceptions that you shouldn't include in this list.
%description - The longer descritption of your package. Don't make it too long, a few sentences should do. Also, don't put more than 80 characrters per line of the description - That's what line breaks are for!
*** Read me before!
Now we're getting into the complex part of the rpm specfile, so here's some more info...
***
RPM uses macros, which are useful for creating high-grade RPMs that across distributions.
A macro is basically a special tag that RPM replaces with a directory on the system - But each distribution can define their own tags. So, if you use macros as often as possible, you have a better chance of not only making the same RPM work on future versions of Fedora but on other distributions. Here's the list of Fedora's macros:
Code:
%_prefix /usr
%_exec_prefix %{_prefix}
%_bindir %{_exec_prefix}/bin
%_sbindir %{_exec_prefix}/sbin
%_libexecdir %{_exec_prefix}/libexec
%_datadir %{_prefix}/share
%_sysconfdir %{_prefix}/etc
%_sharedstatedir %{_prefix}/com
%_localstatedir %{_prefix}/var
%_libdir %{_exec_prefix}/lib
%_includedir %{_prefix}/include
%_oldincludedir /usr/include
%_infodir %{_prefix}/info
%_mandir %{_prefix}/man
You can use a macro in a regular command, like this:
Code:
install -D -p -m755 usr/sbin/fwbackups ${RPM_BUILD_ROOT}%{_sbindir}/fwbackups
RPM will repalace the macro with the real path when building.
%prep - The prep section, stuff that happens before building starts. Unpacking the source tarballs goes here, along with any patches you need to apply.
%setup -q - Unpacks the tarballs and changes the working directory to them.
patch0 -b .patch0 - Again, optional but used to apply the patch referenced by Patch0. You apply more patches in the same way with '%patch1 -b .patch1', and so on.
%build - The build step.
%configure - (I think) Configure you package (./configure) with the normal Fedora directories passed as args. Can be commented if your program doesn't need a ./configure.
make %{?_smp_mflags} - Run 'make' the program, paying attention to SMP flags. Again, can be commented if your program doesn't need to 'make'.
%install - The section used to place the commands used to install files on your system.
rm -rf $RPM_BUILD_ROOT - You
always want to clean your buildroot as the first thing in %install to remove any trace of a previous build or anything else lying around.
Now, a few examples of things in the %install section:
Code:
install -d -p -m755 ${RPM_BUILD_ROOT}%{_bindir}
Create /usr/bin in for the RPM buildroot, with permissions of '755'. You NEVER want to simply do:
Code:
install -d -p -m755 %{_bindir}
As this affects the real filesystem. (It actually tries to make /usr/bin on the system, which exists and you'll get an error)
*** NOTE: When installing files, you install everything to the buildroot, which in turn and it gets packaged into the binary RPMs.[/b] Besides that if something messes up, you haven't modified the whole system but only the buildroot. The contents of a directory is disposable, the system isn't. ***
Code:
install -D -p -m644 etc/fwbackups/fwbackups.conf ${RPM_BUILD_ROOT}%{_sysconfdir}/fwbackups/fwbackups.conf
This installs the etc/fwbackups/fwbackups.conf file from the tarball into [buildroot]/etc/fwbackups/fwbackups.conf - Which in turn becomes /etc/fwbackups/fwbackups.conf in the outputted RPMs.
make install DESTDIR=$RPM_BUILD_ROOT - Again, can be commented out if your program doesn't need a 'make install'.
%clean - Cleaning after building.
rm -rf $RPM_BUILD_ROOT - Clean your buildroot after you're done building stuff!