Packaging/SUSE Package Conventions/Specific Packages

From openSUSE

10. Specific Packages

Prev

Next



Contents

10. Specific Packages


10.1. GTK+ and GNOME Packages


This section describes how GTK+ and GNOME packages are done on SUSE Linux. After the first part including basic information, there are some subsections describing more complicated or less common features, namely: Gconf, the GStreamer registry, and the shared MIME database.

The following basic rules are defined:


  • GTK+ version 1.x is deprecated. Packages using GTK+ version 2.x are preferred and should be used whenever possible.
  • GTK+ and GNOME–based libraries (optionally also applications) should use the same prefix as GTK+/GNOME itself. This helps to prevent prefix clashes. The prefix is currently /opt/gnome, but it will change to /usr in the future. There are few exceptions where files must be explicitly moved to /usr. See 10.1.3, "Shared MIME Info".

According to FHS, configuration files must be located below /etc/opt/gnome and variable data below /var/opt/gnome if the the prefix is /opt/gnome.

  • GTK+-related -devel packages should be in the RPM group Development/Libraries/X11. GNOME related -devel subpackages packages should be in the group Development/Libraries/GNOME. Both GTK+ and GNOME–related packages providing the parts of libraries needed at runtime should be in the group System/Libraries. The GNOME desktop packages should be in the group System/GUI/GNOME. Finally, the GTK+ and GNOME–related applications should be in a respective subgroup of Productivity.


The packages needed for build must be mentioned in the BuildRequires tag, dependencies are solved automatically. Two meta packages are defined: gtk2-devel-packages and gnome2-devel-packages, which can be listed in the BuildRequires tag. They substitute for packages needed for compilation of packages based on GTK+ 2.x and GNOME 2.x. The meta package gnome2-devel-packages includes only core libraries, including libgnomeprint, but not less common libraries, like gnome-panel, vte, and gail. Some other packages that are required at runtime but not for building are also not included, for example, some gdk-pixbuf loaders, fonts, and font database configuration.

Most GTK+ and GNOME packages use the standard configure, make, and make install technique. It is usually enough to set the right paths with configure options but no other special actions are necessary to locate GTK+ and GNOME. In this way, it is similar to other packages.

The related part of the spec file typically looks like:

%build
%suse_update_config -f
CFLAGS="$RPM_OPT_FLAGS” \
./configure --prefix=/opt/gnome \
        --libdir=/opt/gnome/%_lib \
        --sysconfdir=/etc/opt/gnome \
        --localstatedir=/var/opt/gnome
make

%install
make DESTDIR=$RPM_BUILD_ROOT install

In the example above, see how the $RPM_OPT_FLAGS are usually passed to configure. Also see that the macro %suse_update_config is usually called to update some auto-stuff related files.

Many GNOME packages use helper scripts or binaries installed in the libexec directory. They must call --libexecdir=/opt/gnome/lib/{name} where {name} usually is the package name. lib is used instead of %lib. See 4.1, "Biarch Systems" for more details. The configure options usually look like:

./configure --libdir=/opt/gnome/%_lib \
            --libexecdir=/opt/gnome/lib/%{name} \
            [...]

Packages providing GNOME applets can use --libexecdir=/opt/gnome/lib/gnome-applet. The directory is reserved for these applets.

All applications should install a .desktop file to define a menu entry. They must call the macro %suse_update_desktop_file for all installed menu entries in the %install section. This typical example is taken from the package planner:

%install
[...]
%suse_update_desktop_file %name Office ProjectManagement

Language-specific files (localizations of menu entries, messages, help content, etc.) should be marked with the respective %lang tag in the file list. There is the macro %find_lang for this purpose. It is typically used the following way:

%install
[...]
%find_lang %name

%files -f %{name}.lang
[...]


10.1.1. GConf


GNOME packages often use the GConf configuration database. It is made from front-end files and back-end files. Only front-end files are included in the file list. Back-end files are generated during installation. This feature is used when a package installs any file to $sysconfdir/gconf.

