|
|
(166 intermediate revisions by 6 users not shown) |
Line 1: |
Line 1: |
| <!-- page was renamed from PackagingGuidelines
| | {{DISPLAYTITLE:Fedora Packaging Guidelines}} |
| -->
| |
| = Packaging Guidelines =
| |
|
| |
|
| It is the 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.) 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.
| | {{admon/warning |The packaging guidelines have been moved out of the wiki. The current version of this document is located at https://docs.fedoraproject.org/en-US/packaging-guidelines/ . Please update your bookmarks.}} |
| | |
| Please remember that any package that you submit must also conform to the [[Packaging:ReviewGuidelines| Review Guidelines]] .
| |
| | |
| '''Author:''' [[TomCallaway| Tom 'spot' Callaway]] (based on many other documents)<BR>
| |
| '''Revision:''' 1.03<BR>
| |
| '''Initial Draft:''' Wednesday Feb 23, 2005<BR>
| |
| '''Last Revised:''' Thursday Apr 12, 2012<BR>
| |
| | |
| {{Anchor|Naming}} | |
| == Naming ==
| |
| | |
| You should go through the [[Packaging:NamingGuidelines]] 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: [[Packaging:NamingGuidelines#Package_Versioning]]
| |
| | |
| {{Anchor|Legal}}
| |
| | |
| == Legal ==
| |
| | |
| There are various legal concerns to consider when packaging for Fedora.
| |
| | |
| {{Anchor|LegalLicensing}}
| |
| === Licensing ===
| |
| | |
| You should review [[Licensing:Main]] and the [[Packaging:LicensingGuidelines]] to ensure that your package is licensed appropriately.
| |
| | |
| | |
| {{Anchor|CodeVsContent}}
| |
| === Code Vs Content ===
| |
| It is important to make distinction between computer executable code and content.
| |
| While code is permitted (assuming, of course, that it has an open source compatible license, is not legally questionable, etc.), only some kinds of content are permissable.
| |
| | |
| The rule is this:
| |
| | |
| If the content enhances the OS user experience, then the content is OK to be packaged in Fedora. This means, for example, that things like: fonts, themes, clipart, and wallpaper are OK.
| |
| | |
| Content still has to be reviewed for inclusion. It must have an open source compatible license, must not be legally questionable. In addition, there are several additional restrictions for content:
| |
| * Content must not be pornographic, or contain nudity, whether animated, simulated, or photographed. There are better places on the Internet to get porn.
| |
| * Content should not be offensive, discriminatory, or derogatory. If you're not sure if a piece of content is one of these things, it probably is.
| |
| * All content is subject to review by FESCo, who has the final say on whether or not it can be included.
| |
| | |
| Some examples of content which is permissable:
| |
| | |
| * Package documentation or help files
| |
| * Clipart for use in office suites
| |
| * Background images (non-offensive, discriminatory, with permission to freely redistribute)
| |
| * Fonts (under an open source license, with no ownership/legal concerns)
| |
| * Game levels are not considered content, since games without levels would be non functional.
| |
| * Sound or graphics included with the source tarball that the program or theme uses (or the documentation uses) are acceptable.
| |
| * Game music or audio content is permissible, as long as the content is freely distributable without restriction, and the format is not patent encumbered.
| |
| * Example files included with the source tarball are not considered content.
| |
| | |
| Some examples of content which are not permissable:
| |
| | |
| * Comic book art files
| |
| * Religious texts
| |
| * mp3 files (patent encumbered)
| |
| | |
| If you are unsure if something is considered approved content, ask on fedora-devel-list.
| |
| | |
| {{Anchor|External Bits}}
| |
| === Packages which are not useful without external bits ===
| |
| | |
| Some software is not functional or useful without the presence of external code dependencies in the runtime operating system environment. When those external code dependencies are non-free, legally unacceptable, or binary-only (with the exception of permissible firmware), then the dependent software is not acceptable for inclusion in Fedora. If the code dependencies are acceptable for Fedora, then they should be packaged and included in Fedora as a pre-requisite for inclusion of the dependent software. Software which downloads code bundles from the internet in order to be functional or useful is not acceptable for inclusion in Fedora (regardless of whether the downloaded code would be acceptable to be packaged in Fedora as a proper dependency).
| |
| | |
| This also means that packages which are not functional or useful without code or packages from third-party sources are not acceptable for inclusion in Fedora.
| |
| | |
| {{Anchor|SourceRequirement}}
| |
| | |
| == No External Kernel Modules ==
| |
| {{:Packaging:KernelModules}}
| |
| | |
| == No inclusion of pre-built binaries or libraries ==
| |
| | |
| All program binaries and program libraries included in Fedora packages must be built from the source code that is included in the source package. This is a requirement for the following reasons:
| |
| * Security: Pre-packaged program binaries and program libraries not built from the source code could contain parts that are malicious, dangerous, or just broken. Also, these are functionally impossible to patch.
| |
| * Compiler Flags: Pre-packaged program binaries and program libraries not built from the source code were probably not compiled with standard Fedora compiler flags for security and optimization.
| |
| | |
| Content binaries (such as .pdf, .png, .ps files) are ''not'' required to be rebuilt from the source code.
| |
| | |
| If you are in doubt as to whether something is considered a program binary or a program library, here is some helpful criteria:
| |
| * Is it executable? If so, it is probably a program binary.
| |
| * Does it contain a .so, ,so.#, or .so.#.#.# extension? If so, it is probably a program library.
| |
| * If in doubt, ask your reviewer. If the reviewer is not sure, they should ask the Fedora Packaging Committee.
| |
| | |
| Packages which require non-open source components to build are also not permitted (e.g. proprietary compiler required).
| |
| | |
| When you encounter prebuilt binaries in a package you '''MUST''':
| |
| | |
| * Remove all pre-built program binaries and program libraries in %prep prior to the building of the package. Examples include, but are not limited to, *.class, *.dll, *.DS_Store, *.exe, *.jar, *.o, *.pyc, *.pyo, *.egg, *.so, *.swf files.
| |
| * Ask upstream to remove the binaries in their next release.
| |
| | |
| {{Anchor|SourceRequirementExceptions}}
| |
| === Exceptions ===
| |
| | |
| * Some software (usually related to compilers or cross-compiler environments) cannot be built without the use of a previous toolchain or development environment (open source). If you have a package which meets this criteria, contact the Fedora Packaging Committee for approval. Please note that this exception, if granted, is limited to only the initial build of the package. You may bootstrap this build with a "bootstrap" pre-built binary, but after this is complete, you must immediately increment Release, drop the "bootstrap" pre-built binary, and build completely from source. Bootstrapped packages containing pre-built "bootstrap" binaries must not be pushed as release packages or updates under any circumstances. These packages should contain the necessary logic to be built once bootstrapping is completed and the prebuilt programs are no longer needed. Information about how you should break circular dependencies by bootstrapping can be found here: [[Packaging:Guidelines#Bootstrapping]]
| |
| * An exception is made for binary firmware, as long as it meets the requirements documented here: [[Licensing:Main#Binary_Firmware]]
| |
| * Some pre-packaged program binaries or program libraries may be under terms which do not permit redistribution, or be affected by legal scenarios such as patents. In such situations, simply deleting these files in %prep is not sufficient, the maintainer will need to make a modified source that does not contain these files. See: [[Packaging:SourceURL#When_Upstream_uses_Prohibited_Code]]
| |
| | |
| {{Anchor|Spec Legibility}}
| |
| | |
| == Spec Legibility ==
| |
| All Fedora Package Spec Files must be legible. If the reviewer is unable to read the spec file, it will be impossible to perform a review. Fedora Spec files are not the place for entries into the [http://www.ioccc.org/ Obfuscated Code Contest].
| |
| | |
| {{Anchor|PackageFromScratch}}
| |
| == Writing a package from scratch ==
| |
| When writing a package from scratch, you should base your spec file on the Fedora spec file template (see [[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.
| |
| | |
| {{Anchor|ModifyingExistingPackage}}
| |
| == Modifying an existing package ==
| |
| If you base a package on an existing non-Fedora 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.
| |
| | |
| 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| Tags]] ),
| |
| *skim the summary and description for typos and oddities (see [[#summary| Summary and description]] ),
| |
| *make sure that the correct build root is used,
| |
| *ensure that macro usage is consistent (see [[#macros| Macros]] ).
| |
| | |
| Keep old changelog 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 changelog from scratch. In other words, use your best judgement.
| |
| | |
| {{Anchor|ArchitectureSupport}}
| |
| == 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 [[Architectures#Primary_Architectures|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 <code>ExcludeArch</code>. Each architecture listed in <code>ExcludeArch</code> 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 <code>ExcludeArch</code> 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:
| |
| | |
| * [https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=FE-ExcludeArch-x86 FE-ExcludeArch-x86]
| |
| * [https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=FE-ExcludeArch-x64 FE-ExcludeArch-x64]
| |
| * [https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=F-ExcludeArch-arm F-ExcludeArch-arm]
| |
| * [https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=FE-ExcludeArch-ppc FE-ExcludeArch-ppc]
| |
| * [https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=FE-ExcludeArch-ppc64 FE-ExcludeArch-ppc64]
| |
| * [https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=F-ExcludeArch-s390x F-ExcludeArch-s390x]
| |
| | |
| === 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' yum repositories or prevent it from building on certain architectures in the buildsystem.
| |
| | |
| ==== Requires ====
| |
| | |
| When your package needs the problematic dependency at runtime but not at build time then you only need to keep it from entering the yum repositories for that architecture. There is a relatively simple workaround for this:
| |
| | |
| <pre>
| |
| BuildArch: noarch
| |
| # List the arches that the dependent package builds on below
| |
| ExclusiveArch: %{ix86} %{arm} x86_64 noarch
| |
| </pre>
| |
| | |
| Sometimes a language runtime you are packaging for will provide a macro for the arches it's available on, for instance, <code>%{nodejs_arches}</code>. If it does exist, then you can use something like <code>ExclusiveArch:%{nodejs_arches} noarch</code> in your spec file. Take a look at the Guidelines for the language to see if such a macro exists.
| |
| | |
| ==== BuildRequires ====
| |
| | |
| Building a noarch package that has a dependency that isn't available on all arches is much more difficult to handle. There is no way to specify architectures to exclude building on that koji will apply to a noarch package build. Koji attempts to use any available builder to build a noarch package.
| |
| | |
| In this case packagers '''MUST''' make their packages architecture specific. Koji will then be able to use the package's <code>ExclusiveArch:</code> tag to tell what architectures cannot be used to build:
| |
| | |
| <pre>
| |
| # Cannot build as noarch until foo-lang is ported to arm.
| |
| # Comment out BuildArch: noarch for now.
| |
| # BuildArch: noarch
| |
| ExclusiveArch: %{ix86} x86_64
| |
| </pre>
| |
| | |
| Packagers are sometimes tempted to continue to keep the package noarch and simply resubmit the package when it fails. However this is a very kludgey and manual method. A big drawback is that automated mass rebuilds will generate failed builds simply because the package hit a builder of the wrong architecture.
| |
| | |
| ==== Conditionalizing Builds for Architecture ====
| |
| Packages '''MUST NOT''' have <code>SourceN:</code> or <code>PatchN:</code> tags which are conditionalized on architecture. For instance:
| |
| | |
| <pre>
| |
| # Incorrect
| |
| %ifarch ppc64
| |
| Patch0: build-fix-for-ppc64.patch
| |
| %endif
| |
| </pre>
| |
| | |
| Conditionalizing Source and Patch tags by architecture makes it so the built SRPM may not contain everything needed to rebuild itself on a different architecture (If the example above was built into an SRPM on x86 then the SRPM would not contain Patch0. This would mean the SRPM would not contain all the files needed to be built on a ppc64 computer.)
| |
| | |
| The best strategy for things like this is to write code that can be built on any architecture (using conditionals in the code to handle incompatibilities between architectures if necessary). The second best strategy is to use spec file conditionals only when utilizing the value of a Source or Patch tag like this:
| |
| | |
| <pre>
| |
| %prep
| |
| [...]
| |
| %ifarch ppc64
| |
| %patch0 -p1
| |
| %endif
| |
| </pre>
| |
| | |
| {{Anchor|layout}}
| |
| | |
| == Filesystem Layout ==
| |
| | |
| Fedora follows the [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard (FHS)] with regards to filesystem layout. The FHS defines where files should be placed on the system. Fedora packages must follow the FHS. Any deviation from the FHS should be rationalized when the package is reviewed.
| |
| | |
| {{admon/note||Some interpretations of the FHS say that the FHS does not prevent distributions from creating and using directories outside of the listed hierarchies (for instance, adding new toplevel directories to <code>/</code> or adding new directories under <code>/usr</code>). For the purposes of the Fedora Packaging Guidelines, new directories of this sort are not allowed unless listed in the Guidelines. If you feel the need for a new directory, please contact the FPC with a rationale for the directory and what category of software belongs in that directory. You may need to read the FHS to tell if a directory is already part of an FHS approved hierarchy.}}
| |
| | |
| There are notable exceptions to this guideline for libexecdir (as specified in the [http://www.gnu.org/prep/standards/standards.html#index-libexecdir-139 GNU Coding Standards]), <code>/run</code> (which has been widely adopted by Linux distributions even though a new version of the FHS has not been released that includes it) and /usr/target for cross-compilers.
| |
| | |
| {{Anchor|libexecdir}}
| |
| === Libexecdir ===
| |
| | |
| The [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard] does not include any provision for libexecdir, but Fedora packages may store appropriate files there. Libexecdir (aka, <code>/usr/libexec</code> 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, <code>%{_libexecdir}</code>. Packagers are highly encouraged to store libexecdir files in a package-specific subdirectory of <code>%{_libexecdir}</code>, such as <code>%{_libexecdir}/%{name}</code>.
| |
| | |
| If upstream's build scripts support the use of <code>%{_libexecdir}</code> then that is the most appropriate place to configure it (eg. passing <code>--libexecdir=%{libexecdir}/%{name}</code> to autotools configure). If upstream's build scripts do not support that, <code>%{_libdir}/%{name}</code> 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 <code>/usr/libexec</code> can set LIBEXECDIR to another directory more appropriate for their distro.
| |
| | |
| === Multilib Exempt Locations ===
| |
| If a package is exempt from multilib, it may use <code>%{_prefix}/lib</code> instead of <code>%{_libdir}</code>. Packages that contain architecture specific files that would ordinarily be installed into <code>%{_libexecdir}</code> 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 may need to store run-time variable data somewhere before <code>/var/run</code> is mounted. Currently, many programs are abusing <code>/dev</code> for that purpose. A few distributions have figured out elaborate hacks to use <code>/var/run</code> even before <code>/var</code> itself is mounted to do this. These are seen as less than ideal, however. Several major distributions have committed to support using <code>/run</code> for this purpose instead.
| |
| | |
| For now, applications can use <code>/run</code> or <code>/var/run</code> almost interchangably. <code>/run</code> <b>MUST</b> be used when the application can be started during boot before <code>/var</code> may be mounted.
| |
| | |
| {{admon/note|| [[https://bugs.linuxfoundation.org/show_bug.cgi?id=718 | FHS ticket for /run]]}}
| |
| | |
| {{Anchor|rpmlint}}
| |
| | |
| === Binaries in /bin and /sbin ===
| |
| {{admon/note||This section is only relevant on versions of Fedora older than 17 and EPEL.}}
| |
| | |
| Binaries placed into /bin and /sbin must not depend upon libraries stored in /usr/lib (or /usr/lib64). Binaries which depend on libraries in /usr/lib* must live in either /usr/bin or /usr/sbin.
| |
| | |
| {{Anchor|NoFilesOrDirectoriesUnderSrv}}
| |
| === No Files or Directories under /srv, /usr/local, or /home/$USER ===
| |
| | |
| The [http://www.pathname.com/fhs/pub/fhs-2.3.html#SRVDATAFORSERVICESPROVIDEDBYSYSTEM FHS says] :
| |
| | |
| <pre>
| |
| "...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."
| |
| </pre>
| |
| | |
| The FHS is explicitly handing control of the directory structure under <code>/srv</code> to the system administrator rather than the distribution. Therefore, no Fedora packages can have any files or directories under <code>/srv</code>, come preconfigured to use specific files or directories under <code>/srv</code>, 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:
| |
| * <code>/usr/local</code> as these directories are not permitted to be used by Distributions in the FHS
| |
| * <code>/home/$USER</code> 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 <code>/home</code> 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 <code>/srv</code> as a location for data. The package simply must not do this out of the box
| |
| | |
| === Limited usage of /opt, /etc/opt, and /var/opt ===
| |
| | |
| <code>/opt</code> and its related directories (<code>/etc/opt</code> and <code>/var/opt</code>) is reserved for the use of vendors in the FHS. We have reserved the <code>fedora</code> name with [http://www.lanana.org/lsbreg/providers/providers.txt LANANA] for our use. If a package installs files into <code>/opt</code> it may only use directories in the <code>/opt/fedora</code> hierarchy. Fedora attempts to organize this directory by allocating a subdirectory of our <code>/opt/fedora</code> directory for specific subsystems. If you think you need to use <code>/opt/fedora</code> please file an FPC ticket to decide whether it's a valid use of <code>/opt</code> and what subdirectory should be allocated for your use.
| |
| | |
| Currently, we have allocated <code>/opt/fedora/scls</code>, <code>/etc/opt/fedora/scls</code>, and <code>/var/opt/fedora/scls</code> for use by [[User:Toshio/SCL_Guidelines_(draft)| Software Collections]].
| |
| | |
| === Effect of the UsrMove Fedora Feature ===
| |
| | |
| Fedora has merged several directories in <code>/</code> with their counterparts in <code>/usr/</code>.
| |
| | |
| <table>
| |
| <tr><td>
| |
| /bin
| |
| </td><td>/usr/bin aka %{_bindir}
| |
| </td></tr>
| |
| <tr><td>
| |
| /sbin
| |
| </td><td>
| |
| /usr/sbin aka %{_sbindir}
| |
| </td></tr>
| |
| <tr><td>
| |
| /lib64 or /lib
| |
| </td><td>
| |
| /usr/lib64 or /usr/lib aka %{_libdir}
| |
| </td></tr>
| |
| <tr><td>
| |
| /lib
| |
| </td><td>
| |
| /usr/lib aka %{_prefix}/lib
| |
| </td></tr>
| |
| </table>
| |
| | |
| For example, end users will find that <code>/bin/sh</code> is the same file as <code>/usr/bin/sh</code>.
| |
| | |
| However, rpm file dependencies don't work according to what's on the filesystem, they work according to the path specified in the rpm <code>%files</code> section. So an rpm which specified:
| |
| | |
| <pre>
| |
| %files
| |
| /bin/sh
| |
| </pre>
| |
| | |
| would be able to satisfy a file dependency for <code>/bin/sh</code> but not for <code>/usr/bin/sh</code>. As a packager you may need to pay attention to where other packages expect to find your files. Things that history has placed into <code>/bin</code>, <code>/sbin</code>, <code>/lib</code>, or <code>/lib64</code> should be listed in the <code>%files</code> section as being in those directories. Things that history placed in <code>/usr/bin</code>, <code>/usr/sbin</code>, etc, should be listed in the <code>%files</code> section as being in <code>%{_bindir}</code>, <code>%{_sbindir}</code>, etc. If you feel that there is some historical confusion as to which directory a program is placed in, you can use a Virtual Provides to list the alternate path. For instance:
| |
| | |
| <pre>
| |
| Provides: %{_sbindir}/ifconfig
| |
| [...]
| |
| %files
| |
| /sbin/ifconfig
| |
| </pre>
| |
| | |
| If you are a packager who uses file dependencies to Require the proper dependencies then you may need to make sure that the file dependencies are pointing to the location that the packager of that file specified to rpm. Here's an example of doing this:
| |
| | |
| <pre>
| |
| $ rpm -ql $(rpm -qf /usr/sbin/ifconfig)|grep sbin/ifconfig
| |
| /sbin/ifconfig
| |
| </pre>
| |
| | |
| So you'd want to use <code>Requires: /sbin/ifconfig</code> in your spec file.
| |
| | |
| == Use rpmlint ==
| |
| Run rpmlint on binary and source rpms to examine them for common errors, and fix them (unless rpmlint is wrong, which can happen, too). If you find rpmlint's output cryptic, the <code>-i</code> switch to it can be used to get more verbose descriptions of most errors and warnings. Note that rpmlint will perform additional checks if given the name of an installed package. For example, <code>yum install foo-1.0-1.f20.x86_64.rpm; rpmlint foo</code> will perform a set of tests on the foo package that <code>rpmlint foo-1.0-1.f20.x86_64.rpm</code> cannot. The rpmlint package is available in the Fedora repositories.
| |
| | |
| === Rpmlint Errors ===
| |
| | |
| Rpmlint has the ability to make a lot of noise when it is run, even on perfectly valid packages. This section exists to help you decipher the messages, so that you can make fixes as necessary.
| |
| | |
| * <code>E: foo-package no-packager-tag</code>: This error occurs because no <code>Packager:</code> value is defined in the spec file. In Fedora, we do not use the <code>Packager</code> tag, so you can ignore this error.
| |
| * <code>E: foo-package no-signature</code>: This error occurs because your package is not signed. Since Fedora doesn't store SRPMS in CVS (only the files inside them), you do not need to sign your package, and you can ignore this error.
| |
| * <code>W: foo-package summary-ended-with-dot Summary of my package.</code>: This error occurs because the entry in your spec for <code>Summary:</code> ended with a period. Just get rid of the period at the end of the line.
| |
| * <code>E: foo-package wrong-script-end-of-line-encoding /path/to/somefile</code>: This error occurs because of DOS line breaks in a file. Fix it in the %prep section with sed: <code>sed -i 's/\r//' src/somefile</code> or <code>dos2unix</code>.
| |
| | |
| * <code>E: foo-package invalid-lc-messages-dir /usr/share/locale/xx_XX/LC_MESSAGES/foo.mo</code>: This error is a common false positive and usually should be ignored.
| |
| | |
| {{Anchor|Changelogs}}
| |
| | |
| == Changelogs ==
| |
| ''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.
| |
| | |
| <pre>
| |
| * Wed Jun 14 2003 Joe Packager <joe at gmail.com> - 1.0-2
| |
| - Added README file (#42).
| |
| </pre>
| |
| | |
| You must use one of the following formats:
| |
| <pre>
| |
| * Fri Jun 23 2006 Jesse Keating <jkeating@redhat.com> - 0.6-4
| |
| - And fix the link syntax.
| |
| </pre>
| |
| | |
| <pre>
| |
| * Fri Jun 23 2006 Jesse Keating <jkeating@redhat.com> 0.6-4
| |
| - And fix the link syntax.
| |
| </pre>
| |
| | |
| <pre>
| |
| * Fri Jun 23 2006 Jesse Keating <jkeating@redhat.com>
| |
| - 0.6-4
| |
| - And fix the link syntax.
| |
| </pre>
| |
| | |
| Changelog entries should provide a brief summary of the changes done to the package between releases, including noting updating to a new version, adding a patch, fixing other spec sections, note bugs fixed, and CVE's if any. They must never simply contain an entire copy of the source CHANGELOG entries. The intent is to give the user a hint as to what changed in a package update without overwhelming them with the technical details. Links to upstream changelogs can be entered for those who want additional information.
| |
| If you wish to "scramble" or "obfuscate" your email address in the changelog, you may do so, provided that it is still understandable by humans.
| |
| | |
| === Multiple Changelog Entries per Release ===
| |
| In some situations, it may be useful for packagers to have multiple changelog entries in the spec file, but not increment the release field for each one. There are two supported methods for doing this:
| |
| | |
| ==== Updating and replacing the existing date line ====
| |
| | |
| In this situation, you have added this changelog entry, but have not built the package yet:
| |
| | |
| <pre>
| |
| * Nov 12 2010 Toshio Kuratomi <toshio_fedoraproject.org> - 1.0-1
| |
| - Fix spelling errors in package description
| |
| </pre>
| |
| | |
| The next day, you make additional changes to the spec, and need to add a new changelog line, then you would update the existing date line for 1.0-1, and append any new notes, making the changelog look like this:
| |
| | |
| <pre>
| |
| * Nov 13 2010 Toshio Kuratomi <toshio_fedoraproject.org> - 1.0-1
| |
| - Fix spelling errors in package description
| |
| - Add a patch to fix compilation problems on F15
| |
| </pre>
| |
| | |
| Please remember that this is only acceptable if 1.0-1 has not yet been built.
| |
| | |
| You can do this any number of times, until you actually build 1.0-1 in the buildsystem. At that point, you must go back to adding new entries as described in [[Packaging:Guidelines#Changelogs|Changelogs]].
| |
| | |
| | |
| ==== Repeat the old version release with a new entry ====
| |
| | |
| In this situation, you have added this changelog entry, but have not built the package yet:
| |
| | |
| <pre>
| |
| * Nov 12 2010 Toshio Kuratomi <toshio_fedoraproject.org> - 1.0-1
| |
| - Fix spelling errors in package description
| |
| </pre>
| |
| | |
| The next day, you make additional changes to the spec, and need to add a new changelog line. Now, you can add an additional changelog item with the new date, but the same Version-Release, so your new changelog looks like this:
| |
| | |
| <pre>
| |
| * Nov 13 2010 Toshio Kuratomi <toshio_fedoraproject.org> - 1.0-1
| |
| - Add a patch to fix compilation problems on F15
| |
| | |
| * Nov 12 2010 Toshio Kuratomi <toshio_fedoraproject.org> - 1.0-1
| |
| - Fix spelling errors in package description
| |
| </pre>
| |
| | |
| Please remember that this is only acceptable if 1.0-1 has not yet been built.
| |
| | |
| You can do this any number of times, until you actually build 1.0-1 in the buildsystem. At that point, you must go back to adding new entries as described in [[Packaging:Guidelines#Changelogs|Changelogs]].
| |
| | |
| {{Anchor|tags}}
| |
| | |
| == Tags ==
| |
| *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 [http://www.rpm.org/max-rpm/s1-rpm-inside-tags.html#S3-RPM-INSIDE-PACKAGER-TAG www.rpm.org] . If you need to include information about the packager in the rpms ''you'' built, use <code>%packager</code> in your <code>~/.rpmmacros</code> 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, as detailed in [[Packaging:LicensingGuidelines]] . Contact the upstream author if there is any doubt about what license the software is distributed under.
| |
| *The ''Summary'' tag value should not end in a period. If this bothers you from a grammatical point of view, sit down, take a deep breath, and get over it.
| |
| *Usually, the ''Pre<code></code>Req'' tag should be replaced by plain ''Requires''. For more info, see Maximum RPM snapshot's [http://www.rpm.org/max-rpm-snapshot/s1-rpm-depend-manual-dependencies.html#S3-RPM-DEPEND-FINE-GRAINED fine grained dependencies chapter] .
| |
| * The ''Source'' tag documents where to find the upstream sources for the rpm. In most cases this should be a complete URL to the upstream tarball. For special cases, please see the [[Packaging:SourceURL]] Guidelines
| |
| | |
| {{Anchor|BuildRoot}}
| |
| | |
| == BuildRoot tag ==
| |
| | |
| Fedora (as of F-10) does not require the presence of the BuildRoot tag in the spec and if one is defined it will be ignored. The provided buildroot will automatically be cleaned before commands in %install are called.
| |
| | |
| {{admon/note|EPEL difference|rpm in EPEL5 and below require the BuildRoot tag and it must be manually cleaned in %install; follow the [[EPEL/GuidelinesAndPolicies#Distribution_specific_guidelines|EPEL Guidelines]].}}
| |
| | |
| | |
| == Group tag ==
| |
| | |
| All current versions of Fedora (and their respective RPM versions) treat the Group tag as optional. Packages may include a Group: field for compatibility with EPEL, but are not required to do so.
| |
| | |
| | |
| {{Anchor|Clean}}
| |
| | |
| == %clean ==
| |
| The %clean section is not required for F-13 and above. Each package for F-12 and below (or EPEL 5) MUST have a %clean section, which contains <code>rm -rf %{buildroot}</code> ([[Packaging:Guidelines#UsingBuildRootOptFlags|or $RPM_BUILD_ROOT]]).<BR>
| |
| | |
| {{Anchor|Requires}}
| |
| | |
| == Requires ==
| |
| RPM has very good capabilities of automatically finding dependencies for libraries and eg. Perl modules. In short, don't reinvent the wheel, but just let rpm do its job. There is usually no need to explicitly list eg. Requires: libX11 when the dependency has already been picked up by rpm in the form of depending on libraries in the libX11 package.
| |
| | |
| Build requirements are different. There's no automatic dependency find procedure for them, which means that you must explicitly list stuff that the package requires to build successfully. Typically, some -devel packages are listed there. Refer to the [[#BuildRequires| BuildRequires section]] .
| |
| | |
| Sometimes we know that a package requires eg. gtk+-devel 1.2 or newer to build (and thus gtk+ 1.2 or newer to run, but that's handled automatically). There are two things to consider here:
| |
| | |
| First, if the lowest possible requirement is so old that nobody has a version older than that installed on any target distribution release, there's no need to include the version in the dependency at all. In that case we know the available software is new enough. For example, the version in gtk+-devel 1.2 dependency above is unnecessary for all Red Hat Linux distributions since (at least) release 6.2. As a rule of thumb, if the version is not required, don't add it just for fun.
| |
| | |
| Second, the Epoch (if used) must be listed when adding a versioned dependency to achieve robust epoch-version-release comparison. See [[#Use_of_Epochs]] for details. A quick way to check the Epoch of package foo is to run:
| |
| | |
| rpm --query --qf "%{EPOCH}\n" packagename
| |
| | |
| Typically, the requirements for -devel packages need yet another look. They're not usually picked up automatically by rpm; and unless the generated RPMs will be noarch, -devel package dependencies on other -devel packages should be arch-specific.
| |
| | |
| A dependency is made arch-specific by appending the macro %{?_isa} to the package name. For example:
| |
| <pre>
| |
| Requires: foo
| |
| </pre>
| |
| becomes:
| |
| <pre>
| |
| Requires: foo%{?_isa}
| |
| </pre>
| |
| | |
| If the foo-devel package has a foo-config script, you can try doing a foo-config --libs and foo-config --cflags to get strong hints what packages should be marked as foo's requirements. For example:
| |
| | |
| <pre>
| |
| $ gtk-config --cflags
| |
| -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include
| |
| $ gtk-config --libs
| |
| -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
| |
| </pre>
| |
| | |
| This means that gtk+-devel should contain
| |
| | |
| Requires: glib-devel%{?_isa} libXi-devel%{?_isa} libXext-devel%{?_isa} libX11-devel%{?_isa}
| |
| | |
| {{Anchor|PreReq}}
| |
| === PreReq ===
| |
| | |
| Packages should not use the PreReq tag. Once upon a time, in dependency loops PreReq used to "win" over the conventional Requires when RPM determined the installation order in a transaction. This is no longer the case.
| |
| | |
| {{Anchor|FileDeps}}
| |
| === File Dependencies ===
| |
| | |
| Rpm gives you the ability to depend on files instead of packages. Whenever possible you should avoid file dependencies outside of /etc, /bin, /sbin, /usr/bin, or /usr/sbin. Using file dependencies outside of those directories requires yum (and other depsolvers using the repomd format) to download and parse a large xml file looking for the dependency. Helping the depsolvers avoid this processing by depending on the package instead of the file saves our end users a lot of time. There are times when other technical considerations outweigh these considerations. One specific example is packages installing into %{_libdir}/mozilla/plugins. In this case, mandating a specific browser in your package just to own this directory could drag in a large amount of needless packages. Requiring the directory to resolve the dependency is the better choice.
| |
| | |
| {{Anchor|ExplicitRequires}}
| |
| === Explicit Requires ===
| |
| Explicit Requires are Requires added manually by the packager in the spec file. Packages must not contain unnecessary explicit Requires on libraries. We generally rely on rpmbuild to automatically add dependencies on library SONAMEs. Modern package management tools are capable of resolving such dependencies to determine the required packages in many cases. However, present versions of rpmbuild only add deps on library SONAMES, not the library's full version. This can be a problem if a library has added features over the course of time without backwards incompatibilities that would cause SONAMES to be changed. This can lead to a case where the user has an old version of a library installed, the new version of the library with new ABI is built in Fedora and an application using that ABI is built. If the user just attempts to install or update that one application without also updating the library, the application will install fine (because the SONAME dependency is satisfied) but will fail when run because the library installed on the system is missing features it needs.
| |
| | |
| Although you do need to add explicit library dependencies to keep this from occurring, there are drawbacks to manually specifying this in all your packages. History has shown that such dependencies add confusion when library/files are moved from one package to another, when packages get renamed, when one out of multiple alternative packages would suffice, and when versioned explicit dependencies become out-of-date and inaccurate. Additionally, in some cases, old explicit dependencies on package names require unnecessary updates/rebuilds. For example, Fedora packages are only required to retain historical provides for two full release cycles.
| |
| | |
| Because of this and because we hope to have this fixed in rpmbuild, this is something to be aware of but it's not required that you explicitly specify the libraries you require with their version information.
| |
| | |
| When explicit library Requires are necessary, explicit library dependencies should typically be arch-specific (unless the packages involved are noarch) and there should be a spec file comment justifying it:
| |
| | |
| <pre>
| |
| # The automatic dependency on libfubar.so.1 is insufficient,
| |
| # as we strictly need at least the release that fixes two segfaults.
| |
| Requires: libfubar%{?_isa} >= 0:1.2.3-7
| |
| </pre>
| |
| | |
| Packagers should revisit an explicit dependency as appropriate to avoid it becoming inaccurate and superfluous. For instance in the example above, when no current Fedora release shipped with libfubar < 1.2.3-7, it is no longer necessary to list the explicit, versioned requirement.
| |
| | |
| === Filtering Auto-Generated Requires ===
| |
| RPM attempts to auto-generate Requires (and Provides) at build time, but in some situations, the auto-generated Requires/Provides are not correct or not wanted. For more details on how to filter out auto-generated Requires or Provides, please see: [[Packaging:AutoProvidesAndRequiresFiltering]]
| |
| | |
| {{Anchor|BuildRequires}}
| |
| | |
| == BuildRequires ==
| |
| | |
| In package development and testing, please verify that your package is not missing any necessary build dependencies. Having proper build requirements saves the time of all developers and testers as well as autobuild systems because they will not need to search for missing build requirements manually. It is also a safety feature that prevents builds with that would not otherwise fail, but would be missing crucial features. For example, a graphical application may exclude PNG support after its '''configure''' script detects that libpng is not installed.
| |
| | |
| Before adding Build<code></code>Requires to any package, please be comfortable with [[#Requires| Requires]] .
| |
| | |
| There are two suggested ways of detecting missing Build<code></code>Requires. '''rpmdev-rmdevelrpms''' and '''mock'''. The first one is designed to remove all developer-related packages from your system. If the build fails or is missing certain features due to missing build dependencies, then the missing dependency needs to be found and added. Check the [[#rmdevelrpms| rpmdev-rmdevelrpms]] section to find out more. <BR>
| |
| '''mock''' is another good way to check build dependencies. Rather than remove all developer packages, it tries to build your package in a chroot. It makes no changes to your normal, daily environment and ensures that your package will build fine. However, '''mock''' may need a good internet connection to download all required packages. [[Extras/MockTricks| MockTricks]] page contains more information. Another mock-like tool, '''mach''' is also available in the Fedora repository.
| |
| | |
| {{Anchor|rmdevelrpms}}
| |
| === rpmdev-rmdevelrpms ===
| |
| | |
| '''rpmdev-rmdevelrpms''' script within the [[rpmdevtools]] toolkit is a script written by Ville Skyttä that helps RPM packagers in finding missing Build<code></code>Requires. Simply run it and allow it to remove all *-devel packages and build tools like this example.
| |
| | |
| <pre>
| |
| [root@build-fc1 /] # rpmdev-rmdevelrpms
| |
| Found 52 devel packages:
| |
| guile-devel-1.6.4-8.2
| |
| bison-1.875-5
| |
| m4-1.4.1-14
| |
| flex-2.5.4a-30
| |
| openssl-devel-0.9.7a-23
| |
| automake-1.7.8-1
| |
| fontconfig-devel-2.2.1-6.1
| |
| XFree86-devel-4.3.0-42
| |
| tcl-devel-8.3.5-93
| |
| SDL_image-devel-1.2.3-3
| |
| SDL_ttf-devel-2.0.6-0.fdr.3.1
| |
| pth-devel-2.0.0-0.fdr.1.1
| |
| libIDL-devel-0.8.2-1
| |
| atk-devel-1.4.0-1
| |
| gtk2-devel-2.2.4-5.1
| |
| libmng-devel-1.0.4-4
| |
| glib-devel-1.2.10-11
| |
| gtk+-devel-1.2.10-28.1
| |
| audiofile-devel-0.2.3-7
| |
| compface-1.4-0.fdr.3.1
| |
| esound-devel-0.2.31-1
| |
| libungif-devel-4.1.0-16
| |
| gnome-libs-devel-1.4.1.2.90-35
| |
| openldap-devel-2.1.22-8
| |
| aspell-devel-0.50.3-16
| |
| gpgme03-devel-0.3.16-0.fdr.2.1
| |
| freeglut-devel-1.3-1.20020125.3
| |
| e2fsprogs-devel-1.34-1
| |
| db4-devel-4.1.25-14
| |
| krb5-devel-1.3.1-6
| |
| autoconf-2.57-3
| |
| libtool-1.5-8
| |
| gdbm-devel-1.8.0-21
| |
| freetype-devel-2.1.4-5
| |
| pkgconfig-0.14.0-6
| |
| ncurses-devel-5.3-9
| |
| tk-devel-8.3.5-93
| |
| SDL-devel-1.2.5-9
| |
| SDL_mixer-devel-1.2.4-9
| |
| zlib-devel-1.2.0.7-2
| |
| libgpg-error-devel-0.6-0.fr.3.1
| |
| glib2-devel-2.2.3-1.1
| |
| pango-devel-1.2.5-1.1
| |
| libjpeg-devel-6b-29
| |
| libpng-devel-1.2.2-17
| |
| ORBit-devel-0.5.17-10.3
| |
| clamav-devel-0.65-0.fdr.4.1
| |
| cyrus-sasl-devel-2.1.15-6
| |
| libtiff-devel-3.5.7-14
| |
| imlib-devel-1.9.13-14
| |
| gdk-pixbuf-devel-0.22.0-3.0
| |
| pilot-link-devel-0.11.8-1
| |
| Remove them? [y/N] y[
| |
| ]Removing.................................................................................................
| |
| ................................................................Done.
| |
| </pre>
| |
| Then attempt to build your RPM package. Use yum to reinstall any packages that are already in Build<code></code>Requires. If your build fails after this point, then you need to read through the build process and ascertain the missing Build<code></code>Requires from the error messages within.
| |
| | |
| Be very careful to watch especially the '''configure''' part of the build process for missing optional libraries or tools that are desirable for the package.
| |
| | |
| By default, the script may attempt to remove some packages that your system needs to operate correctly. Usually, this will fail due to an unsatisfied dependency (and this, BTW is why the script is using rpm -e instead of yum remove...)
| |
| | |
| An example of this are the gettext and libgcj packages. gettext is usually a development-only package, but for example redhat-lsb depends on it. Also, it seems that RH9 Konqueror needs openssl-devel for SSL. If you wish to mark some packages so that they will be ignored by rpmdev-rmdevelrpms, do it in /etc/rpmdevtools/rmdevelrpms.conf or your personal /.rmdevelrpmsrc and pay special attention to the packages you treated this way when building.
| |
| | |
| {{Anchor|Exceptions}}
| |
| === Exceptions ===
| |
| | |
| There is no need to include the following packages or their dependencies as Build<code></code>Requires because they would occur too often. These packages are considered the minimum build environment.
| |
| | |
| <pre>
| |
| bash
| |
| bzip2
| |
| coreutils
| |
| cpio
| |
| diffutils
| |
| fedora-release
| |
| findutils
| |
| gawk
| |
| gcc
| |
| gcc-c++
| |
| grep
| |
| gzip
| |
| info
| |
| make
| |
| patch
| |
| redhat-rpm-config
| |
| rpm-build
| |
| sed
| |
| shadow-utils
| |
| tar
| |
| unzip
| |
| util-linux
| |
| which
| |
| xz
| |
| </pre>
| |
| | |
| === BuildRequires and %{_isa} ===
| |
| | |
| You '''MUST NOT''' use arched BuildRequires. The arch ends up in the built SRPM but SRPMs need to be architecture independent. For instance, if you did this:
| |
| <pre>
| |
| # Example of what *not* to do
| |
| BuildRequires: python%{?_isa} >= 2.7
| |
| </pre>
| |
| | |
| Then the SRPM that is built in Fedora would have one of these Requirements depending on what builder the SRPM was created on:
| |
| | |
| <pre>
| |
| python(x86-32) >= 2.7
| |
| # or
| |
| python(x86-64) >= 2.7
| |
| </pre>
| |
| | |
| This would prevent yum-builddep or similar tools that use the SRPM's requirements from operating correctly.
| |
| | |
| {{Anchor|ConditionalDependencies}}
| |
| | |
| === BuildRequires based on pkg-config ===
| |
| | |
| Fedora packages which use <code>pkg-config</code> to build against a library (e.g. 'foo') on which they depend, '''SHOULD''' express their build dependency correctly as <code>pkgconfig(foo)</code>. For more information, see [[Packaging:PkgConfigBuildRequires]].
| |
| | |
| == Conditional dependencies ==
| |
| If the spec file contains conditional dependencies selected based on presence of optional <code>--with(out) foo</code> arguments to <code>rpmbuild</code>, build the source RPM to be submitted with the default options, ie. so that none of these arguments are present in the <code>rpmbuild</code> command line. The reason is that those requirements get "serialized" into the resulting source RPM, ie. the conditionals no longer apply.
| |
| | |
| {{Anchor|summary}}
| |
| == 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. Also, please make sure that there are no lines in the description longer than 80 characters.
| |
| | |
| Please put personal preferences aside and use American English spelling in the summary and description. Packages can contain additional translated summary/description for supported Non-English languages, if available.
| |
| | |
| === Trademarks in Summary or Description ===
| |
| Packagers should be careful how they use trademarks in Summary or Description. There are a few rules to follow:
| |
| * Never use "(TM)" or "(R)" (or the unicode equivalents, ™/®). It is incredibly complicated to use these properly, so it is actually safer for us to not use them at all.
| |
| * Use trademarks in a way that is not ambiguous. Avoid phrasing like "similar to" or "like". Some examples:
| |
| | |
| * '''BAD:''' It is similar to Adobe Photoshop.
| |
| * '''GOOD:''' It supports Adobe Photoshop PSD files, ...
| |
| | |
| * '''BAD:''' A Linux version of Microsoft Office
| |
| * '''GOOD:''' A word-processor with support for Microsoft Office DOC files
| |
| | |
| If you're not sure, ask yourself, is there any chance someone may get confused and think that this package is the trademarked item? When in doubt, try to leave the trademark out.
| |
| | |
| {{Anchor|PackageEncoding}}
| |
| | |
| == Encoding ==
| |
| Unless you need to use characters outside the [http://commons.wikimedia.org/wiki/Image:Ascii_full.png 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 [http://commons.wikimedia.org/wiki/Image:Ascii_full.png this chart] .
| |
| | |
| {{Anchor|FilenameEncoding}}
| |
| === 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.
| |
| | |
| {{Anchor|PackageDocumentation}}
| |
| == Documentation ==
| |
| Any relevant documentation included in the source distribution should be included in the package as %doc. 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 <code>*-doc</code> as the subpackage name, and <code>Documentation</code> as the value of the <code>Group</code> tag.
| |
| | |
| Files marked as documentation must not cause the package to pull in more dependencies than it would without the documentation. One simple way to ensure this is to remove all executable permissions from <code>%doc</code> files (<code>chmod -x</code>).
| |
| | |
| Also, if a package includes something as <code>%doc</code>, it must not affect the runtime of the packaged application(s). To summarize: If it is in <code>%doc</code>, the included programs must run properly if it is not present.
| |
| | |
| == Compiler ==
| |
| Fedora uses gcc as the compiler (for all languages that gcc supports). Packages may only build with an alternative compiler to gcc if upstream does not support gcc.
| |
| | |
| {{Anchor|CompilerFlags}}
| |
| == Compiler flags ==
| |
| Compilers used to build packages must honor the applicable compiler flags set in the system rpm configuration. Honoring means that the contents of that variable is used as the basis of the flags actually used by the compiler during the package build.
| |
| | |
| For C, C++, and Fortran code, the [[Packaging:RPMMacros#Build_flags_macros_and_variables| %{optflags} macro]] contains these flags.
| |
| Overriding these flags for performance optimizations (for instance, -O3 instead of -O2) is generally discouraged. If you can present benchmarks that show a
| |
| significant speedup for this particular code, this could be revisited on a case-by-case basis. Adding to and overriding or filtering parts of
| |
| these flags is permitted if there's a good reason to do so; the rationale for doing so must be documented in the specfile.
| |
| | |
| There are certain, security related flags that are commonly allowed. These flags may degrade performance slightly but the increased security can be worthwhile for some programs.
| |
| | |
| === PIE ===
| |
| | |
| PIE adds security to executables by composing them entirely of position-independent code. Position-independent code (PIC) is machine instruction code that executes properly regardless of where in memory it resides. PIE allows Exec Shield to use address space layout randomization to prevent attackers from knowing where existing executable code is during a security attack using exploits that rely on knowing the offset of the executable code in the binary, such as return-to-libc attacks.
| |
| | |
| To use this in your spec, add:
| |
| | |
| <pre>
| |
| %global _hardened_build 1
| |
| </pre>
| |
| | |
| This adds <code>-fPIC</code> (if <code>-fPIE</code> is not already present) to the compiler flags, and adds <code>-z now</code> to the linker flags.
| |
| | |
| If your package meets any of the following criteria you <b>MUST</b> enable the PIE compiler flags:
| |
| | |
| * Your package is long running. This means it's likely to be started and keep running until the machine is rebooted, not start on demand and quit on idle.
| |
| | |
| * Your package has suid binaries, or binaries with capabilities.
| |
| | |
| * Your package runs as root.
| |
| | |
| If your package meets the following criteria you <b>should consider</b> enabling the PIE compiler flags:
| |
| | |
| * Your package accepts/processes untrusted input.
| |
| | |
| FESCo maintains a [[Hardened_Packages|list of packages]] that <b>MUST</b> have PIE turned on. Other packages may enable the flags at the maintainer's discretion.
| |
| | |
| There are some notable disadvantages to enabling PIE that should be considered in making the decision:
| |
| | |
| * Some code does not compile with PIE (or does not function properly).
| |
| | |
| * You can not use prelink on PIE enabled binaries, resulting in a slower startup time.
| |
| | |
| {{Anchor|Debuginfo}}
| |
| | |
| == Debuginfo packages ==
| |
| Packages should produce useful <code>-debuginfo</code> packages, or explicitly disable them when it is not possible to generate a useful one but rpmbuild would do it anyway. Whenever a <code>-debuginfo</code> package is explicitly disabled, an explanation why it was done is required in the specfile. Debuginfo packages are discussed in more detail in a separate document, [[Packaging:Debuginfo]] .
| |
| | |
| {{Anchor|DevelPackages}}
| |
| == Devel Packages ==
| |
| | |
| Fedora packages must be designed with a logical separation of files. Specifically, -devel packages must be used to contain files which are intended solely for development or needed only at build-time. This is done to minimize the install footprint for users. There are some types of files which almost always belong in a -devel package:
| |
| | |
| * Header files (foo.h), usually found in /usr/include
| |
| * Static library files when the package does not provide any matching shared library files. See [[Packaging:Guidelines#Packaging_Static_Libraries]] for more information about this scenario.
| |
| * Unversioned shared system library files, when a matching versioned shared system library file is also present. For example, if your package contains:
| |
| <pre>
| |
| /usr/lib/libfoo.so.3.0.0
| |
| /usr/lib/libfoo.so.3
| |
| /usr/lib/libfoo.so
| |
| </pre>
| |
| | |
| The versioned shared library files (/usr/lib/libfoo.so.3.2.0 and /usr/lib/libfoo.so.3) are necessary for users to run programs linked against libfoo, so they belong in the base package. The other, unversioned, shared library file (/usr/lib/libfoo.so) is only used to actually link libfoo to code being compiled, and is not necessary to be installed on a users system. This means that it belongs in a -devel package. Please note that in most cases, only the fully versioned shared library file (/usr/lib/libfoo.so.3.2.0) is an actual file, all of the other files are symbolic links to it.
| |
| When a shared library file is only provided in an unversioned format, the packager should ask upstream to consider providing a properly versioned library file. However, in such cases, if the shared library file is necessary for users to run programs linked against it, it must go into the base package. If upstream versions the shared library file at a future point, packagers must be careful to move to the versioned layout described above.
| |
| | |
| As an additional complication, some software generates unversioned shared objects which are not intended to be used as system libraries. These files are usually plugins or modular functionality specific to an application, and are not located in the ld library paths or cache. This means that they are not located directly in /usr/lib or /usr/lib64, or in a directory listed as a library path in /etc/ld.so.conf (or an /etc/ld.so.conf.d/config file). Usually, these unversioned shared objects can be found in a dedicated subdirectory under /usr/lib or /usr/lib64 (e.g. /usr/lib/purple-2/ is the plugin directory used for libpurple applications). In these cases, the unversioned shared objects do not need to be placed in a -devel package.
| |
| | |
| There are some notable exceptions to this packaging model, specifically:
| |
| | |
| * compilers often include development files in the main package because compilers are themselves only used for software development, thus, a split package model does not make any sense.
| |
| | |
| When in doubt as to whether a file belongs in the base package or in -devel, packagers should consider whether the file is necessary to be present for a user to use or execute the functionality in the base package properly, or if it is only necessary for development. If it is only necessary for development, it must go into a -devel package.
| |
| | |
| As with all Fedora Packaging Guidelines, it is recognized that there are unique situations that fall outside of the boundaries of this model. Should you come across such a case, please open a ticket with the [https://fedorahosted.org/fpc/ Fedora Packaging Committee] and explain it to us so that we can extend the Guidelines to address it.
| |
| | |
| {{Anchor|PkgconfigFiles}}
| |
| === Pkgconfig Files (foo.pc) ===
| |
| | |
| The placement of pkgconfig(.pc) files depends on their usecase. Since they are almost always used for development purposes, they should be placed in a -devel package. A reasonable exception is when the main package itself is a development tool not installed in a user runtime, e.g. gcc or gdb.
| |
| | |
| {{Anchor|RequiringBasePackage}}
| |
| | |
| == Requiring Base Package ==
| |
| Subpackages are often extensions for their base package and in that case they should require their base package. It is almost always better to over specify the version, so it is best practice to just use a fully versioned dependency: Requires: %{name}%{?_isa} = %{version}-%{release}. Devel packages are an example of a package that must require their base packages using a fully versioned dependency. -libs subpackages which only contain shared libraries do not normally need to explicitly depend on %{name}%{?_isa} = %{version}-%{release}, as they usually do not need the base package to be functional libraries.
| |
| | |
| If you end up in a situation where the main package depends on the subpackage and the subpackage on the main package you should think carefully about why you don't have everything in the main package.
| |
| | |
| When a subpackage requires the base package, it must do so using a fully versioned arch-specific (for non-noarch packages) dependency:
| |
| <pre>
| |
| Requires: %{name}%{?_isa} = %{version}-%{release}
| |
| </pre>
| |
| | |
| {{Anchor|SharedLibraries}}
| |
| == Shared Libraries ==
| |
| Whenever possible (and feasible), Fedora Packages containing libraries should build them as shared libraries. In addition, every binary RPM package which contains shared library files (not just symlinks) in any of the dynamic linker's default paths, must call ldconfig in <code>%post</code> and <code>%postun</code>. If the package has multiple subpackages with libraries, each subpackage should also have a <code>%post/%postun</code> section that calls <code>/sbin/ldconfig</code>. An example of the correct syntax for this is:
| |
| <pre>
| |
| %post -p /sbin/ldconfig
| |
| | |
| %postun -p /sbin/ldconfig
| |
| </pre>
| |
| Note that this specific syntax only works if <code>/sbin/ldconfig</code> is the only call in <code>%post</code> and <code>%postun</code>. If you have additional commands to run during the scriptlet, call <code>/sbin/ldconfig</code> at the beginning of the scriptlet, like this:
| |
| <pre>
| |
| %post
| |
| /sbin/ldconfig
| |
| /usr/bin/foo --add
| |
| | |
| %postun
| |
| /sbin/ldconfig
| |
| /usr/bin/foo --remove
| |
| </pre>
| |
| | |
| {{Anchor|StaticLibraries}}
| |
| == Packaging Static Libraries ==
| |
| Packages including libraries should exclude static libs as far as possible (eg by configuring with ''--disable-static''). Static libraries should only be included in exceptional circumstances. Applications linking against libraries should as far as possible link against shared libraries not static versions.
| |
| | |
| Libtool archives, ''foo.la'' files, should not be included. Packages using libtool will install these by default even if you configure with ''--disable-static'', so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable release (not devel) and the package already contains *.la files, removing the *.la files should be treated as an API/ABI change -- ie: Removing them changes the interface that the library gives to the rest of the world and should not be undertaken lightly.
| |
| | |
| {{Anchor|StaticInclusion}}
| |
| === Packaging Static Libraries ===
| |
| * In general, packagers are strongly encouraged not to ship static libs unless a compelling reason exists.
| |
| | |
| * We want to be able to track which packages are using static libraries (so we can find which packages need to be rebuilt if a security flaw in a static library is fixed, for instance). There are two scenarios in which static libraries are packaged:
| |
| # '''Static libraries and shared libraries.''' In this case, the static libraries must be placed in a ''*-static'' subpackage. Separating the static libraries from the other development files in ''*-devel'' allow us to track this usage by checking which packages <code>BuildRequire</code> the ''*-static'' package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries.
| |
| # '''Static libraries only.''' When a package only provides static libraries you can place all the static library files in the ''*-devel'' subpackage. When doing this you also must have a virtual Provide for the ''*-static'' package:
| |
| <pre>%package devel
| |
| Provides: foo-static = %{version}-%{release}</pre>
| |
| | |
| Packages which explicitly need to link against the static version must <code>BuildRequire: foo-static</code>, so that the usage can be tracked.
| |
| | |
| * If (and only if) a package has shared libraries which require static libraries to be functional, the static libraries can be included in the ''*-devel'' subpackage. The devel subpackage must have a virtual Provide for the ''*-static'' package, and packages dependent on it must <code>BuildRequire</code> the ''*-static'' package.
| |
| | |
| {{Anchor|HeaderOnlyLibraries}}
| |
| === Packaging Header Only Libraries ===
| |
| | |
| Certain libraries, especially some C++ template libraries, are header only libraries. Since the code is generated during compile time, they act just like static libraries and need to be treated as such.
| |
| | |
| Place all of the header files in the ''*-devel'' subpackage and then you must have a virtual Provide for the ''*-static'' package:
| |
| <pre>%package devel
| |
| Provides: foo-static = %{version}-%{release}</pre>
| |
| | |
| Packages which use the header library must <code>BuildRequire: foo-static</code>, so that the usage can be tracked.
| |
| | |
| ==== Do not use noarch ====
| |
| | |
| It may be tempting to make the header library package noarch, since the header files themselves are simply text. However, a library should have tests which should be run on all architectures. Also, the install process may modify the installed headers depending on the build architecture. For these reasons, header-only packages must not be marked noarch.
| |
| | |
| {{Anchor|StaticLinkage}}
| |
| | |
| === Statically Linking Executables ===
| |
| * Static linkage is a special exception and should be decided on a case-by-case basis. The packager must provide rationale for linking statically, including precedences where available, to FESCO for approval.
| |
| * If you link statically against a library, add yourself to the initialcc list for the library so you can watch for any security issues or bug fixes for which you'd want to rebuild your package against a new version of the library. Here are [[PackageMaintainers/CVSAdminProcedure| instructions]] for making that request.
| |
| | |
| ==== Programs which don't need to notify FESCo ====
| |
| * Programs written in OCaml do not normally link dynamically to OCaml libraries. Because of that this requirement is waived. (OCaml code that calls out to libraries written in C should still link dynamically to the C libraries, however.)
| |
| | |
| * If a library you depend on '''only''' provides a static version your package can link against it provided that you <code>BuildRequire</code> the ''*-static'' subpackage. Packagers in such a situation should be aware that if a shared library becomes available, that you should adjust your package to use the shared library.
| |
| | |
| ==== Programs which have been granted exceptions ====
| |
| * yaboot has permission to link statically since it's a boot loader that uses e2fsprogs-libs to read the filesystem
| |
| | |
| {{Anchor|SystemLibraryDuplication}}
| |
| | |
| == Duplication of system libraries ==
| |
| | |
| A package should not include or build against a local copy of a library that exists on a system. The package should be patched to use the system libraries. This prevents old bugs and security holes from living on after the core system libraries have been fixed.
| |
| | |
| In this RPM packaging context, the definition of the term 'library' includes: compiled third party source code resulting in shared or static linkable files, interpreted third party source code such as Python, PHP and others. At this time JavaScript intended to be served to a web browser on another computer is specifically exempted from this but this will likely change in the future.
| |
| | |
| Note that for C and C++ there's only one "system" in Fedora but for some other languages we have parallel stacks. For instance, python, python3, jython, and pypy are all implementations of the python language but they are separate interpreters with slightly different implementations of the language. Each stack is considered its own "system" and can each contain its own copy of a library.
| |
| | |
| Some packages may be granted an exception to this. Please see the [[Packaging:No Bundled Libraries|No Bundled Libraries]] page for rationale, the process for being granted an exception, and the requirements if your package is bundling.
| |
| | |
| For information on how to remove bundled libraries, see: [[Packaging:Treatment_Of_Bundled_Libraries|Treatment Of Bundled Libraries]].
| |
| | |
| {{Anchor|Rpath}}
| |
| | |
| == Beware of Rpath ==
| |
| Sometimes, code will hardcode specific library paths when linking binaries (using the -rpath or -R flag). This is commonly referred to as an rpath. Normally, the dynamic linker and loader (ld.so) resolve the executable's dependencies on shared libraries and load what is required. However, when -rpath or -R is used, the location information is then hardcoded into the binary and is examined by ld.so in the beginning of the execution. Since the Linux dynamic linker is usually smarter than a hardcoded path, we usually do not permit the use of rpath in Fedora.
| |
| | |
| There is a tool called ''check-rpaths'' which is included in the ''rpmdevtools'' package. It is a good idea to add it to the ''<code>%__arch_install_post</code>'' macro in your ''<code>~/.rpmmacros</code>'' config file:
| |
| <pre>
| |
| %__arch_install_post \
| |
| /usr/lib/rpm/check-rpaths \
| |
| /usr/lib/rpm/check-buildroot
| |
| </pre>
| |
| | |
| When ''check-rpaths'' is run, you might see output like this:
| |
| <pre>
| |
| ERROR 0001: file '/usr/bin/xapian-tcpsrv' contains a standard rpath '/usr/lib64' in [/usr/lib64]
| |
| </pre>
| |
| | |
| Any rpath flagged by check-rpaths '''MUST''' be removed.
| |
| | |
| {{Anchor|AcceptableRpath}}
| |
| === Rpath for Internal Libraries ===
| |
| | |
| When a program installs internal libraries they are often not installed in the system path. These internal libraries are only used for the programs that are present in the package (for example, to factor out code that's common to the executables). These libraries are not intended for use outside of the package. When this occurs, it is acceptable for the programs within the package to use an rpath to find these libraries.
| |
| | |
| Example:
| |
| <pre>
| |
| # Internal libraries for myapp are present in:
| |
| %{_libdir}/myapp/
| |
| %{_libdir}/myapp/libmyapp.so.0.3.4
| |
| %{_libdir}/myapp/libmyapp.so
| |
| | |
| # myapp has an rpath to %{_libdir}/myapp/
| |
| readelf -d /usr/bin/myapp | grep RPATH
| |
| 0x0000000f (RPATH) Library rpath: [/usr/lib/myapp]
| |
| </pre>
| |
| | |
| {{admon/tip|Non-Internal Libraries|When programs outside of the package are supposed to link against the library, it is better to use the [[#AlternativeRpath| Alternative to Rpath]] or simply move the libraries into %{_libdir} instead. That way the dynamic linker can find the libraries without having to link all the programs with an rpath.}}
| |
| | |
| {{Anchor|AlternativeRpath}}
| |
| === Alternatives to Rpath ===
| |
| Often, rpath is used because a binary is looking for libraries in a non-standard location (standard locations are /lib, /usr/lib, /lib64, /usr/lib64). If you are storing a library in a non-standard location (e.g. /usr/lib/foo/), you should include a custom config file in /etc/ld.so.conf.d/. For example, if I was putting 32 bit libraries of libfoo in /usr/lib/foo, I would want to make a file called "foo32.conf" in /etc/ld.so.conf.d/, which contained the following:
| |
| <pre>
| |
| /usr/lib/foo
| |
| </pre>
| |
| Make sure that you also make a 64bit version of this file (e.g. foo64.conf) as well (unless the package is disabled for 64bit architectures, of course).
| |
| | |
| {{Anchor|RemovingRpath}}
| |
| === Removing Rpath ===
| |
| | |
| There are several different ways to fix the rpath issue:
| |
| | |
| * If the application uses configure, try passing the ''--disable-rpath'' flag to configure.
| |
| * If the application uses a local copy of libtool, add the following lines to the spec after %configure:
| |
| <pre>
| |
| %configure
| |
| sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
| |
| sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
| |
| </pre>
| |
| * Sometimes, the code/Makefiles can be patched to remove the ''-rpath'' or ''-R'' flag from being called. This is not always easy or sane to do, however.
| |
| * As a last resort, Fedora has a package called ''chrpath''. When this package is installed, you can run <code>chrpath --delete</code> on the files which contain rpaths. So, in our earlier example, we'd run:
| |
| <pre>
| |
| chrpath --delete $RPM_BUILD_ROOT%{_bindir}/xapian-tcpsrv
| |
| </pre>
| |
| Make sure that you remember to add a '''BuildRequires: chrpath''' if you end up using this method.
| |
| | |
| {{Anchor|Config}}
| |
| == Configuration files ==
| |
| | |
| Configuration files must be marked as such in packages.
| |
| | |
| As a rule of thumb, use <code>%config(noreplace)</code> instead of plain <code>%config</code> unless your best, educated guess is that doing so will break things. In other words, think hard before overwriting local changes in configuration files on package upgrades. An example case when /not/ to use <code>noreplace</code> is when a package's configuration file changes so that the new package revision wouldn't work with the config file from the previous package revision. Whenever plain <code>%config</code> is used, add a brief comment to the specfile explaining why.
| |
| | |
| Don't use %config or %config(noreplace) under /usr. /usr is deemed to not contain configuration files in Fedora.
| |
| | |
| === Configuration of Package Managers ===
| |
| | |
| Configuration for package managers in Fedora <b>MUST ONLY</b> reference the official Fedora repositories in their default enabled and disabled state (see the yum repo configuration in the <code>fedora-release</code> or <code>fedora-repos</code> packages for the canonical list). Unofficial and third-party repositories that contain only packages that it is legal for us to direct people to in Fedora (see the [[Forbidden items]] and [[Licensing:Main]] pages for an explanation of what is legal) may be shipped in <code>%{_docdir}</code>. The idea is that the system administrator would need to explicitly copy the configuration file from doc into the proper location on the filesystem if they want to enable the repository.
| |
| | |
| == Per-product Configuration ==
| |
| | |
| In the Fedora.next world, we will have a set of curated Fedora Products as well as the availability of classic Fedora. Historically, we have maintained a single set of configuration defaults for all Fedora installs but different target use-cases have different needs. Please see the [[Packaging:Per-Product_Configuration| Per-Product Configuration Guidelines]] for instructions on how to create packages that need to behave differently between Fedora.next Products.
| |
| | |
| {{Anchor|Init}}
| |
| {{Anchor|Initscripts}}
| |
| | |
| == Systemd ==
| |
| | |
| As of Fedora 15, Systemd unit files are supported in Fedora. There are detailed guidelines for Systemd unit files here:
| |
| [[Packaging:Systemd]]
| |
| | |
| === Initscripts ===
| |
| | |
| Older versions of Fedora supported SystemV-style initscripts, but they are now considered obsolete for Fedora 15+. There are detailed guidelines for SysV-style initscripts here: [[Packaging:SysVInitScript]]
| |
| | |
| {{Anchor|desktop}}
| |
| | |
| == Desktop files ==
| |
| | |
| If a package contains a GUI application, then it needs to also include a properly installed .desktop file. For the purposes of these guidelines, a GUI application is defined as any application which draws an X window and runs from within that window. Installed .desktop files MUST follow the [http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html desktop-entry-spec] , paying particular attention to validating correct usage of Name, GenericName, [http://standards.freedesktop.org/menu-spec/latest/apa.html Categories] ,
| |
| [http://www.freedesktop.org/Standards/startup-notification-spec StartupNotify]
| |
| entries.
| |
| | |
| === Icon tag in Desktop Files ===
| |
| The icon tag can be specified in two ways:
| |
| | |
| * Full path to specific icon file:
| |
| <code> Icon=/usr/share/pixmaps/comical.png </code>
| |
| | |
| * Short name without file extension:
| |
| <code> Icon=comical </code>
| |
| | |
| The short name without file extension is preferred, because it allows for icon theming (it assumes .png by default, then tries .svg and finally .xpm), but either method is acceptable.
| |
| | |
| Additionally, there are scriptlets for packages to use to update the icon cache to ensure that the Desktop files are able to load the included icon files. See [[Packaging:ScriptletSnippets#Icon_Cache]].
| |
| | |
| === .desktop file creation ===
| |
| If the package doesn't already include and install its own .desktop file, you need to make your own. You can do this by including a .desktop file you create as a Source: (e.g. Source3: %{name}.desktop) or generating it in the spec file. Here are the contents of a sample .desktop file (comical.desktop):
| |
| | |
| <pre>
| |
| [Desktop Entry]
| |
| Name=Comical
| |
| GenericName=Comic Archive Reader
| |
| Comment=Open .cbr & .cbz files
| |
| Exec=comical
| |
| Icon=comical
| |
| Terminal=false
| |
| Type=Application
| |
| Categories=Graphics;
| |
| </pre>
| |
| | |
| === desktop-file-install usage ===
| |
| It is not simply enough to just include the .desktop file in the package, one MUST run <code>desktop-file-install</code> (in <code>%install</code>) OR <code>desktop-file-validate</code> (in <code>%check</code> or <code>%install</code>) and have <code>BuildRequires: desktop-file-utils</code>, to help ensure .desktop file safety and spec-compliance. <code>desktop-file-install</code> MUST be used if the package does not install the file or there are changes desired to the .desktop file (such as add/removing categories, etc). <code>desktop-file-validate</code> MAY be used instead if the .desktop file's content/location does not need modification. Here are some examples of
| |
| usage:
| |
| | |
| <pre>
| |
| desktop-file-install \
| |
| --dir=${RPM_BUILD_ROOT}%{_datadir}/applications \
| |
| %{SOURCE3}
| |
| </pre>
| |
| | |
| <pre>
| |
| desktop-file-install \
| |
| --add-category="AudioVideo" \
| |
| --delete-original \
| |
| --dir=%{buildroot}%{_datadir}/applications \
| |
| %{buildroot}/%{_datadir}/applications/foo.desktop
| |
| </pre>
| |
| | |
| <pre>
| |
| desktop-file-validate %{buildroot}/%{_datadir}/applications/foo.desktop
| |
| </pre>
| |
| | |
| {{admon/warning|--vendor and desktop-file-install| For F19 and onwards, do '''not''' apply a vendor tag to .desktop files (using --vendor). New packages should not add a vendor tag to any older branches either. The vendor tag is implemented by adding a vendor prefix to the .desktop filename which breaks some tools. If an existing package has a vendor tag in previous Fedora releases it must continue to do so but only in those releases. This is mostly for the sake of user menu-editing which bases off of .desktop file/path names and thus break if the filename changes.}}
| |
| | |
| {{Anchor|macros}}
| |
| | |
| == Macros ==
| |
| Packagers are strongly encouraged to use macros instead of hard-coded directory names (see [[Packaging:RPMMacros]] ). However, in situations where the macro is longer than the path it represents, or situations where the packager feels it is cleaner to use the actual path, the packager is permitted to use the actual path instead of the macro. There are several caveats to this approach:
| |
| * The package must be consistent. For any given path, within the same spec, use either a hard-coded path or a macro, not a combination of the two.
| |
| * %{_libdir} must always be used for binary libraries due to multi-lib, you may not substitute a hard-coded path.
| |
| | |
| Macro forms of system executables SHOULD NOT be used except when there is a need to allow the location of those executables to be configurable. For example, <code>rm</code> should be used in preference to <code>%{__rm}</code>, but <code>%{__python}</code> is acceptable.
| |
| | |
| Having macros in a Source: or Patch: line is a matter of style. Some people enjoy the ready readability of a source line without macros. Others prefer the ease of updating for new versions when macros are used. In all cases, remember to be consistent in your spec file and verify that the URLs you list are valid. spectool (from the rpmdevtools package) can aid you in checking that whether the URL contains macros or not.
| |
| | |
| If you need to determine the actual string when it contains macros, you can use rpm. For example, to determine the actual Source: value, you can run:
| |
| <pre>
| |
| rpm -q --specfile foo.spec --qf "$(grep -i ^Source foo.spec)\n"
| |
| </pre>
| |
| | |
| {{Anchor|%autosetup}}
| |
| === %autosetup ===
| |
| As an alternative to the usual %setup macro, %autosetup exists in current versions of Fedora (RPM 4.11+) and (in addition to the normal %setup tasks) will apply all defined Patch# items in the spec automatically. It is also capable of handling VCS formatted patch files, but this will require additional BuildRequires, and assumes that _all_ patch files in the spec are formatted for that single VCS type. For this reason, we do not recommend that you specify a VCS with %autosetup. For more details on proper use of %autosetup, see http://www.rpm.org/wiki/PackagerDocs/Autosetup.
| |
| | |
| {{Anchor|UsingBuildRootOptFlags}}
| |
| === Using %{buildroot} and %{optflags} vs $RPM_BUILD_ROOT and $RPM_OPT_FLAGS ===
| |
| There are two styles of defining the rpm Build Root and Optimization Flags in a spec file:
| |
| | |
| {| border="1"
| |
| |-
| |
| | ||macro style || variable style
| |
| |-
| |
| |Build Root||%{buildroot}||$RPM_BUILD_ROOT
| |
| |-
| |
| |Opt. Flags||%{optflags}||$RPM_OPT_FLAGS
| |
| |}
| |
| | |
| There is very little value in choosing one style over the other, since they will resolve to the same values in all scenarios. You should pick a style and use it consistently throughout your packaging.
| |
| | |
| Mixing the two styles, while valid, is bad from a QA and usability point of view, and should not be done in Fedora packages.
| |
| | |
| {{Anchor|MakeInstall}}
| |
| === Why the %makeinstall macro should not be used ===
| |
| Fedora's RPM includes a <code>%makeinstall</code> macro but it must '''NOT''' be used when make install DESTDIR=%{buildroot} works. %makeinstall is a kludge that can work with Makefiles that don't make use of the DESTDIR variable but it has the following potential issues:
| |
| * <code>%makeinstall</code> overrides a set of Make variables during "make install" and prepends the %{buildroot} path. I.e. it performs make prefix="%{buildroot}%{_prefix}" libdir="%{buildroot}%{_libdir} ...".
| |
| * It is error-prone and can have unexpected effects when run against less than perfect Makefiles, e.g. the buildroot path may be included in installed files where variables are substituted at install-time.
| |
| * It can trigger unnecessary and wrong rebuilds when executing "make install", since the Make variables have different values compared with the %build section.
| |
| * If a package contains libtool archives, it can cause broken *.la files to be installed.
| |
| | |
| Instead, Fedora packages should use: <code>%make_install</code> (Note the "_" !), <code>make DESTDIR=%{buildroot} install</code> or <code>make DESTDIR=$RPM_BUILD_ROOT install</code>. Those all do the same thing.
| |
| | |
| === Source RPM Buildtime Macros ===
| |
| All macros in <code>Summary:</code> and <code>%description</code> need to be expandable at srpm buildtime. Because SRPMs are built without the package's BuildRequires installed, depending on macros defined outside of the spec file can easily lead to the unexpanded macros showing up in the built SRPM. One way to check is to create a minimal chroot and build the srpm:
| |
| | |
| <pre>
| |
| mock --init
| |
| mock --copyin [SRPM] /
| |
| mock --shell bash
| |
| rpm -ivh [SRPM]
| |
| cd /builddir/build/SPECS
| |
| rpmbuild -bs --nodeps [SRPM]
| |
| rpm -qpiv /builddir/build/SRPMS/[SRPM]
| |
| </pre>
| |
| Check the <code>rpm</code> output for unexpanded macros (<code>%{foo}</code>) or missing information (when<code>%{?foo}</code> is expanded to the empty string). Even easier is to simply avoid macros in <code>Summary:</code> and <code>%description</code> unless they are defined in the current spec file.
| |
| | |
| === Improper use of %_sourcedir ===
| |
| Packages which use files itemized as Source# files, must refer to those files by their <code>Source#</code> macro name, and must not use <code>$RPM_SOURCE_DIR</code> or <code>%{sourcedir}</code> to refer to those files. See [[Packaging:RPM_Source_Dir]] for full details.
| |
| | |
| === Software Collection Macros ===
| |
| [[User:Toshio/SCL_Guidelines_(draft)| Software Collections]] are to be kept to separate packages from mainstream packages similar to how [[Packaging:MinGW| MingW packages]] are managed.
| |
| | |
| In the past, SCL macros were allowed to be present inside of mainstream packages if they were not used. Since we're now building SCLs, we are now enforcing a strict separation. Packages '''MUST''' be updated to restrict SCL macros to only those packages particularly approved as part of an SCL.
| |
| | |
| === Packaging of Additional RPM Macros ===
| |
| | |
| Additional RPM macros '''must''' be stored under the <code>%{_rpmconfigdir}/macros.d</code> directory. spec files that are intended to also work on EPEL < 7 can conditionally use <code>%{_sysconfdir}/rpm</code> instead as rpm in RHEL6 and below does not search <code>%{_rpmconfigdir}/macros.d</code> for macros).
| |
| | |
| They '''must''' be named using the syntax "<code>macros.$PACKAGE</code>" (e.g. <code>macros.perl</code>). Normally, these files are packaged in the -devel subpackage, since they are usually only needed for building other packages. However, in some situations, this is not always ideal and packagers are encouraged to use their best judgment when determining the proper package for these files. RPM Macro files '''MUST NOT''' be marked as <code>%config</code>.
| |
| | |
| Here's some example spec snippets that place the macro file into the correct directory with both RHEL5 & 6's rpm and with modern rpm.
| |
| | |
| <pre>
| |
| # define macrosdir to the old location for EPEL 5 and 6. Use the new location everywhere else
| |
| %global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d)
| |
| [..]
| |
| SOURCE1: macros.perl
| |
| [..]
| |
| %install
| |
| cp %{SOURCE1} %{buildroot}%{macrosdir}
| |
| [..]
| |
| %files -n devel
| |
| %{macrosdir}/macros.perl
| |
| </pre>
| |
| | |
| == Scripting inside of spec files ==
| |
| | |
| Sometimes it is necessary to write a short script (perhaps a one-liner) that is executed in the %setup, %build, or %install sections of a spec file to get some information about the build environment. In Fedora, spec files should only use the following languages for this purpose:
| |
| | |
| 1. Python
| |
| 2. Perl
| |
| 3. Standard programs used in shell programing, for instance gawk or sed
| |
| 4. Lua (as supported by the native lua interpreter in rpm)
| |
| | |
| Additionally, if your package cannot build without a specific scripting language (such as Ruby, or Tcl), and therefore already has a BuildRequires on that language, it may also be called from the spec file.
| |
| | |
| Note: If you call perl or python in your spec file (and it is not already a BuildRequires for the package), you need to explicitly add a BuildRequires for perl or python.
| |
| | |
| Rationale: Use of fringe scripting languages, or languages unrelated to the package being built, leads to a more complex dependency graph and causes problems when bootstrapping or rebuilding the OS. Also, limiting the languages used makes working on Fedora spec files more uniform, and easier for more packagers.
| |
| | |
| == %global preferred over %define ==
| |
| | |
| Use <code>%global</code> instead of <code>%define</code>, unless you really need only locally defined submacros within other macro definitions (a very rare case).
| |
| | |
| Rationale: The two macro defining statements behave the same when they are a the top level of rpm's nesting level.
| |
| | |
| But when they are used in nested macro expansions (like in <code> %{!?foo: ... } </code> constructs, <code>%define</code> theoretically only lasts until the end brace (local scope), while <code>%global</code> definitions have global scope.
| |
| | |
| Note that %define and %global differ in more ways than just scope: the body of a %define'd macro is lazily expanded (ie when used), but the body of %global is expanded at definition time. It's possible to use %%-escaping to force lazy expansion of %global.
| |
| | |
| {{admon/note||In Fedora 12 and earlier, a minor bug in rpm caused the local macro definition to not be garbage collected unless other events forced rpm to. So the bug is seldom triggered but when it is it is difficult to diagnose the issue. Using <code>%global</code> by default helps to avoid creation of new latent bugs. [https://www.redhat.com/archives/fedora-devel-list/2010-January/msg00093.html Bugfix description]}}
| |
| | |
| {{Anchor|locales}}
| |
| | |
| == Handling Locale Files ==
| |
| | |
| Translation files may be handled by different programs for different frameworks. Make sure you BuildRequire the correct package or else your package could fail to generate translation files in the buildroot.
| |
| | |
| If the package uses gettext for translations, add
| |
| <pre>
| |
| BuildRequires: gettext
| |
| </pre>
| |
| | |
| For Qt-based packages that use the Linguist tool chain, for the localisation utilities add
| |
| <pre>
| |
| BuildRequires: qt-devel
| |
| </pre>
| |
| | |
| Fedora includes an rpm macro called <code>%find_lang</code>. This macro will locate all of the locale files that belong to your package (by name), and put this list in a file. You can then use that file to include all of the locales. <code>%find_lang</code> should be run in the %install section of your spec file, after all of the files have been installed into the buildroot. The correct syntax for <code>%find_lang</code> is usually:
| |
| <pre>
| |
| %find_lang %{name}
| |
| </pre>
| |
| In some cases, the application may use a different "name" for its locales. You may have to look at the locale files and see what they are named. If they are named <code>myapp.mo</code>, then you will need to pass <code>myapp</code> to <code>%find_lang</code> instead of <code>%{name}</code>.
| |
| After <code>%find_lang</code> is run, it will generate a file in the active directory (by default, the top level of the source dir). This file will be named based on what you passed as the option to the <code>%find_lang</code> macro. Usually, it will be named <code>%{name}.lang</code>. You should then use this file in the <code>%files</code> list to include the locales detected by <code>%find_lang</code>. To do this, you should include it with the -f parameter to <code>%files</code>.
| |
| <pre>
| |
| %files -f %{name}.lang
| |
| %{_bindir}/foobar
| |
| ...
| |
| </pre>
| |
| | |
| Note that <code>%find_lang</code> by default searches for gettext locales, but it can also handle Qt translations, localised manpages and help files.
| |
| | |
| To process GNOME help files put into <code>/usr/share/gnome/help/</code> use
| |
| <pre>
| |
| %find_lang %{name} --with-gnome
| |
| </pre>
| |
| | |
| To process KDE help files put into <code>/usr/share/doc/HTML/</code> use
| |
| <pre>
| |
| %find_lang %{name} --with-kde
| |
| </pre>
| |
| | |
| To process Qt's <code>.qm</code> binary translation files use
| |
| <pre>
| |
| %find_lang %{name} --with-qt
| |
| </pre>
| |
| | |
| To process localised manpages (doesn't include the default, non-localised one), use
| |
| <pre>
| |
| %find_lang %{name} --with-man
| |
| </pre>
| |
| | |
| To see all the options, run <code>/usr/lib/rpm/find-lang.sh</code> in the terminal.
| |
| | |
| Names different from <code>%{name}</code> (e.g. multiple manpages) must be handled via separate calls to <code>%find_lang</code>.
| |
| | |
| Here is an example of proper usage of <code>%find_lang</code>, in <code>foo.spec</code> with the "foo" application localised using gettext and man pages named "bar" instead of "foo":
| |
| | |
| <pre>
| |
| Name: foo
| |
| ...
| |
| %prep
| |
| %setup -q
| |
| | |
| %build
| |
| %configure --with-cheese
| |
| make %{?_smp_mflags}
| |
| | |
| %install
| |
| make DESTDIR=%{buildroot} install
| |
| %find_lang %{name}
| |
| %find_lang bar --with-man
| |
| | |
| %files -f %{name}.lang -f bar.lang
| |
| %doc LICENSE README
| |
| %{_bindir}/%{name}
| |
| %{_mandir}/man1/bar.1.gz
| |
| | |
| %changelog
| |
| * Fri Jan 13 2012 Karel Volny <kvolny@redhat.com> 0.1-2
| |
| - add man pages example
| |
| | |
| * Thu May 4 2006 Tom "spot" Callaway <tcallawa@redhat.com> 0.1-1
| |
| - sample spec that uses %%find_lang | |
| | |
| </pre>
| |
| | |
| {{Anchor|whyfindlang}}
| |
| === Why do we need to use %find_lang? ===
| |
| | |
| Using <code>%find_lang</code> helps keep the spec file simple, and helps avoid several other packaging mistakes.
| |
| | |
| * Packages that use <code>%{_datadir}/*</code> to grab all the locale files in one line also grab ownership of the locale directories, which is not permitted.
| |
| * Most packages that have locales have lots of locales. Using <code>%find_lang</code> is much easier in the spec file than having to do:
| |
| <pre>
| |
| %{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo
| |
| %{_datadir}/locale/be/LC_MESSAGES/%{name}.mo
| |
| %{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo
| |
| %{_datadir}/locale/de/LC_MESSAGES/%{name}.mo
| |
| %{_datadir}/locale/es/LC_MESSAGES/%{name}.mo
| |
| ...
| |
| </pre>
| |
| * As new locale files appear in later package revisions, <code>%find_lang</code> will automatically include them when it is run, preventing you from having to update the spec any more than is necessary.
| |
| | |
| Keep in mind that usage of <code>%find_lang</code> in packages containing locales is a MUST.
| |
| | |
| {{Anchor|Timestamps}}
| |
| | |
| == Timestamps ==
| |
| When adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, eg. <code>cp -p</code> or <code>install -p</code>.
| |
| | |
| When downloading sources, patches etc, consider using a client that preserves the upstream timestamps. For example <code>wget -N</code> or <code>curl -R</code>. To make the change global for wget, add this to your <code>~/.wgetrc</code>: <code>timestamping = on</code>, and for curl, add to your <code>~/.curlrc</code>: <code>-R</code>.
| |
| | |
| {{Anchor|parallelmake}}
| |
| == Parallel make ==
| |
| Whenever possible, invocations of <code>make</code> should be done as
| |
| <pre>
| |
| make %{?_smp_mflags}
| |
| </pre>
| |
| 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
| |
| <pre>
| |
| %_smp_mflags -j3
| |
| </pre>
| |
| to your <code>~/.rpmmacros</code> file -- even on UP machines -- as this will expose most of these errors.
| |
| | |
| {{Anchor|Scriptlets}}
| |
| == Scriptlets ==
| |
| Great care should be taken when using scriptlets in Fedora packages. If scriptlets are used, those scriptlets must be sane. Some common scriptlets are documented here: [[Packaging:ScriptletSnippets]].
| |
| | |
| {{Anchor|ScriptletConditionals}}
| |
| === 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:
| |
| <pre>
| |
| install erase upgrade reinstall
| |
| %pre 1 - 2 2
| |
| %post 1 - 2 2
| |
| %preun - 0 1 -
| |
| %postun - 0 1 -
| |
| </pre>
| |
| This means that for example a package that installs an init script with the <code>chkconfig</code> command should uninstall it only on erase and not upgrade with the following snippet:
| |
| <pre>
| |
| %preun
| |
| if [ $1 -eq 0 ] ; then
| |
| /sbin/chkconfig --del %{name}
| |
| fi
| |
| </pre>
| |
| See also <code>/usr/share/doc/rpm-*/triggers</code>, which gives a more formal, generalized definition about the integer value(s) passed to various scripts.
| |
| | |
| {{Anchor|SciptletsWriteDirs}}
| |
| === Scriplets are only allowed to write in certain directories ===
| |
| Build scripts of packages (%prep, %build, %install, %check and %clean) may only alter files (create, modify, delete) under %{buildroot}, %{_builddir} and valid temporary locations like /tmp, /var/tmp (or $TMPDIR or %{_tmppath} as set by the rpmbuild process) according to the following matrix
| |
| | |
| {| border="1"
| |
| |-
| |
| | || /tmp, /var/tmp, $TMPDIR, %{_tmppath} || %{_builddir} || %{buildroot}
| |
| |-
| |
| |%prep || yes || yes || no
| |
| |-
| |
| |%build || yes || yes || no
| |
| |-
| |
| |%install || yes || yes || yes
| |
| |-
| |
| |%check || yes || yes || no
| |
| |-
| |
| |%clean || yes || yes || yes
| |
| |}
| |
| | |
| Further clarification: That should hold true irrespective of the builder's uid.
| |
| | |
| === The %pretrans scriptlet ===
| |
| | |
| Note that the %pretrans scriptlet will, in the particular case of system installation, run before anything at all has been installed. This implies that it cannot have any dependencies at all. For this reason, %pretrans is best avoided, but if you must use it, the script must be written in Lua. See http://www.rpm.org/wiki/PackagerDocs/RpmLua for more information.
| |
| | |
| | |
| {{Anchor|SeparateUserAccounts}}
| |
| | |
| == Build packages 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.
| |
| | |
| The same applies to reviewers/testers. Rebuild src.rpms in a separate account which does not have access to any sensitive data.
| |
| | |
| {{Anchor|RelocatablePackages}}
| |
| == Relocatable packages ==
| |
| The use of RPM's facility for generating relocatable packages is strongly discouraged. It is difficult to make work properly, impossible to use from the installer or from yum, and not generally necessary if other packaging guidelines are followed. However, in the unlikely event that you have a good reason to make a package relocatable, you MUST state this intent and reasoning in the request for package review.
| |
| | |
| {{Anchor|FileAndDirectoryOwnership}}
| |
| == File and Directory Ownership ==
| |
| | |
| Your package should own all of the files that are installed as part of the %install process.
| |
| | |
| In most cases, it should not be necessary for multiple packages to contain identical copies of the same file. However, if it is necessary, multiple packages may contain identical copies of the same file, as long as the following requirements are met:
| |
| | |
| * The packages sharing ownership of the identical files are built from a single SRPM.
| |
| | |
| OR
| |
| | |
| * The packages sharing ownership of the identical files are not in a dependency chain (e.g. if package A requires package B, they should not both contain identical files, either A or B must own the common files, but not both.)
| |
| | |
| In addition, identical files are defined as files which are always identical in content, checksum, permissions, and location on the filesystem in each package.
| |
| | |
| Directory ownership is a little more complex than file ownership. Packages must own all directories they put files in, except for:
| |
| * any directories owned by the <code>filesystem</code>, <code>man</code>, or other explicitly created <code>-filesystem</code> packages
| |
| * any directories owned by other packages in your package's natural dependency chain
| |
| | |
| In this context, a package's "natural dependency chain" is defined as the set of packages necessary for that package to function normally. To be specific, you do not need to require a package for the sole fact that it happens to own a directory that your package places files in. If your package already requires that package for other reasons, then your package should not also own that directory.
| |
| | |
| In all cases we are guarding against unowned directories being present on a system. Please see [[Packaging:UnownedDirectories]] for the details.
| |
| | |
| {{admon/important|Note on multiple ownership| Note that when co-owning directories, you <b>must</b> ensure that the ownership and permissions on the directory match in all packages that own it.}}
| |
| | |
| Here are examples that describe how to handle most cases of directory ownership.
| |
| | |
| === The directory is wholly contained in your package, or involves core functionality of your package ===
| |
| | |
| An example:
| |
| <pre>
| |
| gnucash places many files under the /usr/share/gnucash directory
| |
| </pre>
| |
| | |
| Solution: the <code>gnucash</code> package should own the <code>/usr/share/gnucash</code> directory
| |
| | |
| === The directory is also owned by a package implementing required functionality of your package ===
| |
| | |
| An example:
| |
| | |
| <pre>
| |
| pam owns the /etc/pam.d directory
| |
| gdm places files into /etc/pam.d
| |
| gdm depends on pam to function normally, and would Require: pam (either implicitly or explicitly) separate from the directory ownership.
| |
| </pre>
| |
| | |
| Solution: the <code>pam</code> package should own the <code>/etc/pam.d</code> directory, and <code>gdm</code> should <code>Require:</code> the <code>pam</code> package.
| |
| | |
| === The directory is owned by a package which is not required for your package to function ===
| |
| | |
| Some packages create and own directories with the intention of permitting other packages to store appropriate files, but those other packages do not need that original package to be present to function properly.
| |
| | |
| An example:
| |
| | |
| <pre>
| |
| gtk-doc owns the /usr/share/gtk-doc/ directory
| |
| evolution puts files into /usr/share/gtk-doc/
| |
| evolution does not need gtk-doc in order to function properly.
| |
| Nothing in evolution's dependency chain owns /usr/share/gtk-doc/
| |
| </pre>
| |
| | |
| Solution: the <code>evolution</code> package should own the <code>/usr/share/gtk-doc</code> directory. There is no need to add an explicit Requires on gtk-doc solely for the directory ownership.
| |
| | |
| {{admon/important|An exception|Sometimes, it may be preferable for such directories to be owned by an "artificial filesystem" package, such as <code>mozilla-filesystem</code>. These packages are designed to be explicitly required when other packages store files in their directories, thus, in such situations, these packages should explicitly Require the artificial filesystem package and not multiply own those directories. Packagers should consider the number of affected directories and packages when determining whether to create artificial filesystem packages, and use their own best judgement to determine if this is necessary or not.}}
| |
| | |
| Another example:
| |
| | |
| <pre>
| |
| bash-completion owns the /etc/bash_completion.d directory and uses the files placed there to configure itself.
| |
| git places files into /etc/bash_completion.d
| |
| bzr places files into /etc/bash_completion.d
| |
| </pre>
| |
| | |
| Solution: Both the git and bzr packages should own the /etc/bash_completion.d directory as bash-completion is optional functionality and the installation of git or bzr should not force the installation of bash-completion.
| |
| {{admon/important|Rule of Thumb|When determining whether this exception applies, packagers and reviewers should ask this question: Do the files in this common directory enhance or add functionality to another package, where that other package is not necessary to be present for the primary functionality of this package?}}
| |
| | |
| === The package you depend on to provide a directory may choose to own a different directory in a later version and your package will run unmodified with that later version ===
| |
| | |
| An example involving Perl modules:
| |
| | |
| Assume <code>perl-A-B</code> depends on <code>perl-A</code> and installs files into /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B.
| |
| The base Perl package guarantees that it will own /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi for as long as it remains compatible with version 5.8.8, but a future upgrade of the <code>perl-A</code> package may install into (and thus own) /usr/lib/perl5/vendor_perl/5.9.0/i386-linux-thread-multi/A. So the <code>perl-A-B</code> package needs to own /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A as well as /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B in order to maintain proper ownership.
| |
| | |
| {{Anchor|DuplicateFiles}}
| |
| === Duplicate Files ===
| |
| | |
| A Fedora package must not list a file more than once in the spec file's %files listings. If you think your package is a valid exception to this, please bring it to the attention of the Packaging Committee so they can improve on this Guideline.
| |
| | |
| One notable exception to this rule is around license texts. There are certain situations where it is required to duplicate the license text across multiple %files section within a package. For more details, please refer to [[Packaging:LicensingGuidelines#Subpackage_Licensing]].
| |
| | |
| {{Anchor|FilePermissions}}
| |
| === File Permissions ===
| |
| | |
| Permissions on files must be set properly. Inside of /usr, files should be owned by root:root unless a more specific user or group is needed for security . They must be universally readable (and executable if appropriate). Outside of /usr, non-config and non-state files should be owned by root:root, universally readable (and executable if appropriate) unless circumstances require otherwise.
| |
| | |
| Default file mode is 0644 or 0755. Directories should be mode 0755. Most well behaved build scripts and rpm will use these defaults. If the directory needs to be group writable, it should also have the setgid bit set so that files written there are owned by that group. These directories should have mode 2775.
| |
| | |
| Deviations from the default ownership or mode must be justified and documented in the specfile.
| |
| | |
| In the past (pre rpm 4.4), it was necessary to have a <code>%defattr</code> section at the beginning of each <code>%files</code> section, but this is now the default and no longer necessary to explicitly include.
| |
| | |
| {{Anchor|UsersAndGroups}}
| |
| | |
| == Users and Groups ==
| |
| | |
| Some packages require or benefit from dedicated runtime user and/or group accounts. Guidelines for handling these cases are in a separate [[Packaging:UsersAndGroups]] document.
| |
| | |
| {{Anchor|WebApplications}}
| |
| == Web Applications ==
| |
| | |
| Web applications packaged in Fedora should put their content into /usr/share/%{name} and NOT into /var/www/. This is done because:
| |
| | |
| * /var is supposed to contain variable data files and logs. /usr/share is much more appropriate for this.
| |
| * Many users already have content in /var/www, and we do not want any Fedora package to step on top of that.
| |
| * /var/www is no longer specified by the Filesystem Hierarchy Standard
| |
| | |
| {{Anchor|Conflicts}}
| |
| == Conflicts ==
| |
| | |
| Whenever possible, Fedora packages should avoid conflicting with each other. Unfortunately, this is not always possible. For full details on Fedora's Conflicts policy, see: [[Packaging:Conflicts]] .
| |
| | |
| Tools such as Alternatives and Environment Modules can also help prevent package conflicts.
| |
| | |
| === Alternatives ===
| |
| | |
| The "alternatives" tool provides a means for parallel installation of packages which provide the same functionality by maintaining sets of symlinks. For full details on how to properly use alternatives, see [[Packaging:Alternatives]].
| |
| | |
| === Environment Modules ===
| |
| | |
| When there are multiple variants that each serve the needs of some user and thus must be available simultaneously by users, the alternatives system simply isn't enough since it is system-wide. In such situations, use of Environment Modules can avoid conflicts. For full details on how to properly use Environment Modules, see [[Packaging:EnvironmentModules]].
| |
| | |
| {{Anchor|Bundling}}
| |
| | |
| == Bundling of multiple projects ==
| |
| Fedora packages should make every effort to avoid having multiple, separate, upstream projects bundled together in a single package.
| |
| | |
| However, when this is unavoidable, packagers must apply for a Bundling Exception with the Fedora Packaging Committee. For more information on Bundling and applying for a Bundling Exception, please read [[Packaging:No_Bundled_Libraries]].
| |
| | |
| {{Anchor|AvoidFontBundling}}
| |
| === Avoid bundling of fonts in other packages ===
| |
| Fonts in general-purpose formats such as Type1, OpenType TT (TTF) or OpenType CFF (OTF) are subject to specific packaging guidelines ([[Packaging:FontsPolicy|1]]), and should never be packaged in a private application directory instead of the system-wide font repositories.
| |
| For more information, see: [[Packaging:FontsPolicy#Package_layout_for_fonts]].
| |
| | |
| == All patches should have an upstream bug link or comment ==
| |
| | |
| All patches in Fedora spec files '''SHOULD''' have a comment above them about their upstream status. Any time you create a patch, it is best practice to file it in an upstream bug tracker, and include a link to that in the comment above the patch. For example:
| |
| | |
| <pre>
| |
| # http://bugzilla.gnome.org/show_bug.cgi?id=12345
| |
| Patch0: gnome-panel-fix-frobnicator.patch
| |
| </pre>
| |
| | |
| The above is perfectly acceptable; but if you prefer, a brief comment about what the patch does above can be helpful:
| |
| | |
| <pre>
| |
| # Don't crash with frobnicator applet
| |
| # http://bugzilla.gnome.org/show_bug.cgi?id=12345
| |
| Patch0: gnome-panel-fix-frobnicator.patch
| |
| </pre>
| |
| | |
| Sending patches upstream and adding this comment will help ensure that Fedora is acting as a good FLOSS citizen (see [[PackageMaintainers/WhyUpstream| Why Upstream?]] ). It will help others (and even you) down the line in package maintenance by knowing what patches are likely to appear in a new upstream release.
| |
| | |
| === If upstream doesn't have a bug tracker ===
| |
| You can indicate that you have sent the patch upstream and any known status:
| |
| | |
| <pre>
| |
| # Sent upstream via email 20080407
| |
| Patch0: foobar-fix-the-bar.patch
| |
| </pre>
| |
| | |
| <pre>
| |
| # Upstream has applied this in SVN trunk
| |
| Patch0: foobar-fix-the-baz.patch
| |
| </pre>
| |
| | |
| === Fedora-specific (or rejected upstream) patches ===
| |
| It may be that some patches truly are Fedora-specific; in that case, say so:
| |
| | |
| <pre>
| |
| # This patch is temporary until we land the long term System.loadLibrary fix in OpenJDK
| |
| Patch0: jna-jni-path.patch
| |
| </pre>
| |
| | |
| {{Anchor|Epochs}}
| |
| == Use of Epochs ==
| |
| RPM supports a field called "Epoch:", which is a numeric field, that, if set, adds another qualifier for RPM to use in doing package comparisons. Specifically, if set, the Epoch of a package trumps all other comparisons (except for a larger Epoch). If Epoch is not set in a package, RPM treats it the same as if it was set to 0.
| |
| | |
| Example:
| |
| <pre>
| |
| Version: 1.2
| |
| Release: 3%{?dist}
| |
| Epoch: 1
| |
| </pre>
| |
| | |
| A package with those definitions would be considered greater than a package with a higher version or a higher release. Since Epoch is confusing to humans (and can never be removed from a package once used), it should only be used in Fedora '''as a last resort''' to resolve upgrade ordering of a package, and should be avoided wherever possible.
| |
| | |
| Also, Epoch complicates normal packaging guidelines. If a package uses an Epoch, it must be referred to in any place where <code>%{version}-%{release}</code> is used. For example, if a package being depended upon has an Epoch, this must be listed when adding a versioned dependency:
| |
| | |
| <pre>
| |
| Requires: foo = %{epoch}:%{version}-%{release}
| |
| </pre>
| |
| | |
| === Epochs from Third Party Repositories ===
| |
| If a package to be imported is or previously was present in a publicly accessible repository, the packager can optionally include an Epoch tag equal to that of the most recent version of the third-party package.
| |
| | |
| == Symlinks ==
| |
| There are two ways of making a symlink, either as a relative link or an absolute link. In Fedora, neither method is required. Packagers should use their best judgement when deciding which method of symlink creation is appropriate.
| |
| | |
| === Relative Symlinks ===
| |
| A relative symlink is a symlink which points to a file or directory relative to the position of the symlink. For example, this command would create a relative symlink:
| |
| <pre>
| |
| ln -s ../..%{_bindir}/foo %{buildroot}/bin/foo
| |
| </pre>
| |
| | |
| Pros:
| |
| * Relative symlinks will point to the same file inside or outside of a chroot.
| |
| | |
| Cons:
| |
| * Much more complicated to create than absolute symlinks
| |
| * Relative symlinks may break or behave unexpectedly when a part of a filesystem is mounted to a custom location.
| |
| * Relative symlinks may break when bind mounting or symlinking directories.
| |
| * Relative symlinks may make it more difficult to use rpm system macros.
| |
| | |
| === Absolute Symlinks ===
| |
| An absolute symlink is a symlink which points to an absolute file or directory path. For example, this command would create an absolute symlink:
| |
| <pre>
| |
| ln -s %{_bindir}/foo %{buildroot}/bin/foo
| |
| </pre>
| |
| | |
| Pros:
| |
| * Much easier to create than relative symlinks.
| |
| * Absolute symlinks work properly when bind mounting or symlinking directories.
| |
| * Absolute symlinks work well with rpm system macros.
| |
| | |
| Cons:
| |
| * Absolute symlinks may break when used with chroots.
| |
| | |
| == Replacing a symlink to a directory or a directory to any type file ==
| |
| In some cases replacing a symlink to a directory requires special handling. Replacing a directory with any type of file always requires special handling.
| |
| | |
| See [[Packaging:Directory_Replacement]] for information about doing this.
| |
| | |
| == Man pages ==
| |
| Man pages are the traditional method of getting help on a unix system. Packages should contain man pages for all binaries/scripts. If it doesn't, work with upstream to add them. Sometimes, other distributions (notably Debian), have man pages for programs. You can use those as a starting point.
| |
| | |
| == Test Suites ==
| |
| If the source code of the package provides a test suite, it should be executed in the <code>%check</code> section, whenever it is practical to do so.
| |
| | |
| == Tmpfiles.d ==
| |
| There are specific guidelines for handling tmpfiles.d configurations and directories (in /var/run and /var/lock): [[Packaging:Tmpfiles.d]]
| |
| | |
| == Renaming/Replacing Existing Packages ==
| |
| {{admon/note|FESCo Policy|FESCo has a [[Package_Renaming_Process#Re-review_required| package renaming policy]] that should be followed when renaming an existing package.}}
| |
| In the event that it becomes necessary to rename or replace an existing package, the new package should make the change transparent to end users to the extent applicable.
| |
| | |
| If a package is being renamed without any functional changes, or is a compatible enough replacement to an existing package (where "enough" means that it includes only changes of magnitude that are commonly found in version upgrade changes), provide clean upgrade paths and compatibility with:
| |
| | |
| <pre>
| |
| Provides: oldpackagename = $provEVR
| |
| Obsoletes: oldpackagename < $obsEVR
| |
| </pre>
| |
| | |
| $provEVR refers to an (Epoch-)Version-Release tuple the original unchanged package would have had if it had been version or release bumped. You usually use macros here because the provides EVR should continue to go up as the renamed package advances in version and release. $obsEVR is an (Epoch-)Version-Release tuple arranged so that there is a clean upgrade path but without gratuitously polluting the version space upwards. You usually do not use macros for this as you're simply trying to advance beyond the last known release under the old name.
| |
| | |
| {{admon/warning|Take <code>%{?dist}</code> into account| When deciding what $obsEVR should be, remember that it needs to be higher than the previous <code>Release:</code> with <code>%{?dist}</code> expanded. Example: if the package previously had <code>Release: 4%{?dist}</code> the release in $obsEVR should be at least 5.}}
| |
| | |
| If a package supersedes/replaces an existing package without being a compatible enough replacement as defined in above, use only the Obsoletes from above.
| |
| | |
| If the provided package had an Epoch set, it must be preserved in both the Provides and Obsoletes. It may and should be removed from the actual new package.
| |
| | |
| Example: foo being renamed to bar, bar is compatible with foo, and the last foo package release being foo-1.0-3%{?dist} with Epoch: 2; add to bar (and similarly for all subpackages as applicable):
| |
| | |
| <pre>
| |
| Version: 1.0
| |
| Release: 4%{?dist}
| |
| Provides: foo = 2:%{version}-%{release}
| |
| Obsoletes: foo <= 2:1.0-4 # Important: We set the Obsoletes release to 4 to be higher than the previous Release: 3%{?dist}
| |
| </pre>
| |
| | |
| Explicit Provides: need to be aware of whether the package is supplying things that can be used in an arch-independent or arch-specific fashion. For packages that are not noarch, Provides: should be made arch-specific by applying the %{?_isa} macro to the end of the text string in Provides (e.g. Provides: foo%{?_isa} = 2:%{version}-%{release}). Packages that explicitly Provide: things that can be used in an arch-independent way—i.e., packages whose dependents don't need to be of the same arch—need not apply this macro. In some cases, a package will supply multiple elements, some of which may be consumed only by dependents of an identical arch and some which may be consumed by dependents of any arch. In such cases, both arch-specific and arch-independent Provides: are warranted.
| |
| | |
| Examples of packages that should explicitly provide only arch-specific Provides: include native code libraries or plug-ins and their associated -devel packages. Packages that should explicitly provide only arch-independent Provides: include most stand-alone programs (in addition to all noarch packages). Even though these programs may themselves be arch-specific, clients that run them should not care about their arch in most cases. A package that explicitly provides, for example, both a native code library as well as an interpreted language interface to that library should have both arch-specific (for clients of the native code library) and arch-independent (for clients of the interpreted language interface) Provides:.
| |
| | |
| If there is no standard naming for a package or other long term naming compatibility requirements involved with the rename, the Provides should be assumed to be deprecated and short lived and removed in the distro release after the next one (ie. if introduced in FC-X, keep in all subsequent package revisions for distros FC-X and FC-(X+1), drop in FC-(X+2)), and the distro version where it is planned to be dropped documented in a comment in the specfile. Maintainers of affected packages should be notified and encouraged to switch to use the new name. Forward compatibility Provides: in older distro branches can be considered in order to make it possible for package maintainers to keep same simple specfiles between branches but still switch to the newer name.
| |
| | |
| For packages that are not usually pulled in by using the package name as the dependency such as library only packages (which are pulled in through library soname depenencies), there's usually no need to add the Provides. Note however that the -devel subpackages of lib packages are pulled in as build dependencies using the package name, so adding the Provides is often appropriate there.
| |
| | |
| == Networking Support ==
| |
| If an application contains native and stable support for both IPv4 and IPv6, and support for IPv6 does not negatively affect IPv4 then both must be enabled in the Fedora package.
| |
| | |
| == Cron Files ==
| |
| For details on how to package cron files, refer to: [[Packaging:CronFiles]]
| |
| | |
| == Security Updates To Resolve Known CVE Issues ==
| |
| If an update to your package resolves a known security concern (at the time of the update) with a Common Vulnerabilities and Exposures (CVE) number assigned to it, you should mention the CVE number in the RPM changelog entry.
| |
| | |
| == Build time network access ==
| |
| Packages in the Fedora buildsystem are built in a mock chroot with no access to the internet. Packages must not depend or or use any network resources that they don't themselves create (ie, for tests). In no cases should source code be downloaded from any external sources, only from the lookaside cache and/or the Fedora git repository.
| |
| | |
| == Bootstrapping ==
| |
| | |
| If your package introduces build time circular dependencies, you should use this macro to bootstrap your package:
| |
| | |
| <pre>
| |
| # Set this to 0 after we've bootstrapped
| |
| %{!?_with_bootstrap: %global bootstrap 1}
| |
| | |
| [...]
| |
| | |
| %if 0%{?bootstrap}
| |
| # dependencies for %%check
| |
| BuildRequires: foo
| |
| %endif
| |
| | |
| [...]
| |
| | |
| %if 0%{?bootstrap}
| |
| %check
| |
| make check
| |
| %endif
| |
| </pre>
| |
| | |
| If your package explicitly <code>Provides:</code> some functionality that is missing when bootstrapped, then that <code>Provides:</code> should look like:
| |
| | |
| <pre>
| |
| %if ! 0%{?bootstrap}
| |
| Provides: bar(some_functionality)
| |
| %endif
| |
| </pre>
| |
| | |
| Please note that usage of pre-built binaries in bootstrap still needs an exception from the Packaging Committee as stated in [[Packaging:Guidelines#Exceptions]]
| |
| | |
| {{Anchor|ApplicationSpecificGuidelines}}
| |
| | |
| == Application Specific Guidelines ==
| |
| | |
| Some applications have specific guidelines written for them, located on their own pages in the Packaging: Namespace.
| |
| | |
| {{Anchor|AdaGuidelines}}
| |
| === Ada ===
| |
| Guidelines for Ada packages: [[Packaging:Ada]]
| |
| | |
| {{Anchor|DGuidelines}}
| |
| === D ===
| |
| Guidelines for D packages: [[Packaging:D]]
| |
| | |
| === Drupal 7 ===
| |
| Guidelines for Drupal7 packages [[Packaging:Drupal7]]
| |
| | |
| {{Anchor|EclipseGuidelines}}
| |
| | |
| === Eclipse ===
| |
| Guidelines for Eclipse plugin packages: [[Packaging:EclipsePlugins]]
| |
| | |
| {{Anchor|EmacsGuidelines}}
| |
| === Emacs ===
| |
| Guidelines for Emacs/X-Emacs packages: [[Packaging:Emacs]]
| |
| | |
| {{Anchor|FontGuidelines}}
| |
| === Fonts ===
| |
| Guidelines for font packages: [[Packaging:FontsPolicy]]
| |
| | |
| {{Anchor|FortranGuidelines}}
| |
| === Fortran ===
| |
| Guidelines for Fortran packages: [[Packaging:Fortran]]
| |
| | |
| {{Anchor|GlobusGuidelines}}
| |
| | |
| === Globus Toolkit ===
| |
| Guidelines for packaging pieces of the Globus Toolkit [[Packaging:Globus]]
| |
| | |
| {{Anchor|HaskellGuidelines}}
| |
| === Haskell ===
| |
| Guidelines for Haskell packages: [[Packaging:Haskell]]
| |
| | |
| {{Anchor|JavaGuidelines}}
| |
| === Java ===
| |
| Guidelines for java packages: [[Packaging:Java]]
| |
| | |
| === JavaScript ===
| |
| Guidelines for browser javascript packages: [[Packaging:JavaScript]]
| |
| | |
| {{Anchor|LibreOfficeGuidelines}}
| |
| === LibreOffice ===
| |
| Guidelines for LibreOffice extension packages: [[Packaging:LibreOfficeExtensions]]
| |
| | |
| {{Anchor|LispGuidelines}}
| |
| | |
| === Lisp ===
| |
| Guidelines for lisp packages: [[Packaging:Lisp]]
| |
| | |
| {{Anchor|MonoGuidelines}}
| |
| === Mono ===
| |
| Guidelines for Mono packages: [[Packaging:Mono]]
| |
| | |
| {{Anchor|MPIGuidelines}}
| |
| === MPI ===
| |
| Guidelines for MPI packages: [[Packaging:MPI]]
| |
| | |
| === Node.js ===
| |
| Guidelines for Node.js packages: [[Packaging:Node.js]]
| |
| | |
| | |
| {{Anchor|OCamlGuidelines}}
| |
| | |
| === OCaml ===
| |
| Guidelines for OCaml packages: [[Packaging:OCaml]]
| |
| | |
| {{Anchor|OctaveGuidelines}}
| |
| === Octave ===
| |
| Guidelines for Octave packages: [[Packaging:Octave]]
| |
| | |
| {{Anchor|PerlGuidelines}}
| |
| === Perl ===
| |
| Guidelines for Perl packages: [[Packaging:Perl]]
| |
| | |
| {{Anchor|PHPGuidelines}}
| |
| === PHP ===
| |
| Guidelines for PHP packages: [[Packaging:PHP]]
| |
| | |
| {{Anchor|PythonGuidelines}}
| |
| === Python ===
| |
| Guidelines for Python addon modules: [[Packaging:Python]]
| |
| | |
| {{Anchor|RGuidelines}}
| |
| === R ===
| |
| Guidelines for R module packages: [[Packaging:R]]
| |
| | |
| {{Anchor|RubyGuidelines}}
| |
| === Ruby ===
| |
| Guidelines for Ruby packages: [[Packaging:Ruby]]
| |
| | |
| {{Anchor|SugarGuidelines}}
| |
| === Sugar ===
| |
| Guidelines for Sugar Activity packages: [[Packaging:SugarActivityGuidelines]]
| |
| | |
| {{Anchor|TclGuidelines}}
| |
| === Tcl/Tk ===
| |
| Guidelines for Tcl/Tk extension packages: [[Packaging:Tcl]]
| |
| {{Anchor|TclGuidelines}}
| |
| | |
| === Web Assets ===
| |
| Guidelines for shared web assets (css libraries, shared images, etc): [[Packaging:Web Assets]]
| |
| | |
| === Wordpress ===
| |
| Guidelines for Wordpress extension packages: [[Packaging:WordPress plugin packaging guidelines]]
| |
| | |
| [[Category:Packaging guidelines]]
| |