Fedora Packaging Guidelines

The Packaging Guidelines are a collection of common issues and the severity that should be placed on them. While these guidelines should not be ignored, they should also not be blindly followed. If you think that your package should be exempt from part of the Guidelines, please bring the issue to the Fedora Packaging Committee.

These documents cover the fine details of acceptable Fedora packaging and while they may include various examples they will not be particularly useful as a tutorial. They also do not cover the details and policies relating to gaining access to the Fedora repositories as a packager, or the mechanics of actually creating and releasing packages as part of the distribution. For documents which cover those issues, please see the following:

It is the package reviewer’s responsibility to point out specific problems with a package and a packager’s responsibility to deal with those issues. The reviewer and packager work together to determine the severity of the issues (whether they block a package or can be worked on after the package is in the repository.) Please remember that any package that you submit must also conform to the Review Guidelines.

The original author of these documents is Tom 'spot' Callaway, though they were originally based on many other documents. They have been significantly modified over the years by many members of the Packaging Committee.

The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in these guidelines are to be interpreted as described in RFC 2119.

Report issues with these guidelines, including typos, here.

Applicability

In general, these guidelines apply to the currently released, non-end-of-life versions of Fedora, as well as the development version of Fedora (Rawhide). If a particular portion of these guidelines is relevant only to a subset of those releases, this will be specifically noted. However, please note that Rawhide can change rapidly, and there will be times when changes are visible there which are not yet reflected here.

The guidelines also to some degree cover packages for EPEL, but only when combined with the EPEL packaging guidelines. Fedora packaging changes far more rapidly than EPEL packaging, so over time these guidelines will drift further away from any particular EPEL release and for the older supported EPEL release the differences can be quite significant. Portions of these guidelines which do not apply to EPEL will not generally be indicated.

General Exception Policy

As these guidelines can never cover all possible contingencies, there will always be packages which need exceptions. It is the packager’s responsibility to follow these guidelines as closely as is feasible and to clearly document, as comments in the package specfile, instances where they cannot be followed.

If, in a guideline, the language "should" or "is suggested" is used and it is not feasible for the package to conform to that guideline, the packager may deviate from the it. The nature of the deviation and the reasoning behind it MUST be documented in the specfile.

Where the language "must", "is required to" or "needs to" is used, the packager may deviate from the guideline only with approval from the packaging committee. Please follow the procedure at the Packaging Committee page for making these requests.

Allowed Packages

Please review What Can Be Packaged to ensure that what is to be packaged is allowed in Fedora.

Naming

You should go through the Naming Guidelines to ensure that your package is named appropriately.

Version and Release

Documentation covering the proper way to use the Version and Release fields can be found here.

Licensing

You should review the information regarding licenses determined to be allowed in Fedora and the Licensing Guidelines to ensure that your package is licensed appropriately and that the license is properly indicated.

Fedora Trademarks

Packagers MUST NOT add any Fedora trademark assets including the Fedora logo, Fedora logo icons, or graphics that include the Fedora logo. Those assets MUST be added to the fedora-logos package. Your packages(s) install the logos by depending on the fedora-logos package. If the upstream contains Fedora trademark assets that you believe are used inappropriately, email legal@fedoraproject.org

This is because the Fedora logo is a trademark, which are handled under a different legal framework than code. It must only be distributed under terms that protect the trademark. Keeping Fedora trademarks separate in their own package instead of scattered across various other packages is also an essential practice for enabling remixes that necessarily must not use the Fedora trademark, and instead roll their own *-logos package or use the generic-logos package.

Libraries and Applications

Many language- or domain-specific guidelines refer to "libraries", "modules", "plug-ins" or other terms specific to the language or domain. This is specifically important to package naming. Some applications may include libraries, and some libraries may include applications, so the distinction is not always clear.

Library or Application?

  • If the primary purpose of a package is to provide executables to be run by users, it SHOULD be packaged as an application. If it also includes libraries which may be imported or linked to by other code, see Mixed Use Packages below.

  • If the primary purpose of a package is to provide libraries intended to be imported or loaded into other code, it is considered a library and MUST be packaged as such. If it contains utility programs that can be run by users as well, see Mixed Use Packages below.