To use this, the maintainer should first check whether the application installs all schemas files used to $sysconfdir/gconf/schemas. Most packages do it, but there are some buggy packages.

Next, the package must be configured not to create the back-end files within the %install phase. It can be done:


  1. By adding --disable-schemas-install option to configure:
./configure --disable-schemas-install ...
  1. By using of GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL variable:
export GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1
make install DESTDIR=$RPM_BUILD_ROOT
unset GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL
  1. If both fail, the package needs to be fixed manually.


Finally, the back-end files must be generated in the %post script. do not forget to mention the packages used in the PreReq tag.

This example is taken from the package epiphany. There are two files, epiphany.schemas and epiphany-lockdown.schemas, installed in /etc/opt/gnome/gconf/schemas. The corresponding %post script looks like:

PreReq:       gconf2 gnome-filesystem

%post
export GCONF_CONFIG_SOURCE=`opt/gnome/bin/gconftool-2 \
                               –get-default-source`
opt/gnome/bin/gconftool-2 –makefile-install-rule \
    etc/opt/gnome/gconf/schemas/epiphany.schemas >/dev/null
opt/gnome/bin/gconftool-2 –makefile-install-rule \
    etc/opt/gnome/gconf/schemas/epiphany-lockdown.schemas \
    >/dev/null

The back-end files are not removed in the %postun script. This is a design problem of GConf. Since SL 9.2, the script gconftool-rebuild, which can be used to rebuild GConf database from scratch, is available.

It is a good practice to avoid globbing in the file list and explicitly list the .schemas files there. This helps to prevent problems after an update. Both the file list and the %post script must be updated if a new .schemas file appears and rpm warns if all installed files are not mentioned in the file list. The file list from the example above should look like:

%files
[...]
/etc/opt/gnome/gconf/schemas/epiphany.schemas
/etc/opt/gnome/gconf/schemas/epiphany-lockdown.schemas

instead of:

