GNOME/Packaging/Simple program package

From openSUSE


This page contains a very simple RPM spec file for a GNOME program and explains each part of it in detail. You can find the entire package in the project home:maw, package gnome-hello. (We'll probably move it to GNOME:Community soon.)


Contents

Preamble

# norootforbuild

Build requirements

Here we list build requirements. This should be a minimal set of dependencies required to build the package. Note that if one package requires another, then it is only necessary to list the requiring package. For example, if your program uses functionality provided by the glib2 package and the gtk2 package (a common occurrence), then it is only necessary to explicitly list gtk2-devel, since gtk2-devel depends on glib2-devel.

It is a good idea to keep the list of build requirements sorted in alphabetical order. In many SUSE packages, the build requirements are listed all on one line. Since this can be hard to read on the web, we list them here in several lines. So, as you can see, more than one BuildRequires: line is allowed. One line or many -- either way is fine.

BuildRequires: alsa-devel gconf2-devel gnome-common gnome-doc-utils-devel gtk2-devel
BuildRequires: intltool libgnome-devel libgnomeui-devel perl-XML-Parser pkg-config scrollkeeper
BuildRequires: update-desktop-files

If we want the package to build on older versions of the distribution, we sometimes need to require other packages.

%if %suse_version <= 1020
%define _prefix   /opt/gnome
%define _sysconfdir /etc%_prefix
BuildRequires: gconf2-rpm-macros extra-rpm-macros
%endif

Package metadata

Here we list the package's name, a short description, its version, etc.

Name:         gnome-hello
Summary:      A very simple GNOME package
Version:      2.0.3

You don't need to edit the Release: tag; the build service will automatically increment this on each rebuild.

Release:      0
License:      GPL
Group:        Devel/Tools
URL:          http://www.gnome.org

Package sources

Here we list the sources and patches that make up the package.

Source0:      %{name}-%{version}.tar.bz2
Patch0:       gnome-hello-fake-gconf.patch


Misc

The BuildRoot tag specifies where the "fake" installation happens. This is different from the chroot where build occur. So, if the chroot is /builds/10.3, BuildRoot will expand to /builds/10.3/var/tmp/gnome-hello-2.03-build. Its contents will be made up of the files to be included in the package, such as /builds/10.2/var/tmp/gnome-hello-2.03-build/usr/bin/gnome-hello.

BuildRoot:    %{_tmppath}/%{name}-%{version}-build

RPM can examine binaries to determine what libraries they depend on, and as such, it usually isn't necessary to list many requirements explicitly. Autoreqprov: on enables this functionality. Be careful, however, when packaging programs written in interpreted languages such as Python and Ruby; Autoreqprov isn't able to determine these programs' requirements.

The one Requires: entry we have here is for the gnome-hello-lang subpackage. The creation of the subpackage is described later in this document.

Autoreqprov:  on
Requires:     %{name}-lang = %{version}

Packages that include gconf schemas need the following:

%gconf_schemas_prereq

A free-form description of the package.

%description
Insert description here - normally taken from the README.

Declaration of subpackages

This automatically declares a -lang subpackage. See below for more information about the creation of -lang subpackages.

%lang_package

This automatically declares a -debuginfo subpackage. This is all you need to get a -debuginfo subpackage.

%debug_package

Prepare the source

Prepare the source for compilation.

%prep

The %setup line is important; it is what extracts the Source lines listed above.

%setup -n %{name}-%{version}

Apply the zeroth patch.

%patch0 -p1

Build the code

%build

It is possible to adjust CFLAGS (CXXFLAGS for programs written in C++).

export CFLAGS=$RPM_OPT_FLAGS

Since Patch0 modifies a Makefile.am file, it is necessary to rerun the autotools. This would also be the case had we modified a configure.in or .ac file.

autoreconf -f -i

%configure runs "./configure" with a reasonable set of default arguments, including install locations. Subsequent arguments can supplement or override the defaults.

%configure \
    --disable-scrollkeeper

Build the the project. %__make is just an alias for "make". %{?jobs:-j%jobs} causes make to run in parallel where possible and when specified.

%__make %{?jobs:-j%jobs}

Install the result

Once the program has been compiled, it's necessary to install it. This doesn't install the package or any files on your working system. Instead, it puts files where they would go if you ran "make install" directly, but under a temporary directory. The temporary directory that's used is defined in BuildRoot: tag in your spec's preamble.

%install

This is an alias for "make install DESTDIR=$RPM_BUILD_ROOT", which works for nearly every program that is built using autotools. Other programs are different; for example, many programs written in python need "python setup.py install --prefix=%{_prefix} --root=$RPM_BUILD_ROOT" instead.

%makeinstall

This looks for gconf schemas among the "installed" files. This leaves behind several files referred to later in your spec file.

%find_gconf_schemas

This looks for translation files (they end in ".mo") among the "installed files". It leaves behind a file called "%{name}-2.0.lang" which you will refer to later. Note: this is a special, although common, case. For many packages, you'll simply use "%find_lang %{name}" and get a file called "%{name}.lang".

%find_lang %{name}-2.0

Scripts that are run upon installation and uninstallation

Upon installation and uninstallation of many packages, it's necessary to run commands. They usually update databases already installed on your system, etc.

Before installing the package, run a script:

%pre -f %{name}.schemas_pre

Before uninstalling the package, run another script.

%preun -f %{name}.schemas_preun

After installing or uninstalling the package, run still another script.

%posttrans -f %{name}.schemas_posttrans

Clean up working directories

Remove the BuildRoot: specified in the preamble. This is surprisingly important; without it, it is possible to have many mysterious errors. On the other hand, it is sometimes convenient to poke around after a package fails to build. So feel free to comment out this section when working on a package, but remove the comments before distributing the package.

%clean
rm -rf $RPM_BUILD_ROOT

List the files in the package

Here we list all the files and directories that the package includes.

The section starts with "%files". "-f" adds the files listed in its argument to the list of files. In this case, "%{name}.schemas_list" is created by "%find_gconf_schemas" in the %install section.

%files -f %{name}.schemas_list

Make sure that all of the package's files are owned by root.

%defattr(-, root, root)

Automagically install and list documentation files. These files will end up in /usr/share/doc/packages/gnome-hello.

%doc AUTHORS COPYING NEWS README

Include all executable files -- that is, files that go into /usr/bin (or /opt/gnome/bin on openSUSE 10.2 and older).

%{_bindir}/*
%{_datadir}/applications/*

The lines starting with %dir cause directories to be owned by the package. Ideally, only one package will own a directory, and there will be no "unowned" directories on a properly maintained system (except for user home directories, temporary directories, etc).

%dir %{_datadir}/gnome/help/%{name}
%dir %{_datadir}/gnome/help/%{name}/C
%dir %{_datadir}/gnome/help/%{name}/C/figures

It's ok to use shell globs, but be careful not to be too overzealous when using them, as they occasionally mask real problems with your package.

%{_datadir}/gnome/help/%{name}/C/*.xml
%{_datadir}/gnome/help/%{name}/C/figures/*.png
%dir %{_datadir}/gnome/help/%{name}/ja
%dir %{_datadir}/gnome/help/%{name}/ja/figures
%{_datadir}/gnome/help/%{name}/ja/*.xml
%{_datadir}/gnome/help/%{name}/ja/figures/*.png
%dir %{_datadir}/gnome/help/%{name}/oc
%dir %{_datadir}/gnome/help/%{name}/oc/figures
%{_datadir}/gnome/help/%{name}/oc/*.xml
%{_datadir}/gnome/help/%{name}/oc/figures/*.png
%dir %{_datadir}/gnome/help/%{name}/sv
%dir %{_datadir}/gnome/help/%{name}/sv/figures
%{_datadir}/gnome/help/%{name}/sv/*.xml
%{_datadir}/gnome/help/%{name}/sv/figures/*.png
%{_datadir}/icons/hicolor/48x48/apps/*.png
%{_datadir}/omf/%{name}/*.omf

List files owned by the -lang subpackage. The first argument, a bare "lang" means that these files are for the -lang subpackage. (You could also specify this explicitly by using "%files -n %{name}-lang ...", but there's little point in doing so.) The argument "%{name}-2.0.lang" was created by "%find_lang" in the %install section.

%files lang -f %{name}-2.0.lang

Changelog

You can fill this in by hand, but it's easier to maintain an external .changes file, whose contents will be included in the %changelog section automatically by the Build Service.

One advantage to using an external .changes file is that it's safe to do global find-and-replace operations in the spec file that you're editing -- you won't be "rewriting history".

%changelog

The format of .changes files is described here.

See also