Fedora Packager's Handbook (Draft 1)

Marius L. Jøhndal

Ville Skyttä

Copyright © 2004-2005 Marius L. Jøhndal, Ville Skyttä

This manual is free software; you may redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License for more details.

A copy of the GNU General Public License is available on the World Wide Web at the address http://www.gnu.org/copyleft/gpl.html. You can also obtain it by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

$Date: 2005/01/09 13:52:41 $

Abstract

TODO


Table of Contents

1. Introduction
2. Packaging guidelines
2.1. Writing a package from scratch
2.2. Modifying an existing package
2.3. Updating fedora.us packages
2.4. Package naming and versioning
2.4.1. The Name tag
2.4.2. The Version tag
2.4.3. The Release tag
2.5. Sources
2.5.1. Source pristineness
2.5.2. Trojans
2.5.3. Downloading sources
2.6. The .spec file
2.6.1. .spec file encoding
2.6.2. Summary and description
2.6.3. Change logs
2.6.4. Macro use
2.7. The use of particular tags
2.7.1. The Packager tag
2.7.2. The Vendor and Distribution tags
2.7.3. The Copyright tag
2.7.4. The License tag
2.7.5. The Group tag
2.7.6. The BuildRoot tag
2.7.7. The Epoch tag
2.8. Dependencies
2.8.1. Build requires
2.8.2. Versioned dependencies
2.8.3. The Requires(pre,post) notation
2.9. Build related issues
2.9.1. Re-building as non-root
2.9.2. Parallel make
2.9.3. Optimization flags
2.10. Handling particular file types
2.10.1. Installation scriptlets
2.10.2. info files
2.10.3. scrollkeeper files
2.10.4. GConf files
2.10.5. Locale files
2.10.6. Shared object files
2.11. Package payload
2.11.1. Installing files
2.11.2. Path macros
2.11.3. Directory ownership
2.11.4. File and directory user IDs
2.11.5. File and directory permissions
2.11.6. Documentation
2.12. .desktop files
2.12.1. .desktop file format
2.12.2. Installing .desktop files
2.13. Development packages
2.13.1. Using Provides instead of sub-package
2.13.2. pkgconfig files
2.13.3. libtool archives
2.14. Perl module packages
2.14.1. Dependencies
2.14.2. Installation directories
2.14.3. Compiler flags
2.14.4. Linker flags
2.14.5. Cleaning up unused files
2.14.6. CPAN signature considerations
2.15. Python extension packages
2.16. Security issues
2.16.1. Default passwords
2.16.2. Daemon privileges
3. Policy
4. QA checklist
4.1. Additional checklist items for packages with desktop applications
4.2. Additional checklist items for packages with libraries
4.3. Additional checklist items for Perl module packages
4.4. Additional checklist items for Python extension packages

Important

These are not the official fedora.us packaging or QA instructions. Please see The fedora.us home page for the official instructions.

Important

Please note that this document is a work in progress. If you have comments, corrections or want to contribute, please contact one of the authors.

1. Introduction

Mention that this is based on text from the fedora.us Wiki.

The purpose of this document is to describe both the formal and informal aspects of packaging for fedora.us.

TODO: Yep, policy stuff might belong in a separate document, but since hardly anything has been written on that topic yet, it might as well be kept here.

The formal aspects are covered by Section 3, “Policy” and Section 4, “QA checklist”. These detail the baseline requirements which all fedora.us packages must conform to. This is, in other words, the normative part of the document.

Section 2, “Packaging guidelines” focuses more on best practices for fedora.us package developers. These are recommendations and helpful hints, not requirements or policy. These sections also cover policy, but in a more informal way, explaining not only what the requirements are, but their motivation.

This document does not discuss the basics of creating an RPM package, using RPM or the technical details RPM packages. A useful basic introduction to RPM and package writing is Maximum RPM.

2. Packaging guidelines

TODO: Rename this section? TODO: Write an introduction. TODO: Categorize the subsections in a more sensible way.

2.1. Writing a package from scratch