/etc/opt/gnome/gconf/schemas/*.schemas


10.1.2. GStreamer registry


A multimedia package can define its own multimedia plug-in for Gstreamer. This feature is used when the package installs any file to /opt/gnome/%_lib/gstreamer-{version}.

The GStreamer registry must be updated to make the plug-in visible. It should be done in both the %post and the %postun script. Do not forget to mention the utilities used in the PreReq tag. The related code then looks like:

PreReq:       /opt/gnome/bin/gst-register
[...]

%post
opt/gnome/bin/gst-register >/dev/null

%postun
opt/gnome/bin/gst-register >/dev/null

Paths can change in future versions of SuSE Linux.

Packages, except the package gstreamer, must not include the file /var/opt/gnome/cache/gstreamer-{version}/registry.xml. If it is created by make install in $RPM_BUILD_ROOT, it is a bug and the file must be removed.


10.1.3. Shared MIME Info


The shared MIME info is a new standard defined by freedesktop.org. See http://www.freedesktop.org/Standards/shared-mime-info-spec. It is used by new versions of GNOME.

This feature is used when the package installs any file to $datadir/mime and the distribution contains the shared-mime-info package. This package has been part of SUSE Linux since SL 9.2.

The shared MIME database is located in /usr/share/mime. Since SuSE Linux 9.3, GNOME packages can use /opt/gnome/share/mime, too.

Some packages call update-mime-database during installation with DESTDIR defined. It is a bug that can cause packaging of the actual MIME database instead of its component even if DESTDIR is set. The simplest work-around is to remove the generated files at the end of the %install section. Generally, everything except packages/*.xml are generated files and need to be removed. This example is taken from the package planner:

%install
[...]
cd $RPM_BUILD_ROOT/opt/gnome/share/mime
rm -f XMLnamespaces aliases globs magic subclasses application/x-planner.xml
rmdir application

The file /opt/gnome/share/mime/packages/planner.xml is left there to be included in the package.

Finally, the shared MIME database must be updated in the %post and %postun scripts. Do not forget to mention the needed packages in the PreReq tag. The related code then looks like:

PreReq:       shared-mime-info
[...]

%post
usr/bin/update-mime-database /opt/gnome/share/mime >/dev/null

%postun
usr/bin/update-mime-database /opt/gnome/share/mime >/dev/null

MIME types can be tested by the package nautilus. It is enough to install the tested package, start or restart Nautilus, and look at properties of a corresponding file. The installed MIME type should be defined properly there.


Note

/opt/gnome/share/mime was not supported in SL 9.2. That is why GNOME packages moved the related files to /usr/share/mime. This hack is obsolete and can be removed. It usually looked like:

%install
[...]
mkdir -p $RPM_BUILD_ROOT/usr/share
mv $RPM_BUILD_ROOT/opt/gnome/share/mime $RPM_BUILD_ROOT/usr/share


10.1.4. GNOME MIME Info


Older GNOME packages use mime-info for MIME type definitions. Such MIME types are not recognized by new version of GNOME. The package needs shared-mime-info, too. This feature is used when the package installs files in /opt/gnome/share/mime-info. If there are no files in /usr/share/mime or /opt/gnome/share/mime, the shared-mime-info must be generated from mime-info. See also Section 10.1.3, "Shared MIME Info".

The conversion can be done either by the script mime-info-to-mime provided by the package shared-mime-info, it can be called the following way in the %install section:

%install
[...]
DESTDIR=$RPM_BUILD_ROOT mime-info-to-mime

Or if the command fails, the generated files $RPM_BUILD_ROOT/usr/share/mime/packages/*.xml need to be manually edited. The fixed files are usually added to the package as an extra source and installed in the %install section. This example is taken from the package file-roller:

Source1:      file-roller.xml
[...]

%install
[...]
mkdir -p $RPM_BUILD_ROOT/usr/share/mime/packages
cp %{S:1} $RPM_BUILD_ROOT/usr/share/mime/packages

Finally, the new files must be listed in the %files section and the Shared MIME database must be updated in the %post and %postun scripts. See Section 10.1.3, "Shared MIME Info".


10.2. Kernel Modules


Detailed information about the kernel can be found at http://www.suse.com/~agruen/KMPM/.


10.3. Perl Modules


This section describes how Perl modules are packaged on SUSE Linux. The following rules are defined:


  • Each Perl module should be in a separate package.
  • The package name should be perl-XXX, where XXX is the original name of the source tarball, as obtainable at http://cpan.perl.org/by-module/XXX, except that the levels are separated by hyphens rather than slashes or double colons). See also Section 1.5, "Name Tag". (FIXME: this link is broken, as are most other internal links in this guide)
  • The RPM group should be Development/Libraries/Perl (unless it is at an application level package, in which case it might be Productivity/*)
  • The package should require Perl of the same version as was used for build. The macro %perl_version serves this purpose.


A dependency on Perl modules is not detected automatically. This means the packages must mention the necessary Perl modules in the Requires tag. This applies to the dependency between Perl modules as well.

The package perl and Perl modules should be mentioned in the BuildRequires tag.

This example of a typical spec file preamble comes from the package perl-Inline-CPR:

# norootforbuild
 # usedforbuild    ... perl perl-Inline perl-Parse-RecDescent ...
 
 
 Name:         perl-Inline-CPR
 License:      Artistic License
 Group:        Development/Libraries/Perl
 Version:      0.12
 Release:      151
 Autoreqprov:  on
 Requires:     perl = %{perl_version}
 Requires:     perl-Inline
 BuildRequires:	perl ... ????FIXME (the following section explains this tag, making the reader expect an example here) 
 Summary:      Write Perl subroutines in C
 URL:          http://cpan.org/modules/by-module/Inline
 Source:       Inline-CPR-%{version}.tar.bz2
 Patch:        Inline-CPR-%{version}.diff
 BuildRoot:    %{_tmppath}/%{name}-%{version}-build
 
 %description
 This module allows you to program C in perl. See also perl-Inline.
 
 
 Authors:
 --------
     Brian Ingerson <INGY@cpan.org>

In the example above, see that two other Perl modules are needed for build and at run-time. They are mentioned by the BuildRequires tag and the package perl-Inline is mentioned by the Requires tag. The second package perl-Parse-RecDescent need not be mentioned by the Requires tag because it is required already by perl-Inline.

Most Perl modules are built and installed a standard way. In addition, the macros %perl_make_install, %perl_process_packlist, %perl_vendorarch, and %perl_vendorlib are available. This makes it extremely easy to create a package. This approach is also used in the package perl-Inline-CPR from the example above. Here is the rest of its spec file:

%prep
%setup -n Inline-CPR-%{version}
%patch

%build
perl Makefile.PL
make
make test

%install
%perl_make_install
%perl_process_packlist

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-, root, root)
%doc Changes README MANIFEST
%{perl_vendorlib}/Inline/CPR*
%{perl_vendorarch}/auto/Inline/CPR
/var/adm/perl-modules/%{name}

In the example above, see how the macro %perl_process_packlist is used. It removes $RPM_BUILD_ROOT from some files and allows packing the file %perl_archlib/perllocal.pod as /var/adm/perl-modules/%{name}. See Section 3.15, "%perl_process_packlist" for more details.

SuSEconfig --module perl should be called after installing the package. It updates the %perl_archlib/perllocal.pod from the information saved in /var/adm/perl-modules. It is not called from the %post script because it would take ages if several packages are installed at once and each of them called this script independently.

If a module includes a part written in C, the $RPM_OPT_FLAGS can usually be passed the following way. The example is taken from the package perl-Bit-Vector:

%build
perl Makefile.PL OPTIMIZE="$RPM_OPT_FLAGS -Wall"
make
make test

10.4. Python Modules


This section describes how Python modules are packaged on SUSE Linux. The following rules are defined:


  • Each Python module should be in a separate package.
  • The package name should be python-XXX. See also Section 1.5, "Name Tag".
  • The RPM group should be Development/Libraries/Python.
  • The package should require Python of the same major version as was used for build. This avoids problems when upgrading Python. The macro %py_requires exists for this purpose. See how it is used in the example below.


The packages python and python-devel are usually needed to build. They need to be defined in the tag BuildRequires.

This example of a typical spec file preamble comes from the package python-numeric:

 # norootforbuild
 
 Name:           python-numeric
 BuildRequires:  python-devel
 Summary:        A Numerical Extension to Python
 Version:        24.2
 Release:        5
 %define tarname Numeric
 Source0:        %{tarname}-%{version}.tar.bz2
 License:        BSD, Python
 Group:          Development/Libraries/Python
 URL:            http://sourceforge.net/projects/numpy
 Autoreqprov:    on
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 %py_requires
 
 %description
 Numerical Python adds a fast and compact multi-dimensional array
 language facility to Python.
 
 Authors:
 --------
     numpy-developers@lists.sourceforge.net

Most Python modules use distutils now, so it is extremely easy to package them. This feature is documented at http://www.python.org/sigs/distutils-sig/. It is also used in the package python-numeric from the example above. Here is the rest of its spec file:

%prep
%setup -n Numeric-%{version}
%patch

%build
export CFLAGS="$RPM_OPT_FLAGS"
python setup.py build

%install
python setup.py install --root=$RPM_BUILD_ROOT \
                        --prefix=%{_prefix} \
       --record-rpm=INSTALLED_FILES

%clean
rm -rf $RPM_BUILD_ROOT

%files -f INSTALLED_FILES
%defattr(-,root,root)
%doc README changes.txt Demo

In the example above, see how the variable $RPM_OPT_FLAGS is usually used to build binaries. Also see in the install command that the option --record-rpm can be used to create a file list that is then used in the %files section. This feature currently exists only in SUSE Python packages. A patch for upstream is waiting for review.

If a package uses a nonstandard build method, the special RPM macros %py_ver, %py_incdir, %py_libdir and %py_sitedir can be used to get the location of Python directories.

This example is taken from the package python-fcgi:

Source0:      http://alldunn.com/python/fcgi.py
[...]

%prep

%build

%install
install -m755 -d $RPM_BUILD_ROOT/%{py_sitedir}
install -m644 %{S:0} $RPM_BUILD_ROOT/%{py_sitedir}
python%{py_ver} %{py_libdir}/compileall.py -d %{py_site}/ \
   $RPM_BUILD_ROOT/%{py_sitedir}

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root)
%{py_sitedir}/fcgi.py*

10.4. KDE 3.x Packages

For the beginning packager, a KDE packaging cookbook gives step by step instructions on how to package KDE apps.

A typical spec file for a KDE package looks like the following:

# norootforbuild


 Name:           knutclient
 Version:        0.9.3
 Release:        3
 License:        GPLv2
 URL:            http://www.foo.org
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  kdelibs3-devel update-desktop-files
 Source:         %{name}-%{version}.tar.bz2
 Requires:       nut
 Group:          Hardware/UPS
 Summary:        NUT GUI Interface

 %description
 Knutclient is a GUI interface for UPS system NUT
 

 Authors:
 --------
     john.doe@foo.org

The only KDE-specific thing in the heading is kdelibs3-devel in BuildRequires. This package is needed to build all KDE packages. There are couple of exceptions (e.g. kicker addons) which need a more specific development packages, for example kdebase3-devel or kdepim3-devel.

 %prep
. /etc/opt/kde3/common_options
 %setup -n %{name}-%{version} -q
update_admin
 

The file /etc/opt/kde3/common_options sets all the environment variables and flags to the correct values needed for compiling KDE applications. Do not at any time redefine $KDEDIR, $QTDIR etc as you may be used to doing when hand-compiling KDE.

update_admin is a shell macro that updates the admin dir of the package to the latest version from the kdelibs3-devel package. This initializes the (autotools) build system and will switch (depending on the distribution you build for) to unsermake as the default build tool.

If the package you're trying to build does not work with unsermake and it is not possible to fix that, you can use the --no-unsermake parameter to update_admin to force it use regular automake.

 %build
 . /etc/opt/kde3/common_options
 ./configure $configkde
 do_make %{?jobs:-j%jobs}
 

You have to source common_options again, this time to get the correct $RPM_OPT_FLAGS for the build phase. The $configkde variable contains all the right flags for a common ./configure call. It also adds --enable-final for newer distributions. This speeds compile time by concatenating all .cpp files into one and compiling them as one. If your package does not work with --enable-final, and it is not possible to fix that, you can add a --disable-final after $configkde to switch the default again.

'do_make' will call either make or unsermake depending on the way update_admin was called.

 %install
 . /etc/opt/kde3/common_options
 do_make DESTDIR=$RPM_BUILD_ROOT $INSTALL_TARGET
 %suse_update_desktop_file %name System Monitor
 %find_lang %name
 kde_post_install
 

The only custom macro here is kde_post_install. It does a couple of uninteresting things, like marking installed desktop files for translation or moving crystalsvg icons into hicolor, so that they're accessible from non-KDE desktops as well. It should always be the last nonstandard line in your %install section.

 %clean
 rm -rf "$RPM_BUILD_ROOT"
 

Standard %clean section.

 %files -f %name.lang
 %defattr(-,root,root)
 %doc README AUTHORS ChangeLog COPYING INSTALL
 /opt/kde3/bin/*
 /opt/kde3/share/apps/knutclient
 /opt/kde3/share/icons/??color
 /opt/kde3/share/applnk/Utilities/knutclient.desktop
 /opt/kde3/share/locale/*/LC_MESSAGES/*.mo
 /opt/kde3/share/doc/HTML/??/knutclient/*
 

This is a standard %files section, referencing the typical KDE application's structure of supporting files.


Prev

9. Desktop Menu

Home