It is left to the packager to determine the primary purpose of a package. Often times upstream will already have done this with their choice of naming and that choice SHOULD be followed by the Fedora packager.

Mixed Use Packages

Many packages, regardless of their primary purpose, include both applications and libraries. In this case one or both SHOULD be packaged in subpackages in order to allow other applications to depend on only the library and not the associated application(s). Installing an application that depends on a library or service should not automatically pull in other applications associated with that library or service.

Package Independence

Packages SHOULD be installable independently whenever this is technically feasible, but they MUST specify dependencies of correct type on other packages if necessary, see Dependency Types below.

Desktop applications MUST NOT depend on other desktop applications unless strictly required. In particular, packages that contain a visible .desktop file (a .desktop file that does not contain the line NoDisplay=true) SHOULD NOT have a Requires, Recommends, or Supplements on any other package containing a visible desktop file, directly or indirectly.

For example, it would be reasonable for a video game level editor to require the associated video game in order to function, or for an application’s plugin to require the associated application. But it would not be reasonable for an application that happens to use a database library to depend on a database management suite associated with that library, or for an application that happens to use a particular programming language to depend on management tools associated with that programming language.

If a source package provides multiple graphical applications, those applications SHOULD be packaged in separate subpackages when feasible.

Spec Files

The spec file ("spec") is a fundamental element in the packaging workflow. Any change that is made to the package will include a change to the spec. Because packages in Fedora are maintained by a community of packagers as well as automated tooling, it is important for the specs to follow certain conventions. The bulk of these packaging guidelines involves what goes into a spec, but here are a few general items.

Spec File Naming

The spec file MUST be named %{name}.spec. That is, if your package is named example, the spec file must be named example.spec.

Spec Legibility

All spec files MUST be legible and maintained in such a way that the community of packagers is able to understand and work with them.

To help facilitate legibility, only macros and conditionals for Fedora and EPEL are allowed to be used in Fedora Packages. Use of macros and conditionals for other distributions, including Fedora derivatives, is not permitted in spec files of packages in the main Fedora repositories unless those macros and conditionals are also present in Fedora.

Spec File Encoding

Unless you need to use characters outside the 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. If you’re in doubt as to what characters are ASCII, please refer to this chart.

Non-ASCII Filenames

Similarly, filenames that contain non-ASCII characters must be encoded as UTF-8. Since there’s no way to note which encoding the filename is in, using the same encoding for all filenames is the best way to ensure users can read the filenames properly. If upstream ships filenames that are not encoded in UTF-8 you can use a utility like convmv (from the convmv package) to convert the filename in your %install section.

Spec Maintenance and Canonicity

Fedora’s git repository is the canonical location for Fedora spec files. Maintainers MUST expect that other maintainers and automated tooling will make changes to their packages, potentially without communicating prior to doing so (though communication is always encouraged). If some maintainers are also attempting to keep copies of a spec in an outside repository, they MUST be prepared to merge changes made to the spec in Fedora’s repository, and MUST NOT overwrite those changes with a copy from an external repository or using fedpkg import.

Source File Verification

Where the upstream project publishes OpenPGP signatures of their releases, Fedora packages SHOULD verify that signature as part of the RPM build process.

Although a checksum in the sources file certifies that a file retreived from the lookaside cache is the one that the packager uploaded, it is silent on whether the file is what the upstream project released. A signature by the upstream developers certifies that the source is identical to what they released. Verifying the signature as part of the build ensures that packagers don’t forget to verify it.

Obtaining the Correct Keys

The verification method requires one or more OpenPGP keyring files with public keys from the upstream project. The keyrings shall together contain all the keys that are trusted to certify the authenticity of the sources, and MUST NOT contain any other keys.

Ideally the upstream project publishes such a keyring as a downloadable file. You shall download that file and do everything you reasonably can to verify that it is authentic. Then you shall add it unmodified to the package SCM, and provide its URL in the spec file so that others can verify it. The URL MUST use HTTPS or a similarly authenticated protocol if at all possible.