When writing a package from scratch, you should base your spec file on one of the Fedora spec file template (see Fedora spec file templates). The spec template page needs updating, and the info on scriptlet parameters should be incorporated with this text. Please put your preferences about spec file formatting and organization aside, and try to conform to this template as much as possible. This is not because we believe this is the only right way to write a spec file, but because it often makes it easier for QA to spot mistakes and quickly understand what you are trying to do.

2.2. Modifying an existing package

If you base a package on an existing non-fedora.us package, be careful to verify its correctness and to understand exactly what goes on. Do not submit a package without knowing what those strange, but innocent-looking commands do.

When modifying existing packages, you should give credit to the original package author. This is best done by keeping old change log entries to credit the original authors. Entries that are several years old or refer to ancient versions of the software may be erased. If you end up doing radical changes and re-write most of the spec file anyway, feel free to start the change log from scratch. In other words, use your best judgment.

If you happen to find serious errors in the original package, it would be considered polite to inform the original author about the problems and share your solution.

TODO: List some references about other distros. Re-use the info from http://www.fedora.us/wiki/ReferenceMandrakeRPMMacros and http://www.fedora.us/wiki/ReferencePLDRPMMacros

2.3. Updating fedora.us packages

When you update a package, you should always increment the release number and add a entry to the change log.

2.4. Package naming and versioning

RPMs are conventionally identified by a package name, a package version and a package release number, all separated by hyphens, e.g. foobar-1.2.3-1. There may also be a fourth component, the package epoch, which is prefixed to the version number with a colon as separator: foobar-0:1.2.3-1. Each of these components are specified in the package .spec file in the tags Name, Version, Release, and Epoch.

The exact semantics associated with these tags has differed considerably between users of RPM over time. Based on experiences from different ways of using these tags, fedora.us has defined instructions on their proper use which ensure that packages are upgradable and avoid package conflicts.

2.4.1. The Name tag

The package name should preferably match the name of the upstream tarball or the name of the project. In some cases the choice of name is more complicated: When the software has already been packaged by other distributions or by other packagers, it may be a good idea to use the same package name for consistency. Packagers should use their best judgment and consult other developers if necessary.

2.4.2. The Version tag

If the version of a particular software distribution consists of numbers only, these can be put into the Version tag unmodified. If, however, it contains any non-numeric character, RPM will not always be able to handle version comparison correctly if these are put verbatim into the Version field.

As an illustration of what might happen, assume that you have the two packages foobar-1.2.3beta1 and foobar-1.2.3. While foobar-1.2.3 is actually newer than foobar-1.2.3beta1, RPM will assume that the opposite is the case if the version tags are set to 1.2.3beta1 and 1.2.3.

There is also a problem with version comparison in all RPM versions prior to 4.2-0.55: The result of the comparison of the two Version tags 1.0a and 1.0b is entirely a matter of the order of comparison.

fedora.us solves these problems by moving the non-numeric part of version numbers — whatever its intended function is — to the Release tag. The version number 1.2.3beta1, for example, should result in the Version tag 1.2.3, and beta1 would integrated into the Release tag. See Section 2.4.3, “The Release tag” for further details on the composition of the Release tag.

2.4.3. The Release tag

TODO

2.5. Sources

TODO: An introduction.

2.5.1. Source pristineness

