From Fedora Project Wiki

Redirect page

Packaging Hints

This is a collection of some guidelines for writing packages. None of the things mentioned here are mandatory, but most of it is considered to be good practices by packagers and QA people. If you are new to, you should try to stick as closely to these guidelines as possible. When you have gained some experience working with packages, you will know when to deviate from them.

Please remember that any package that you submit must also conform to the ["QAChecklist"] .

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-rpmdevtools"] ). 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.

Modifying an existing package

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

In particular, you should

  • verify any sources and patches.
  • verify that the license stated in the spec file matches the actual license of the software (see Tags ),
  • skim the summary and description for typos and oddities (see Summary and description ),
  • make sure that the correct build root is used,
  • ensure that macro usage is consistent (see Macros ).

Keep old changelog entries to credit the original authors. Entries that are several yers 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 changelog from scratch. In other words, use your best judgement.

Use rpmlint

Run rpmlint on the rpms to examine them for common errors, and fix them (unless rpmlint is wrong, which can happen, too). The rpmlint package is available from Fedora stable.


Every time you make changes, that is, whenever you increment the E-V-R of a package, add a changelog entry. 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.

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

* Wed May 14 2003 Joe Packager <joe at> - 0:1.0-0.fdr.2
- Added README file (#42).


  • The Packager tag should not be used in spec files. The identities of the packagers are evident from the changelog entries. By not using the Packager tag, you also avoid seeing bad binaries rebuilt by someone else with your name in the header. See also the Maximum RPM definition of the Packager tag at . If you need to include information about the packager in the rpms you built, use %packager in your ~/.rpmmacros instead.
  • The Vendor tag should not be used. It is set automatically by the build system.
  • The Copyright tag is deprecated. Use the License tag instead. Use standard abbreviations and names, e.g. GPL, LGPL, BSD, Artistic. Contact the upstream author if there is any doubt about what license the software is distributed under.

Build root tag

The preferred value for the BuildRoot tag is

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

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, or similar, 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.


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.


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.MSDOS. Pay also attention about which subpackage you include documentation in, for example API documentation belongs in the -devel subpackage, not the main one. Or if there's a lot of documentation, consider putting it into a subpackage. In this case, it is recommended to use *-doc as the subpackage name, and Documentation as the value of the Group tag.


Use macros instead of hard-coded directory names (see ["Extras/RPMMacros"] ).

Please avoid using macros in the source URLs, prefer, for example, over{name}/%{version}/%{name}-%{version}.tar.bz2 While using macros saves you as a package maintainer some time whenever you update the package, QA will have to reconstruct the source URL manually when the validity of the sources is checked. The net effort saved by using macros is therefore neglible. (And, no, rpm is unable to emit the fully expanded source URLs from a spec file; and, yes, in the long run we will need a tool which does away with this issue, e.g. this experimental one at

Does the package have any %{buildroot} macros? If so, note that the corresponding $RPM_BUILD_ROOT variable is considered more official. Ditto for %{optflags} -> $RPM_OPT_FLAGS. For more info, see


When adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, eg. cp -p or install -p.

Ditto, when downloading sources, patches etc, consider using a client that preserves the upstream timestamps. For example wget -N or curl -R. To make the change global for wget, add this to your ~/.wgetrc: timestamping = on, and for curl, add to your ~/.curlrc: -R.

Parallel make

Whenever possible, invokations of make should be done as

make %{?_smp_mflags}

This generally speeds up builds and especially on SMP machines.

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

%_smp_mflags -j3

to your ~/.rpmmacros file -- even on UP machines -- as this will expose most of these errors.

Scriptlets requirements

Do not use the Requires(pre,post) style notation for scriptlet dependencies, because of two bugs in RPM. Instead, they should be split like this:

Requires(pre): ...
Requires(post): ...

For more information, see .

Running scriptlets only in certain situations

When the rpm command executes the scriptlets in a package it indicates if the action preformed is an install, erase, upgrade or reinstall by passing an integer argument to the script in question according to the following:

install   erase   upgrade  reinstall
%pre         1        -         2         2
%post        1        -         2         2
%preun       -        0         1         -
%postun      -        0         1         -

This means that for example a package that installs an init script with the chkconfig command should uninstall it only on erase and not upgrade with the following snippet:

if [ $1 -eq 0 ] ; then
/sbin/chkconfig --del %{name}

See also /usr/share/doc/rpm-*/triggers.

Conditional dependencies

If the spec file contains conditional dependencies selected based on presence of optional --with(out) foo arguments to rpmbuild, build the source RPM to be submitted with the default options, ie. so that none of these arguments are present in the rpmbuild command line. The reason is that those requirements get "serialized" into the resulting source RPM, ie. the conditionals no longer apply. While the build system is unaffected by this, it may cause confusion when reviewing the package.

Build and sign with separate user accounts

When building software, which you have not conducted a full security-audit on, protect sensitive data, such as your GPG private key, in a separate user account. When signing packages, do not use rpmbuild --sign, but use rpm --addsign (or rpm --resign) from within a different user account than your build account.

The same applies to reviewers/testers. Rebuild src.rpms in a separate account which does not have access to any sensitive data.