Even if you are unable to verify the key at the first addition, it still enhances security in a trust-on-first-use way. It will ensure that future attacks will be detected if the key is the right one, or that a current attack will be detected later if future releases are signed by the correct key.

Verifying Signatures

When source file verification is done, it MUST be done first in the %prep section of the spec file, before any potentially compromised code is executed. The verification MUST be done with the macro %{gpgverify}, which expands into a command whose parameters shall be the pathnames of the keyring, the signature and the signed file. BuildRequires: gpgverify is necessary for the verification to work.

Any detached signature file (e.g. foo.tar.gz.asc or foo.tar.gz.sig) must be uploaded to the package lookaside cache alongside the source code, while the keyring must be committed directly to the package SCM.

The following format must be used:

Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz
Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz.asc
Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg
…
BuildRequires: gpgverify
…
%prep
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'

The first source is the actual tarball, the second one is the signature from upstream, and the third one is the keyring.

Exceptions

If the upstream tarball of a package needs to be modified, for example because it contains forbidden items, then the tarball cannot be verified as part of the build process. In this case the upstream OpenPGP keyring must still be included in the package SCM and the instructions/script used to build the stripped-down tarball needs to verify the upstream source.

If the upstream project does not publish a keyring file (for example if they publish only a fingerprint on their website and refer to a keyserver network for downloading the key), then you may need to create a keyring after you have verified the key. In this case there is no upstream URL to the keyring, so instead you should document how you created the keyring in a comment in the spec file. A minimal keyring with the key with the fingerprint 7D33D762FD6C35130481347FDB4B54CBA4826A18 can be created with the following command:

gpg2 --export --export-options export-minimal 7D33D762FD6C35130481347FDB4B54CBA4826A18 > gpgkey-7D33D762FD6C35130481347FDB4B54CBA4826A18.gpg

If upstream signed a tarball differently, for example by signing only the uncompressed tarball but distributing a compressed version, then the verification step must be adjusted accordingly, for example:

Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.xz
Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.asc
Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg
…
BuildRequires: gpgverify xz
…
%prep
xzcat '%{SOURCE0}' | %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data=-

If the data and the signature are combined in a single file, then the signed data must be written to an output file:

%{gpgverify} --keyring='%{SOURCE1}' --data='%{SOURCE0}' --output=<pathname>

Packages that are vital during bootstrapping of Fedora may use a bootstrap flag to skip the verification before GPGverify and GnuPG have been built.

Help

If you need help getting your package compliant to this guideline, or if you do not know what to do if a build fails on a signature verification, then you should seek help on the Fedora devel mailing list before circumventing the check, to make sure that you do not build compromised software.

Architecture Support

All Fedora packages must successfully compile and build into binary rpms on at least one supported primary architecture, except where the package is useful only on a secondary architecture (such as an architecture-specific boot utility, microcode loader, or hardware configuration tool). Fedora packagers should make every effort to support all primary architectures.

Content, code which does not need to compile or build, and architecture independent code (noarch) are notable exceptions.

Architecture Build Failures

If a Fedora package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in ExcludeArch. Each architecture listed in ExcludeArch needs to have a bug filed in bugzilla, describing the reason that the package does not compile/build/work on that architecture. The bug number should then be placed in a comment, next to the corresponding ExcludeArch line. New packages will not have bugzilla entries during the review process, so they should put this description in the comment until the package is approved, then file the bugzilla entry, and replace the long explanation with the bug number. The bug should be marked as blocking one (or more) of the following bugs to simplify tracking such issues:

Noarch with Unported Dependencies

Sometimes, you are working on a noarch package that can only run in locations that a different, arched package builds on. This is common for packages written in a scripting language which depend on the language’s interpreter package, for instance. If the arched package that your package deps on isn’t available on all architectures Fedora (or EPEL) targets you run into a situation where you may need to exclude your package from certain architectures' package repositories or prevent it from building on certain architectures in the buildsystem.

Arch-Specific Runtime and Build-Time Dependencies

You can limit both the architectures used to build a noarch package, and the repositories to which the built noarch package will be added, by using either the ExcludeArch: or ExclusiveArch: tags:

BuildArch: noarch
# List the arches that the dependent package builds on below
ExclusiveArch: %{ix86} %{arm} x86_64 noarch