TODO: pristine sources only, ways to assure that sources are pristine (verifying GPG signatures, asking upstream developers to confirm integrity, looking inside other distros' packages).

2.5.2. Trojans

TODO

2.5.3. Downloading sources

When downloading sources and patches, you should consider using a client that preserves the upstream timestamps. Such clients include wget and curl with the -N and -R options respectively.

To make the change permanent for wget, add

timestamping = on

to your ~/.wgetrc file.

See Section 2.11.1, “Installing files” for information about how to preserve timestamps when installing files.

2.6. The .spec file

TODO: A better title for this section? An introduction.

2.6.1. .spec file encoding

Unless you need to use characters outside the US-ASCII repertoire, you will not need to be concerned about the encoding of the spec file. If you do need non-ASCII characters, save your spec files as UTF-8.

2.6.2. Summary and description

The summary should be a short and concise description of the package. The description expands upon this. Do not include installation instructions in the description; it is not a manual. If the package requires some manual configuration or there are other important instructions to the user, refer the user to the documentation in the package. Add a README.Fedora file if you feel this is necessary.

Please put personal preferences aside and use American English spelling in the summary and description. Anything else belongs in localized versions.

2.6.3. Change logs

Every time you make changes, that is, whenever you increment the epoch-version-release-number of a package, add an entry to the change log. This is important not only to have an idea about the history of a package, but also to enable users, fellow packages, and QA people to easily spot the changes that you make.

Each entry should contain the date, the name and e-mail address of the person doing the update, and the complete epoch-version-release-number. Try this format:

* Wed May 14 2003 Joe Packager <joe at fedora.us> - 0:1.0-0.fdr.2
- Improved description.

If a change is related to a particular Bugzilla bug, include the bug ID in the entry for easy reference, e.g.

* Wed May 17 2003 Joe Packager <joe at fedora.us> - 0:1.0-0.fdr.3
- Added README file (bug 42).

Within Emacs you can easily add change log entries by pressing Ctrl+C followed by e in rpm-spec mode. Make sure that you have the fedora-rpmdevtools-emacs package installed to have the entries appear in the expected format.

2.6.4. Macro use

RPM sometimes offers multiple ways to express exactly the same thing. This is the case for the macro %{buildroot} and the variable $RPM_BUILD_ROOT which both expand to the path of the build root. The macro %{optflags} and the variable $RPM_OPT_FLAGS make up another pair of equivalents.

Whichever notation is used, it should be used consistently, and mixing the macro and variable notation is considered bad style.

Also note that the notation using variables, i.e. the $RPM_BUILD_ROOT notation, is considered the more official of the two (see Original posting).

2.7. The use of particular tags

TODO: Introduction

2.7.1. The Packager tag

The Packager tag should not be used in fedora.us packages. The identity of the packager will still be evident from the entries in the change log. By not using the Packager tag, packagers will also avoid seeing bad binaries rebuilt by someone else with their name in the header.

2.7.2. The Vendor and Distribution tags

The Vendor and Distribution tags should not be used in fedora.us packages. These are set automatically by the build system.

2.7.3. The Copyright tag

The Copyright tag is deprecated. Use the License tag instead.

2.7.4. The License tag

The License tag should indicate what license the software in the package is covered by. You should inspect the documentation and sources carefully to establish this. If there is any doubt about what license the software is distributed under, the upstream author should be contacted.

Make a table of the more common licenses and their abbreviations. Try to use established abbreviations and names, e.g. GPL, LGPL, BSD, Artistic.

2.7.5. The Group tag

The value of the Group tag should be one of the group names mentioned in the GROUPS file distributed with the rpm package. Table 1, “Valid values for the Group tag.” lists the group names found in rpm-4.3.1-0.

Table 1. Valid values for the Group tag.

Amusements/Games
Amusements/Graphics
Applications/Archiving
Applications/Communications
Applications/Databases
Applications/Editors
Applications/Emulators
Applications/Engineering
Applications/File
Applications/Internet
Applications/Multimedia
Applications/Productivity
Applications/Publishing
Applications/System
Applications/Text
Development/Debuggers
Development/Languages
Development/Libraries
Development/System
Development/Tools
Documentation
System Environment/Base
System Environment/Daemons
System Environment/Kernel
System Environment/Libraries
System Environment/Shells
User Interface/Desktops
User Interface/X
User Interface/X Hardware Support

2.7.6. The BuildRoot tag

The preferred value for the BuildRoot tag is

BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

2.7.7. The Epoch tag

TODO: can be optionally defined "0" or omitted entirely. Exception: Never add Epoch to Red Hat updated packages.

2.8. Dependencies

TODO: Introduction

2.8.1. Build requires

The build system builds packages in an environment with only a minimal set of installed packages. If the package to be built requires the presence of some package not in this set, e.g. by including a header file from a -devel package, the build will fail. Somehow the build system has to be informed of which packages are expected to be present, and this is accomplished by using a list of build requires in the .spec file specified using

Packages should therefore specify the build requires necessary to build the package using one or more BuildRequires tags. Packages should, however, only specify the minimal set of packages necessary to build the package. The minimal set of build requires does not include the packages that are in the list of base packages nor packages that are pulled in by any of the other build requires.

TODO: Finish this section!

2.8.2. Versioned dependencies

Whenever you use the Requires, BuildRequires, Provides, Obsoletes, Conflicts, or BuildConflicts tags and specify a particular version requirement, you should also specify the epoch.

TODO: Check discussion http://www.fedora.us/pipermail/fedora-devel/2003-March/000651.html for more details.

TODO: Include an example.

2.8.3. The Requires(pre,post) notation

The notation Requires(pre,post) for installation scriptlet dependencies should not be used. Such dependencies should instead be split into separate requirements, e.g.

Requires(post):  GConf2
Requires(preun): GConf2

This notation should not be used as it may trigger rpm bugs. Splitting the requirement is a simple work-around for these bug. (See original posting, first bug report, and second bug report.)

2.9. Build related issues

2.9.1. Re-building as non-root

TODO

2.9.2. Parallel make

Whenever possible, invocations of make should be done as

make %{?_smp_mflags}

This generally speeds up builds -- especially on SMP machines.

Do make sure, however, that the package actually builds cleanly this way as some make files do not support parallel building. You should therefore consider adding

%_smp_mflags -j3

to your ~/.rpmmacros file -- even if you have a UP machine -- to enable parallel builds, as this will expose the majority of such build failures.

2.9.3. Optimization flags

TODO

2.10. Handling particular file types

Rename this section!

2.10.1. Installation scriptlets

TODO: If it has info files, is there a %post script that installs them, and a %postun one which removes them (and only on erase, not upgrade)? Crossref to info file, scrollkeeper, ldconfig, GConf sections

2.10.2. info files

TODO

Requires(post): /sbin/install-info
Requires(preun): /sbin/install-info

%install
rm -f $RPM_BUILD_ROOT%{_infodir}/dir

%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir 2>/dev/null || :

%preun
if [ $1 = 0 ]; then
  /sbin/install-info --delete %{_infodir}/%{name}.info \
    %{_infodir}/dir 2>/dev/null || :
fi

%files
%{_infodir}/*

2.10.3. scrollkeeper files

TODO

Registering documentation with scrollkeeper can be done like this:

Requires(post): scrollkeeper
Requires(postun): scrollkeeper

%install
rm -rf $RPM_BUILD_ROOT/var/scrollkeeper

%post
scrollkeeper-update -q || :

%postun
scrollkeeper-update -q || :

%files
%{_datadir}/omf/*

2.10.4. GConf files

GConf is used by GNOME applications to store configuration data. It is similar to Windows' registry in functionality, and in the same as Windows applications register new key-value pairs when installed, GConf-enabled GNOME applications ship schema files that should be installed at package installation time.

Schema files have the extension .schema and are installed using the gconftool-2 utility shipped in the GConf2 package. The same utility is used to remove schema files when the package is uninstalled. The spec file fragment below will take care of this task in most cases:

Requires(post): GConf2
Requires(preun): GConf2

%install
export GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1
make install DESTDIR=$RPM_BUILD_ROOT
unset GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL

%post
GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source` \
  gconftool-2 --makefile-install-rule %{_sysconfdir}/gconf/schemas/%{name}.schemas &>/dev/null || :

%preun
if [ "$1" = "0" ] ; then
  GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source` \
    gconftool-2 --makefile-uninstall-rule %{_sysconfdir}/gconf/schemas/%{name}.schemas &>/dev/null || :
fi

%files
%{_sysconfdir}/gconf/schemas/*

Makefiles usually call gconf-install-tool as part of the install target. This behavior has to be disabled so that schemas are not installed when the package is built. This is the reason for the setting and unsetting of the GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL variable in the %install section. In some cases schema installation is also performed as part of the default makefile target, so that the GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL must be set and unset in the %build section too.

Removing the schemas when the package is uninstalled is important to avoid compatibility problems. Unfortunately the --makefile-uninstall-rule option to gconftool-2 does not exist in the versions shipped with RedHat Linux 8.0 and 9. To avoid failing %preun scriptlets and error message noise on these distributions, the shell magic shown in the spec file fragment above should be added to the uninstallation command.

2.10.5. Locale files

TODO

2.10.6. Shared object files

TODO: If it installs files named *.so.* into %{_libdir}, is there a %post -p /sbin/ldconfig and %postun -p /sbin/ldconfig?

2.11. Package payload

2.11.1. Installing files

When using copy commands or file installation commands in the spec file, consider using a command that preserves timestamps.

With both cp and install this is accomplished by using the -p switch, e.g.

install -p -m 0644 foobar.xml %{_datadir}/%{name}/foobar.xml

To take advantage of timestamp preservation, timestamps have to be correct in the first place. See Section 2.5.3, “Downloading sources” for more information about this.

2.11.2. Path macros

Use macros instead of hard-coded path names. This is particularly important when the source code accepts custom install paths via some sort of configure script.

Verify this table. Values were taken from RHL 9 (rpm-4.2-0.69). Changes/variants should be noted.

Table 2. Path macros.

MacroFully expanded value
%{_sysconfdir}/etc
%{_initrddir}/etc/rc.d/init.d
%{_bindir}/usr/bin
%{_libdir}/usr/lib
%{_libexecdir}/usr/libexec
%{_sbindir}/usr/sbin
%{_sharedstatedir}/usr/com
%{_datadir}/usr/share
%{_includedir}/usr/include
%{_infodir}/usr/share/info
%{_mandir}/usr/share/man
%{_localstatedir}/var

2.11.3. Directory ownership

Summarize http://www.fedora.us/pipermail/fedora-devel/2003-June/001458.html

2.11.4. File and directory user IDs

TODO: Check ownership of files and directories included within every binary RPM package, e.g. with "rpm -qlv packagename". Check use of %defattr and %attr macros in %files sections.

2.11.5. File and directory permissions

TODO: Check permissions of files and directories included within every binary RPM package, e.g. with "rpm -qlv packagename". Check use of %defattr and %attr macros in %files sections.

2.11.6. Documentation

Any relevant documentation included in the source distribution should be included in the package. Irrelevant documentation include build instructions, the omnipresent INSTALL file containing generic build instructions, for example, and documentation for non-Linux systems, e.g. README.FreeBSD.

2.12. .desktop files

Packages with desktop applications should include .desktop files. These files are used by both GNOME and KDE to describe how an application should be launched and how it should appear in menus.

2.12.1. .desktop file format

The .desktop file format was standardized by freedesktop.org in the Desktop Entry Standard and the list of legal values for the Category key in .desktop files is specified in Appendix A of the Desktop Menu Specification.

The utility desktop-file-validate found in the desktop-file-utils package can be used to validate .desktop files. On pre-FC1 systems you should be aware of a bug which prevents it from handling .desktop files with the Encoding key set (see Original bug report).

In addition to a proper selection of categories from the standard set, .desktop files in fedora.us packages are expected to include the category Application for everything that is supposed to show up in the menus. This is for backwards compatibility. For packages that already exist in Red Hat Linux or Fedora Core, the categories must match the ones in the official packages.

Additionally, all fedora.us packages must use the X-Fedora category. This is usually added when the .desktop file is installed (see Section 2.12.2, “Installing .desktop files” for details).

In particular, make sure that startup-notification (defined in the Startup notification protocol) is enabled. Add

StartupNotify=true

for GNOME 2.2 or later, and

X-KDE-StartupNotify=true

for KDE applications. For other applications compatibility mode should be enabled. This is accomplished by adding

StartupWMClass=string

to the .desktop file where string is a window manager class string for the application. This string can be determined by running

xprop | grep WM_CLASS

and clicking in the application window. For Emacs the following is reported by xprop, for example:

WM_CLASS(STRING) = "emacs", "Emacs"

This means that either of the strings emacs or Emacs would be a valid window manager class string.

Add an example of a "model" .desktop file.

Add a note on boolean notation vs. 0/1?

2.12.2. Installing .desktop files

.desktop files should be installed using the utility desktop-file-install which is found in the desktop-file-utils package.

The files should be installed in the %{_datadir}/applications directory, and when being installed, the vendor prefix should be set to fedora. A typical installation procedure would look like this:

BuildRequires:  desktop-file-utils

%install
desktop-file-install                                       \
  --vendor fedora                                          \
  --dir $RPM_BUILD_ROOT%{_datadir}/applications            \
  --add-category X-Fedora                                  \
  --add-category Application
  %{name}.desktop

%files
%{_datadir}/applications/*%{name}.desktop

Note that this adds the two categories X-Fedora and Application required for fedora.us packages (see Section 2.12.1, “.desktop file format” for details), and is thus suitable for installing valid .desktop files shipped in software distributions.

Some makefiles install .desktop files along with the rest of the files that should be installed. Such .desktop files have to be "re-installed" so that the correct categories and the vendor prefix can be added. This can be done using the following procedure:

BuildRequires:  desktop-file-utils

%install
desktop-file-install                                       \
  --delete-original                                        \
  --vendor fedora                                          \
  --dir $RPM_BUILD_ROOT%{_datadir}/applications            \
  --add-category X-Fedora                                  \
  --add-category Application                               \
  $RPM_BUILD_ROOT%{_datadir}/applications/%{name}.desktop

%files
%{_datadir}/applications/*%{name}.desktop

2.13. Development packages

Some software distributions, in particular libraries, include files that are useful only to developers. These should be put into a separate sub-package conventionally named the same as the main package, but with -devel suffixed to the name.

A typical development sub-package for a library would require additional %package and %description sections like these:

%package        devel
Summary:        Header files and static libraries for %{name}
Group:          Development/Libraries
Requires:       %{name} = %{epoch}:%{version}-%{release}

%description    devel
This package contains header files and static libraries for %{name}.

Typical files to be included in development sub-packages are C/C++ include files (usually files with the extension .h), the unversioned links to shared object files (links with a .so extension), static libraries (files with a .a extension), pkgconfig files (see Section 2.13.2, “pkgconfig files” for details), and -config scripts.

Also some documentation files are suitable for development sub-packages: Manual packages in manual section 3 should be packaged among the rest of the development files. Development related documentation, e.g. API documentation, should be flagged as documentation in the development sub-package. The fragment below should cover files appropriate for a typical development sub-package:

%files devel
%defattr(-,root,root,-)
%doc HACKING
%{_bindir}/%{name}-config
%{_includedir}/*.h
%{_libdir}/*.a
%{_libdir}/*.so
%{_libdir}/pkgconfig/*.pc
%{_mandir}/man3/*

Notice that the .la files generated by libtool are not included in this list (see Section 2.13.3, “libtool archives” for details).

2.13.1. Using Provides instead of sub-package

Even when a particular software distribution includes development files, it might not always be appropriate to put these in a separate sub-package. If there is only a single include file, for example, and it is unlikely that the number of such files will increase in the near future, it will probably not be worth the trouble creating a separate development sub-package. You should instead consider packaging it in the main package and using the Provide mechanism to emulate the existence of the development sub-package:

Provides:       %{name}-devel = %{epoch}:%{version}-%{release}

This mechanism ensures that a development sub-package may be split out from the main package at a later time, should the need arise. For this to work packages depending on the development files in question must have build dependencies on the emulated -devel package, not the main package.

2.13.2. pkgconfig files

pkgconfig files are provided by many software distributions to simplify the configuration and build process. These files are only useful for software developers and belong in a development sub-package.

Whenever pkgconfig files are included, the package should explicitly require the pkgconfig package. In a typical development sub-package with pkgconfig files, this would look like this:

%package        devel
Requires:       pkgconfig

2.13.3. libtool archives

Packaging the .la files generated by libtool is generally not necessary, and may, in fact, cause problems. In general packages should therefore not include these files.

If you package software which generates such files, you should delete them in the %install section:

%install
find $RPM_BUILD_ROOT -type f -name "*.la" -exec rm -f {} ';'

This is preferred to using the %exclude mechanism in the %files section.

2.14. Perl module packages

Portable, Perl version agnostic packaging of Perl modules is black art. When starting a new module package, a good starting point is always the Perl spec file template spectemplate-perl.spec included in the fedora-rpmdevtools package from fedora.us. The guidelines in this section are implemented in the template.

Most of these guidelines are directly applicable to packages using ExtUtils::MakeMaker for installation and its quirks. Some packages use Module::Build which is an emerging replacement for it, and they do not generally suffer from the same unportability. Whenever there is a choice of which of these to use, Module::Build is recommended.

2.14.1. Dependencies

Perl module packages typically require Perl to build. Even though Perl is currently already pulled in by the general build toolchain, it should be listed as a build dependency because support for vendor install directories is available in Perl 5.6.1 and later. Thus, all Perl modules packages should contain:

BuildRequires: perl >= 1:5.6.1

Build and runtime dependencies on other Perl modules should in general use the perl(Some::Module) syntax instead of the package names for flexibility. New modules are regularly folded into upstream Perl between releases; requiring the actual modules minimizes maintenance when package names change. Note that usually rpm figures out the runtime module dependencies correctly automatically, so explicitly including them is seldom necessary.

Since we assume Perl 5.6.1 or newer, there is no need to include explicit dependencies to modules which are already part of it. However, build dependencies on modules which are not part of 5.6.1 must be explicitly included.

In order to depend on a correct version of Perl at runtime, the virtual package perl(:MODULE_COMPAT_X.Y.Z) provided by recent versions of Perl in Fedora Core should be used. For earlier distribution versions, the package perl-forward-compat from fedora.us provides this. :MODULE_COMPAT_X.Y.Z means that the package to be built requires a Perl which is compatible with regards to it's modules and their installation locations to the one that built the module package. Example:

Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))

2.14.2. Installation directories

Perl provides different base locations for installing modules. We consider fedora.us a vendor, so packages should use the vendor installation directories, and leave site install directories for local administrators. This is accomplished by appending INSTALLDIRS=vendor to the Makefile.PL line for packages that use ExtUtils::MakeMaker, and installdirs=vendor to the Build.PL line for packages that use Module::Build. Vendor install directories are available in Perl 5.6.1 and later.

As of rpm version 4.3-0.9 and later (roughly equals Fedora Core 2 and later), two useful rpm macros are available: %{perl_vendorlib} and %{perl_vendorarch}. The former points to the base vendor install directory where Perl installs architecture independent pure Perl modules, and the latter is the same for architecture dependent ones. It is strongly recommended to use these macros in the %files section of Perl module packages; doing so hides the complexity and potential fragility of homebrew solutions of finding the directories where modules are installed. If support for rpm versions where these macros are not available is needed, they can be conditionally defined in specfiles like:

%{!?perl_vendorlib: %define perl_vendorlib %(eval "`%{__perl} -V:installvendorlib`"; echo $installvendorlib)}
%{!?perl_vendorarch: %define perl_vendorarch %(eval "`%{__perl} -V:installvendorarch`"; echo $installvendorarch)}

Note that only one of these macros is needed in the vast majority of Perl module specfiles; as a rule of thumb, %{perl_vendorlib} is for pure Perl noarch packages, and %{perl_vendorarch} for others.

2.14.3. Compiler flags

TODO: check whether both CFLAGS and OPTIMIZE are needed with ExtUtils::MakeMaker packages. Check also if Module::Build uses CFLAGS, and if it's The Right Thing To Do to use optimize=foo and/or CFLAGS.

Like with all non-noarch packages, architecture dependent Perl module packages should honor rpm's optimization flags. To accomplish this in modules using ExtUtils::MakeMaker, set CFLAGS="$RPM_OPT_FLAGS" in the environment before running Makefile.PL, and add the OPTIMIZE="$RPM_OPT_FLAGS" make variable to the main compilation step for backwards compatibility. For module packages using Module::Build, use optimize="$RPM_OPT_FLAGS" in the main compilation step.

2.14.4. Linker flags

The ExtUtils::MakeMaker included in distributions before Fedora Core 2 has a habit of creating spurious RPATHs containing build root dirs in Perl module *.so's. Due to another bug, this cannot be robustly avoided by (un)setting LD_RUN_PATH during the build. The following hack can (and is recommended to) be used instead, in the %build section after the Makefile has been created but before the actual make has been run:

%{__perl} -pi -e 's/^\tLD_RUN_PATH=[^\s]+\s*/\t/' Makefile

It should be safe to include this hack also in specfiles targeted for Fedora Core 2 and newer, although it is most likely unnecessary there. Note also that this hack will get rid of all RPATHs, including legitimate ones, so for the (rare) cases where an RPATH is actually needed, a more fine-grained solution needs to be applied.

2.14.5. Cleaning up unused files

TODO: cleaning up in %install

2.14.6. CPAN signature considerations

More and more CPAN module packages contain digital signatures of the packages' contents inside the distribution tarball. These signatures are usually in a file called SIGNATURE in the distribution, and can be used to verify the integrity of the tarball contents using the cpansign utility available in the perl-Module-Signature package. Additionally, many module distributions verify this signature in their test suite when running make test. That's nice.

However, this built-in integrity checking has a few features that interfere with building rpms: it makes patching of the package practically impossible or at least unnecessarily hard, it may choke on extra files in the build root (such as debug*.list automatically generated for -debuginfo packages), it may need a network connection for fetching keys, and it may silently import those keys in keyrings where we don't want them.

Because of the issues above, and since the shipped source and binary rpms are signed anyway, it is strongly recommended to ensure that this built-in verification is not done when building the rpm (whether perl-Module-Signature is installed in the build system or not), usually by patching the module's test suite one way or another. On the other hand, packagers are encouraged to verify the CPAN signatures manually using cpansign when packaging these modules.

2.15. Python extension packages

TODO: explain %{python_sitelib}, %{python_sitearch}

TODO: dependencies, including python-abi virtual

TODO: distutils stuff for %build and %install, %ghost'd *.pyc and/or *.pyo

2.16. Security issues

2.16.1. Default passwords

Summarize http://www.fedora.us/pipermail/fedora-devel/2003-August/001847.html

2.16.2. Daemon privileges

TODO: Does the package ship daemons or similar programs which support execution as non-root? It is a packaging-error when the daemon runs as root, or as a standard user like nobody. Instead a special user should be used. Discussion at http://www.fedora.us/pipermail/fedora-devel/2003-June/001492.html.

3. Policy

4. QA checklist

This list contains check items that should be verified for any package that passes through QA. Each item is phrased as a "The package must" or "The package must not" statement; an actual explanation of the issue is given in Section 2, “Packaging guidelines”.

These are not ordered in order of importance, but should be treated as equally important.

  1. The package must be correctly named and versioned. (Details)

  2. The package must contain pristine sources. (Details)

  3. The package must contain sources that are free from trojans. (Details)

  4. The package must re-build as non-root. (Details)

  5. The package must have correct installation scriptlets. (Details)

  6. The package must use the Epoch tag in the correct way. (Details)

  7. The package must specify the epoch for any versioned dependency. (Details)

  8. The package must list the correct BuildRequires. (Details)

  9. The package must use an official value for the Group tag. (Details)

  10. The package must use macros for all paths for which there are standardized macros. (Details)

  11. The package must not install unowned directories. (Details)

  12. The package must install files and directories with correct user IDs. (Details)

  13. The package must install files and directories with correct permissions. (Details)

  14. The package must not use the Copyright tag. (Details)

  15. The package must invoke make as make %{?_smp_mflags} whenever possible. (Details)

  16. The package must not use the Requires(pre,post) notation. (Details)

  17. The package must not ship with any default passwords. (Details)

  18. The package must not ship daemons or similar programs running as root or any standard user if non-root execution is supported. (Details)

4.1. Additional checklist items for packages with desktop applications

Define "desktop application"?

  1. The package must supply a valid .desktop file. (Details)

  2. The package must install the .desktop file correctly. (Details)

4.2. Additional checklist items for packages with libraries

  1. The package must supply appropriate post-installation scriptlets for any *.so.* files installed in %{_libdir}. (Details)

4.3. Additional checklist items for Perl module packages

  1. The package must install into vendor install directories. (Details)

  2. TODO: more

4.4. Additional checklist items for Python extension packages

TODO