Sometimes a language runtime you are packaging for will provide a macro for the arches it’s available on, for instance, %{nodejs_arches}. If it does exist, then you can use something like ExclusiveArch: %{nodejs_arches} noarch in your spec file. Take a look at the guidelines for the language to see if such a macro exists.

No Arch-Specific Sources or Patches

Packages MUST NOT have Source: or Patch: tags which are conditionalized on architecture. For example, this is forbidden:

%ifarch ppc64
Patch0: build-fix-for-ppc64.patch
%endif

Conditionalizing Source: or Patch: tags by architecture causes the contents of the source package to differ depending on the architecture which was used to build it.

Note that this unfortunately prevents %autosetup from being used to apply patches when some of those patches apply only to certain architectures. The best solution is to write patches which simply work on all architectures. If that is not possible, then simply use %autosetup -N and to use the %patch macro to apply each patch using %ifarch or %ifnarch as appropriate. For example:

%prep
%autosetup -N
%ifarch s390x
%patch 0 -p1
%endif

Filesystem Layout

Fedora follows the Filesystem Hierarchy Standard with regards to filesystem layout, with exceptions noted below. The FHS defines where files should be placed on the system.

Exceptions

  • Fedora allows cross-compilers to place files in /usr/target.

  • Fedora does not allow new directories directly under / or /usr without FPC approval.

Libexecdir

The Filesystem Hierarchy Standard does not include any provision for libexecdir, but Fedora packages MAY store appropriate files there. Libexecdir (aka, /usr/libexec on Fedora systems) should only be used as the directory for executable programs that are designed primarily to be run by other programs rather than by users.

Fedora’s rpm includes a macro for libexecdir, %{_libexecdir}. Packagers are highly encouraged to store libexecdir files in a package-specific subdirectory of %{_libexecdir}, such as %{_libexecdir}/%{name}.

If upstream’s build scripts support the use of %{_libexecdir} then that is the most appropriate place to configure it (e.g., passing --libexecdir=%{_libexecdir}/%{name} to autotools configure). If upstream’s build scripts do not support that, %{_libdir}/%{name} is a valid second choice. If you have to patch support for using one of these directories in, then you should patch in LIBEXECDIR, preferably configurable at build time (so distributions that do not have /usr/libexec can set LIBEXECDIR to another directory more appropriate for their distro).

Multilib Exempt Locations

If a package is exempt from multilib, it may use %{_prefix}/lib instead of %{_libdir}. Packages that contain architecture specific files that would ordinarily be installed into %{_libexecdir} are always considered ineligible for multilib. However, you should be sure that the (sub)package that they are in does not have other content that would be considered eligible for multilib. If this is not the case for the files you wish to do this in for your package or you are just unsure, ask FESCo for an explicit multilib exemption.

/run

System services should store small volatile run-time data in /run. This is a tmpfs backed directory that is mounted in very early boot, before any services are started (and before /var is available). /var/run is a legacy symlink to /run.

No Files or Directories Under /srv, /usr/local, or /home/$USER

The FHS says:

"...no program should rely on a specific subdirectory structure of /srv existing
or data necessarily being stored in /srv. However /srv should always exist on FHS
compliant systems and should be used as the default location for such data.

Distributions must take care not to remove locally placed files in these
directories without administrator permission."

The FHS is explicitly handing control of the directory structure under /srv to the system administrator rather than the distribution. Therefore, no Fedora packages can have any files or directories under /srv, come preconfigured to use specific files or directories under /srv, to remove files there, or to modify the files there in any way.

In addition, no Fedora package can contain files or directories or modify files under:

  • /usr/local as these directories are not permitted to be used by Distributions in the FHS

  • /home/$USER as users can arbitrarily modify the files in their home directories and rpm packages that modify those files run the risk of destroying user data. Additionally, sites may be nfs mounting /home on many different types of systems or even network automounting them on demand. Modifying files in home directories that are thus configured will have negative effects in both of these situations.

It is important to note that the software in a Fedora package, once installed and configured by a user, can use /srv as a location for data. The package simply must not do this out of the box

Limited Usage of /opt, /etc/opt,