From Fedora Project Wiki

(Replace with a deprecation notice and a link to docs.fp.o)
Tag: Replaced
 
(141 intermediate revisions by 47 users not shown)
Line 1: Line 1:
 
{{autolang|base=yes}}
 
{{autolang|base=yes}}
  
== Introduction ==
+
{{admon/important|deprecated|As part of documentation move to docs.fp.o, this page has moved to https://docs.fedoraproject.org/en-US/quick-docs/creating-rpm-packages}}
 
 
This page describes in detail how to create an RPM package, and in particular, how to create a SPEC file. Unlike other RPM guides, this page explains the specifics for Fedora with links to Fedora-specific guidelines. Since it is maintained through the Fedora Wiki, it is likely to be more up-to-date than other guides. Despite the focus on Fedora, most of this document does apply to other RPM-based distributions. If you're impatient, you might start by looking at the shorter [[How to create a GNU Hello RPM package]].
 
 
 
Please note that these are ''not'' the official package guidelines for Fedora, which can be viewed in the [[Packaging:Guidelines|Packaging Guidelines]] and [[Packaging:NamingGuidelines|Package Naming Guidelines]]. Having said that, this page should be compatible with them.
 
 
 
If you plan to create an RPM package for the Fedora repository, follow the procedure for [[Join the package collection maintainers|joining the package collection maintainers]].
 
 
 
== Preparing your system ==
 
 
 
Before you create RPM packages on Fedora, you need to install some core development tools and set up the account(s) you will use:
 
# yum install @development-tools
 
# yum install fedora-packager
 
 
 
You can create a dummy user specifically for creating RPM packages so that a build process gone wrong can't trash your files or send your private keys to the world.
 
 
 
{{admon/caution|You should ''never'' create your packages as the root user.}}
 
 
 
Create a new user named <code>makerpm</code>, set a password and login as that user:
 
# /usr/sbin/useradd makerpm
 
# passwd makerpm
 
 
 
Once you're logged in as the build/dummy user, create the required directory structure in your home directory by executing:
 
$ rpmdev-setuptree
 
 
 
The <code>rpmdev-setuptree</code> program will create the <code>~/rpmbuild</code> directory and a set of subdirectories (e.g. <code>SPECS</code> and <code>BUILD</code>), which you will use for creating your packages. The <code>~/.rpmmacros</code> file is also created, which can be used for setting various options.
 
 
 
[[Packaging:Guidelines#Timestamps|The packaging guidelines recommend preserving file timestamps]]; you can make this automatic if you use <code>wget</code> or <code>curl</code> to get the source files. If you use <code>wget</code> to get source files, add the text "<code>timestamping = on</code>" to <code>~/.wgetrc</code>.  If you use <code>curl</code>, add the text "<code>-R</code>" to <code>~/.curlrc</code>.
 
 
 
You won't normally need to do these steps again.
 
 
 
== The basics of building RPM packages ==
 
 
 
To create an RPM package, you will need to create a "<code>.spec</code>" text file that provides information about the software being packaged.  You then run the <code>rpmbuild</code> command on the SPEC file, which will go through a series of steps to produce your packages.
 
 
 
Normally, you should place your original (pristine) sources, such as <code>.tar.gz</code> files from the original developers, into the <code>~/rpmbuild/SOURCES</code> directory.  Place your <code>.spec</code> file in the <code>~/rpmbuild/SPECS</code> directory and name it "''NAME''.spec", where ''NAME'' is the base name of the package.  To create both binary and source packages, change directory to <code>~/rpmbuild/SPECS</code> and run:
 
$ rpmbuild -ba ''NAME''.spec
 
 
 
When invoked this way, <code>rpmbuild</code> will read the <code>.spec</code> file and go through in order the stages listed below. Names beginning with <code>%</code> are predefined macros (see the next table down).
 
 
 
{|border="1" cellspacing="0"
 
! Stage !! Reads !! Writes !! Action
 
|-
 
|<code>%prep</code>||<code>%_sourcedir</code>||<code>%_builddir</code>||This reads the sources and patches in the source directory <code>%_sourcedir</code>.  It unpackages the sources to a subdirectory underneath the build directory <code>%_builddir</code> and applies the patches.
 
|-
 
|<code>%build</code>||<code>%_builddir</code>||<code>%_builddir</code>||This compiles the files underneath the build directory <code>%_builddir</code>.  This is often implemented by running some variation of "<code>./configure && make</code>".
 
|-
 
|<code>%check</code>||<code>%_builddir</code>||<code>%_builddir</code>||Check that the software works properly.  This is often implemented by running some variation of "<code>make test</code>".  Many packages don't implement this stage.
 
|-
 
|<code>%install</code>||<code>%_builddir</code>||<code>%_buildrootdir</code>||This reads the files underneath the build directory <code>%_builddir</code> and writes to a directory underneath the build root directory <code>%_buildrootdir</code>. The files that are written are the files that are supposed to be installed when the binary package is installed by an end-user.  Beware of the weird terminology: The ''build root directory'' is '''not''' the same as the ''build directory''.  This is often implemented by running "<code>make install</code>".
 
|-
 
|<code>bin</code>||<code>%_buildrootdir</code>||<code>%_rpmdir</code>||This reads the files underneath the build root directory <code>%_buildrootdir</code> to create binary RPM packages underneath the RPM directory <code>%_rpmdir</code>.  Inside the RPM directory is a directory for each architecture, and a "<code>noarch</code>" directory for packages that apply to any architecture.  These RPM files are the packages for users to install.
 
|-
 
|<code>src</code>||<code>%_sourcedir</code>||<code>%_srcrpmdir</code>||This creates a source RPM package (<code>.src.rpm</code>) inside the source RPM directory <code>%_srcrpmdir</code>.  These files are needed for reviewing and updating packages.
 
|}
 
 
 
<!-- Note: The words "in" and "underneath" in the table above have different meanings.  Given file /a/b/c, c is "underneath" but not "in" a. -->
 
 
 
As you can tell, certain directories have certain purposes in <code>rpmbuild</code>.  These are:
 
{|border="1" cellspacing="0"
 
! Macro Name !! Name !! Usually !! Purpose
 
|-
 
|<code>%_specdir</code>||Specification directory||<code>~/rpmbuild/SPECS</code>||RPM specifications (<code>.spec</code>) files
 
|-
 
|<code>%_sourcedir</code>||Source directory||<code>~/rpmbuild/SOURCES</code>||Pristine source package (e.g. tarballs) and patches
 
|-
 
|<code>%_builddir</code>||Build directory||<code>~/rpmbuild/BUILD</code>||Source files are unpacked and compiled in a subdirectory underneath this.
 
|-
 
|<code>%_buildrootdir</code>||Build root directory||<code>~/rpmbuild/BUILDROOT</code>||Files are installed under here during the <code>%install</code> stage.
 
|-
 
|<code>%_rpmdir</code>||Binary RPM directory||<code>~/rpmbuild/RPMS</code>||Binary RPMs are created and stored under here.
 
|-
 
|<code>%_srcrpmdir</code>||Source RPM directory||<code>~/rpmbuild/SRPMS</code>||Source RPMs are created and stored here.
 
|}
 
 
 
If a stage fails, look at the output to see ''why'' it falied and change the <code>.spec</code> file (or other input) as needed.
 
 
 
== Getting ready to package a particular program ==
 
 
 
If there are special programs that are required to build or run the program you are packaging, install those other programs and write down what they are.
 
 
 
To package a program for the Fedora repository, you must package pristine (original) sources, along with the patches and build instructions;
 
it's '''not''' okay to start with pre-compiled code. Install the file with the original source (usually a <code>.tar.gz</code> file) in the
 
<code>~/rpmbuild/SOURCES</code> directory (of the RPM building user account).
 
 
 
Read through the manual installation instructions for your program. It's often a good idea to do a "dry run" by manually building the program before attempting to do so via RPM. With a few exceptions, all binaries and libraries included in Fedora packages must be built from the source code that is included in the source package.
 
 
 
=== Split up the program ===
 
 
 
Application source code is often released with the source code of other external libraries "bundled" into them. [[Packaging:No_Bundled_Libraries|Do not bundle external libraries with the main application into a single package]]. Instead, split them up into separate packages.
 
 
 
=== Licensing ===
 
 
 
Only package software that is legal for you to package. See [[Packaging/Guidelines#Legal]], [[Licensing:Main]] and [[Packaging:LicensingGuidelines]]. In general, only package software that is released as open source software (OSS) using an approved OSS license (such as the GPL, LGPL, BSD-new, MIT/X, or Apache 2.0 licenses). Check to make sure that the software really is licensed this way (e.g. spot-check source code headers, README files etc.). If there are bundled libraries, make sure they are also OSS.
 
 
 
=== Reuse existing package information ===
 
 
 
Try to reuse what you can. Obviously, make sure you aren't packaging something that is already packaged. You can find a list of existing packages in Fedora Package Collection in the [https://admin.fedoraproject.org/pkgdb/ Fedora Package Database]. Also check the [[PackageMaintainers/InProgressReviewRequests|In Progress Review Requests]] and the [[PackageMaintainers/RetiredPackages|Retired Packages]] list. You can use [http://pkgs.fedoraproject.org/gitweb/ Fedora Packages Git Repositories] directly to view SPEC files (and patches). You can download the SRPMS using a program from the <code>yum-utils</code> package:
 
$ yum -y install yum-utils
 
$ yumdownloader --source sourcepackage-name
 
 
 
Alternatively, get the source manually from the http/ftp page of a [http://mirrors.fedoraproject.org/publiclist Fedora mirror] within the <code>releases/{{FedoraVersion}}/Everything/source/SRPMS</code> directory. Replace "<code>{{FedoraVersion}}</code>" with the Fedora release you want and download the <code>.src.rpm</code> package you want.
 
 
 
Once you have the SRPM, install it into <code>~/rpmbuild</code>:
 
$ rpm -ivh sourcepackage-name*.src.rpm
 
 
 
You can also unpack the SRPM into a directory using <code>rpm2cpio</code>:
 
$ mkdir PROGRAMNAME_src_rpm
 
$ cd PROGRAMNAME_src_rpm
 
$ rpm2cpio ../PROGRAMNAME-*.src.rpm | cpio -i
 
 
 
Sometimes it's easiest to start with an existing package and then clean it up for Fedora. [http://rpmfind.net/ RPM Find] may help you find RPMs for non-Fedora systems. You can install SRPMS for other systems the same way as for Fedora. Failing that, you might look at the source package files (not binary <code>.deb</code>) for [http://packages.ubuntu.com/ Ubuntu] or [http://www.debian.org/distrib/packages Debian] (source package files are standard tarballs with a "<code>debian/</code>" subdirectory). If the [http://www.freebsd.org/ports/installing.html FreeBSD ports collection] has it, you could [ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz download the FreeBSD ports tarball] and see if their packaging information helps as a starting point. However, this is sometimes not helpful at all. Different distributions have different rules, and what they do may be quite inappropriate for Fedora.
 
 
 
== Creating a SPEC file ==
 
 
 
You now need to create a SPEC file in the <code>~/rpmbuild/SPECS</code> directory. You should name it after the program name (e.g. "<code>program.spec</code>").  Use the archive name or the name advocated by the software author where you can, but be sure to follow the [[Packaging/NamingGuidelines|Package Naming Guidelines]].
 
 
 
=== SPEC templates ===
 
 
 
When you're creating a SPEC file for the first time, vim or emacs will automatically create a template for you:
 
  $ cd ~/rpmbuild/SPECS
 
  $ vim program.spec
 
 
 
Here's an example of what that template will look like ('''Note:''' the provided template may not necessarily comply with Fedora Packaging Guidelines):
 
Name:
 
Version:
 
Release: 1%{?dist}
 
Summary:
 
Group:
 
License:
 
URL:
 
Source0:
 
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 
BuildRequires:
 
Requires:
 
 
%description
 
 
%prep
 
%setup -q
 
 
%build
 
%configure
 
make %{?_smp_mflags}
 
 
%install
 
rm -rf %{buildroot}
 
make install DESTDIR=%{buildroot}
 
 
%clean
 
rm -rf %{buildroot}
 
 
%files
 
%defattr(-,root,root,-)
 
%doc
 
 
%changelog
 
 
 
 
 
You can use <code>$RPM_BUILD_ROOT</code> instead of <code>%{buildroot}</code>. Both are acceptable, but just be consistent.
 
 
 
You may also use the <code>rpmdev-newspec</code> command to create a SPEC file for you.  <code>rpmdev-newspec NAME-OF-NEW-PACKAGE</code> can create an initial SPEC file for a new package, tailored to various types of packages.  It will guess what kind of template to use based on the package name, or you can specify a particular template. See <code>/etc/rpmdevtools/spectemplate-*.spec</code> for available templates, and see <code>rpmdev-newspec --help</code> for more information. For example, to create a new SPEC file for a python module:
 
 
 
cd ~/rpmbuild/SPECS
 
rpmdev-newspec python-antigravity
 
vi python-antigravity.spec
 
 
 
=== SPEC example ===
 
 
 
Here's a simple example showing a Fedora 16 SPEC file for the <code>eject</code> program:
 
 
 
<pre>
 
Summary:            A program that ejects removable media using software control
 
Name:              eject
 
Version:            2.1.5
 
Release:            21%{?dist}
 
License:            GPLv2+
 
Group:              System Environment/Base
 
Source:            %{name}-%{version}.tar.gz
 
Patch1:            eject-2.1.1-verbose.patch
 
Patch2:            eject-timeout.patch
 
Patch3:            eject-2.1.5-opendevice.patch
 
Patch4:            eject-2.1.5-spaces.patch
 
Patch5:            eject-2.1.5-lock.patch
 
Patch6:            eject-2.1.5-umount.patch
 
URL:                http://www.pobox.com/~tranter
 
ExcludeArch:        s390 s390x
 
BuildRequires:      gettext
 
BuildRequires:      libtool
 
 
 
%description
 
The eject program allows the user to eject removable media (typically
 
CD-ROMs, floppy disks or Iomega Jaz or Zip disks) using software
 
control. Eject can also control some multi-disk CD changers and even
 
some devices' auto-eject features.
 
 
 
Install eject if you'd like to eject removable media using software
 
control.
 
 
 
%prep
 
%setup -q -n %{name}
 
%patch1 -p1
 
%patch2 -p1
 
%patch3 -p1
 
%patch4 -p1
 
%patch5 -p1
 
%patch6 -p1
 
 
 
%build
 
%configure
 
make %{?_smp_mflags}
 
 
 
%install
 
make DESTDIR=%{buildroot} install
 
 
 
install -m 755 -d %{buildroot}/%{_sbindir}
 
ln -s ../bin/eject %{buildroot}/%{_sbindir}
 
 
 
%find_lang %{name}
 
 
 
%files -f %{name}.lang
 
%doc README TODO COPYING ChangeLog
 
%{_bindir}/*
 
%{_sbindir}/*
 
%{_mandir}/man1/*
 
 
 
%changelog
 
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.5-21
 
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
 
 
 
* Fri Jul 02 2010 Kamil Dudka <kdudka@redhat.com> 2.1.5-20
 
- handle multi-partition devices with spaces in mount points properly (#608502)
 
</pre>
 
 
 
{{Anchor|Spec_file_pieces_explained}}
 
== SPEC file overview ==
 
 
 
Other useful guides:
 
* [http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html RPM Guide] describes how to write a SPEC file.
 
* The IBM series "Packaging software with RPM" [http://www.ibm.com/developerworks/library/l-rpm1/ Part 1], [http://www.ibm.com/developerworks/library/l-rpm2/ Part 2], and [http://www.ibm.com/developerworks/library/l-rpm3.html Part 3].
 
* [http://rpm.org/max-rpm-snapshot/ Maximum RPM] has the most complete information, but is dated.
 
 
 
You will need to follow the Fedora guidelines: [[Packaging/NamingGuidelines|Package Naming Guidelines]], [[Packaging/Guidelines|Packaging guidelines]], and [[Packaging/ReviewGuidelines|Package review guidelines]].
 
 
 
Insert comments with a leading "<code>#</code>" character, but avoid macros (beginning with <code>%</code>) that are potentially multiline (as they are expanded first). If commenting out a line, double the percent signs (<code>%%</code>). Also avoid inline comments on the same line as a script command.
 
 
 
The major tags are listed below. Note that the macros <code>%{name}</code>, <code>%{version}</code> and <code>%{release}</code> can be used to refer to the Name, Version and Release tags respectively. When you change the tag, the macros automatically update to use the new value.
 
* '''Name''': The (base) name of the package, which should match the SPEC file name.  It must follow the [[Packaging/NamingGuidelines|Package Naming Guidelines]] and generally be lowercase.
 
* '''Version''': The upstream version number. See [[Packaging/NamingGuidelines#Version_Tag|Version tag section]] of the packaging guidelines. If the version contains tags that are non-numeric (contains tags that are not numbers), you may need to include the additional non-numeric characters in the Release tag. If upstream uses full dates to distinguish versions, consider using version numbers of the form <code>yy.mm[dd]</code> (e.g. <code>2008-05-01</code> becomes <code>8.05</code>).
 
* '''Release''': The initial value should normally be <code>1%{?dist}</code>. Increment the number every time you release a new package for the same version of software. When a new upstream version is released, change the Version tag to match and reset the Release number to <code>1</code>. See [[Packaging/NamingGuidelines#Release_Tag|Release tag section]] of the packaging guidelines. The optional [[Packaging/DistTag|Dist tag]] might be useful.
 
* '''Summary''': A brief, one-line summary of the package. Use American English. Do '''not''' end in a period.
 
* '''Group''': This needs to be a pre-existing group, like "Applications/Engineering"; run "<code>less /usr/share/doc/rpm-*/GROUPS</code>" to see the complete list. Use the group "Documentation" for any sub-packages (e.g. <code>kernel-doc</code>) containing documentation.
 
* '''License''': The license, which must be an open source software license. Do ''not'' use the old Copyright tag. Use a standard abbreviation (e.g. "<code>GPLv2+</code>") and be specific (e.g. use "<code>GPLv2+</code>" for GPL version 2 or greater instead of just "<code>GPL</code>" or "<code>GPLv2</code>" where it's true).  See [[Licensing]] and the [[Packaging/LicensingGuidelines|Licensing Guidelines]]. You can list multiple licenses by combining them with "<code>and</code>" and "<code>or</code>" (e.g. "<code>GPLv2 and BSD</code>").
 
* '''URL''': The full URL for more information about the program (e.g. the project website).  '''''Note: This is not where the original source code came from which is meant for the Source0 tag below'''''.
 
* '''Source0''': The full URL for the compressed archive containing the (original) pristine source code, as upstream released it. "<code>Source</code>" is synonymous with "<code>Source0</code>".  If you give a full URL (and you should), its basename will be used when looking in the <code>SOURCES</code> directory. If possible, embed <code>%{name}</code> and <code>%{version}</code>, so that changes to either will go to the right place. [[Packaging:Guidelines#Timestamps|Preserve timestamps]] when downloading source files. If there is more than one source, name them <code>Source1</code>, <code>Source2</code> and so on. If you're adding whole new files in addition to the pristine sources, list them as sources ''after'' the pristine sources. A copy of each of these sources will be included in any SRPM you create, unless you specifically direct otherwise.  See [[Packaging/SourceURL|Source URL]] for more information on special cases (e.g. revision control).
 
* '''Patch0''': The name of the first patch to apply to the source code.  If you need to patch the files after they've been uncompressed, you should edit the files and save their differences as a "patch" file in your <code>~/rpmbuild/SOURCES</code> directory. Patches should make only one logical change each, so it's quite possible to have multiple patch files.
 
* '''BuildArch''': If you're packaging files that are architecture-independent (e.g. shell scripts, data files), then add "<code>BuildArch: noarch</code>". The architecture for the binary RPM will then be "<code>noarch</code>".
 
* '''BuildRoot''': This is where files will be "installed" during the %install process (after the %build process). This is now redundant in Fedora and is only needed for EPEL5. By default, the build root is placed in "<code>%{_topdir}/BUILDROOT/</code>".
 
* '''BuildRequires''': A comma-separated list of packages required for building (compiling) the program. This field can be (and is commonly) repeated on multiple lines. These dependencies are ''not'' automatically determined, so you need to include ''everything'' needed to build the program. [[Packaging/Guidelines#BuildRequires|Some common packages can be omitted]], such as <code>gcc</code>. You can specify a minimum version if necessary (e.g. "<code>ocaml >= 3.08</code>"). If you need the file <code>/EGGS</code>, determine the package that owns it by running "<code>rpm -qf /EGGS</code>". If you need the program <code>EGGS</code>, determine the package that owns it by running "<code>rpm -qf `which EGGS`</code>". Keep dependencies to a minimum (e.g. use <code>sed</code> instead of <code>perl</code> if you don't really need perl's abilities), but beware that some applications permanently disable functions if the associated dependency is not present; in those cases you may need to include the additional packages. The "<code>auto-br-rpmbuild</code>" command may be helpful.
 
* '''Requires''': A comma-separate list of packages that are required when the program is installed. Note that the BuildRequires tag lists what is required to build the binary RPM, while the Requires tag lists what is required when installing/running the program; a package may be in one list or in both. In many cases, <code>rpmbuild</code> automatically detects dependencies so the Requires tag is not always necessary. However, you may wish to highlight some specific packages as being required, or they may not be automatically detected.
 
* '''%description''': A longer, multi-line description of the program.  Use American English. All lines must be 80 characters or less. Blank lines indicate a new paragraph. Some graphical user interface installation programs will reformat paragraphs; lines that start with whitespace will be treated as preformatted text and displayed as is, normally with a fixed-width font. See [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch09s03.html RPM Guide].
 
* '''%prep''': Script commands to "prepare" the program (e.g. to uncompress it) so that it will be ready for building.  Typically this is just "<code>%setup -q</code>"; a common variation is "<code>%setup -q -n NAME</code>" if the source file unpacks into <code>NAME</code>. See the %prep section below for more.
 
* '''%build''': Script commands to "build" the program (e.g. to compile it) and get it ready for installing. The program should come with instructions on how to do this.  See the %build section below for more.
 
* '''%check''': Script commands to "test" the program. This is run between the %build and %install procedures, so place it there if you have this section. Often it simply contains "<code>make test</code>" or "<code>make check</code>". This is separated from %build so that people can skip the self-test if they desire.
 
* '''%install''': Script commands to "install" the program.  The commands should copy the files from the <code>BUILD</code> directory <code>%{_builddir}</code> into the buildroot directory, <code>%{buildroot}</code>. See the %install section below for more.
 
* '''%clean''': Instructions to clean out the build root. Note that this section is now redundant in Fedora and is only necessary for EPEL. Typically this contains only:
 
rm -rf %{buildroot}
 
* '''%files''': The list of files that will be installed. See the %files section below for more.
 
* '''%changelog''': Changes in the package.  Use the format example above.
 
* '''ExcludeArch''': If the package does not successfully compile, build or work on a particular architecture, list those architectures under this tag.
 
* You can add sections so that code will run when packages are installed or removed on the real system (as opposed to just running the %install script, which only does a pseudo-install to the build root).  These are called "scriptlets", and they are usually used to update the running system with information from the package.  See the "Scriptlets" section below for more.
 
 
 
RPM also supports the creation of several packages (called [[How_to_create_an_RPM_package#Subpackages|subpackages]]) from a single SPEC file, such as <code>name-libs</code> and <code>name-devel</code> packages.
 
 
 
Do '''not''' use these tags:
 
* Packager
 
* Vendor
 
* Copyright
 
 
 
Do '''not''' create a "relocatable" package; they don't add value in Fedora and make things more complicated.
 
 
 
== SPEC file sections explained ==
 
 
 
=== %prep section ===
 
 
 
The %prep section describes how to unpack the compressed packages so that they can be built. Typically, this includes the "<code>%setup</code>" and "<code>%patch</code>" commands with reference to the Source0 (and Source1 etc.) lines. See the [http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html Maximum RPM section on %setup and %patch] for more details.
 
 
 
The %{patches} and %{sources} macros are available since RPM 4.4.2 and are useful if you have a large list of patches or sources:
 
for p in %{patches}; do
 
    ...
 
done
 
 
 
However, keep in mind that using these will make your SPEC incompatible with RPMS used in RHEL and other RPM-based dirstributions.
 
 
 
==== %prep section: %setup command ====
 
 
 
The "<code>%setup</code>" command unpacks a source package. Switches include:
 
* '''<code>-q</code>''' : Suppress unecessary output. This is commonly used.
 
* '''<code>-n</code> ''name''''' : If the Source tarball unpacks into a directory whose name is not the RPM name, this switch can be used to specify the correct directory name. For example, if the tarball unpacks into the directory FOO, use "</code>%setup -q -n FOO</code>".
 
* '''<code>-c</code> ''name''''' : If the Source tarball unpacks into multiple directories instead of a single directory, this switch can be used to create a directory named ''name'' and then unpack into it.
 
 
 
There are [http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html more %spec options if you are unpacking multiple files], which is primarily useful if you
 
are creating subpackages (see below).  The key ones are:
 
 
 
{|
 
|-
 
| <code>-a number</code> || Only unpack the Source directive of the given number after changing directory (e.g. "<code>–a 0</code>" for Source0).
 
|-
 
| <code>-b number</code> ||  Only unpack the Source directive of the given number before changing directory (e.g. "<code>–b 0</code>" for Source0).
 
|-
 
| <code>-D</code> || Do not delete the directory before unpacking.
 
|-
 
| <code>-T</code> || Disable the automatic unpacking of the archives.
 
|}
 
 
 
==== %prep section: %patch commands ====
 
 
 
The "<code>%patch0</code>" command applies Patch0 (and %patch1 applies Patch1 etc.). Patches are the normal method of making necessary changes to the source code for packaging. The usual "<code>-pNUMBER</code>" option applies, which passes that argument onto the program <code>patch</code>.
 
 
 
Patch file names often look like "<code>telnet-0.17-env.patch</code>", which is the format <code>%{name} - %{version} - REASON.patch</code>" (though sometimes version is omitted). Patch files are typically the result of "<code>diff -u</code>"; if you do this from the subdirectory of <code>~/rpmbuild/BUILD</code> then you won't have to specify a <code>-p</code> level later.
 
 
 
This is a typical procedure for creating a patch for a single file:
 
cp foo/bar foo/bar.orig
 
vim foo/bar
 
diff -u foo/bar.orig foo/bar > ~/rpmbuild/SOURCES/PKGNAME.REASON.patch
 
 
 
If editing many files, one easy method is to copy the whole subdirectory underneath <code>BUILD</code> and then do subdirectory diffs.  After you have changed directory to "<code>~rpmbuild/BUILD/NAME</code>", do the following:
 
cp -pr ./ ../PACKAGENAME.orig/
 
... many edits ...
 
diff -u ../PACKAGENAME.orig . > ~/rpmbuild/SOURCES/''NAME''.''REASON''.patch
 
 
 
If you edit many files in one patch, you can also copy the original files using some consistent ending such as "<code>.orig</code>" before editing them. Then, you can use "<code>gendiff</code>" (in the <code>rpm-build</code> package) to create a patch with the differences.
 
 
 
Try to ensure that your patch match the context exactly. The default "fuzz" value is "<code>0</code>", requiring matches to be exact. You can work around this by adding "<code>%global _default_patch_fuzz 2</code>" to revert to the value found in older versions of RPM in Fedora, but it is generally recommended to avoid doing this.
 
 
 
As explained in [[Packaging/PatchUpstreamStatus]], all patches should have a comment above them in the SPEC file about their upstream status. This should document the upstream bug/email that includes it (including the date). If it is unique to Fedora, you should mention why it is unique. The Fedora Project tries not to deviate from upstream; see [[PackageMaintainers/WhyUpstream]] for the importance of this.
 
 
 
==== %prep section: Unmodified files ====
 
 
 
Sometimes, one or more of the Source files do not need to be uncompressed. You can "prep" those into the build directory like this (where <code>SOURCE1</code> refers to the relevant Source file):
 
cp -p %SOURCE1 .
 
 
 
=== %build section ===
 
 
 
The "%build" section is sometimes complicated; here you configure and compile/build the files to be installed.
 
 
 
Many programs follow the GNU <code>configure</code> approach (or some variation). By default, they will install to a prefix of "<code>/usr/local</code>", which is reasonable for unpackaged files. However, since you are packaging it, change the prefix to "<code>/usr</code>". Libraries should be installed to either <code>/usr/lib</code> or <code>/usr/lib64</code> depending on the architecture.
 
 
 
Since GNU <code>configure</code> is so common, the macro "<code>%configure</code>" can be used to automatically invoke the correct options (e.g. change the prefix to <code>/usr</code>). Some variation of this often works:
 
  %configure
 
  make %{?_smp_mflags}
 
 
 
To override makefile variables, pass them as parameters to <code>make</code>:
 
make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}
 
 
 
More more information, see [http://sourceware.org/autobook/ "GNU autoconf, automake, and libtool"] and [http://www.suse.de/~sh/automake/automake.pdf "Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer].
 
 
 
Some programs use <code>cmake</code>.  See [[Packaging/cmake]].
 
 
 
=== %check section ===
 
 
 
If self-tests are available, it is generally a good idea to include them. They should be placed in the %check section (which immediately follows the %build section) instead of within the %build section itself, so that they can be easily skipped when necessary.
 
 
 
Often, this section contains:
 
make test
 
 
 
=== %install section ===
 
 
 
This section involves script commands to "install" the program, copying the relevant files from <code>%{_builddir}</code> to <code>%{buildroot}</code> (which usually means from <code>~/rpmbuild/BUILD</code> to <code>~/rpmbuild/BUILDROOT</code>) and creating directories inside <code>%{buildroot}</code> as necessary.
 
 
 
Some of the terminology can be misleading:
 
* The "build directory", also known as <code>%{_builddir}</code> is not the same as the "build root", also known as <code>%{buildroot}</code>. Compilation occurs in the former directory, while files to be packaged are copied from the former to the latter.
 
* During the %build section, the current directory will start at <code>%{buildsubdir}</code>, which is the subdirectory within <code>%{_builddir}</code> that was created during %prep stage. This is usually something like <code>~/rpmbuild/BUILD/%{name}-%{version}</code>.
 
* The %install section is '''not''' run when the binary RPM package is installed by the end-user, but is only run when creating a package.
 
 
 
Normally, some variation of "<code>make install</code>" is performed here:
 
%install
 
rm -rf %{buildroot}
 
make DESTDIR=%{buildroot} install
 
 
 
Removal of <code>%{buildroot}</code> is no longer necessary, except for EPEL 5.
 
 
 
Ideally you should use [http://www.gnu.org/prep/standards/html_node/DESTDIR.html <code>DESTDIR=%{buildroot}</code>] if the program supports it, as it redirects file installations to the specified directory and is exactly what we want to happen during the %install section.
 
 
 
If the program does not support <code>DESTDIR</code> (and only if), you can workaround it in one of several (inferior) ways:
 
* Patch the makefile so that is supports <code>DESTDIR</code>. Create directories inside <code>DESTDIR</code> where necessary and submit the patch upstream.
 
* Use the "<code>%makeinstall</code>" macro. This method might work, but can lead to subtle failures. It expands to something like "<code>make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install</code>", which can result in some programs failing to work properly. Create directories inside <code>%{buildroot}</code> where necessary.
 
* Consider using the <code>auto-destdir</code> package. This requires "<code>BuildRequires: auto-destdir</code>", and changing "<code>make install</code>" to "<code>make-redir DESTDIR=%{buildroot} install</code>". This only works well if the installation uses only certain common commands to install files, like <code>cp</code> and <code>install</code>.
 
* Perform the installation by hand. This would involve creating the necessary directories under <code>%{buildroot}</code> and copying files from <code>%{_builddir}</code> to <code>%{buildroot}</code>. Be especially careful with updates, which often contain new or changed filenames. An example of this procedure:
 
%install
 
rm -rf %{buildroot}
 
mkdir -p %{buildroot}%{_bindir}/
 
cp -p mycommand %{buildroot}%{_bindir}/
 
 
 
As noted in [[Packaging:Guidelines#Timestamps]], try to preserve timestamps if the makefile lets you override commands:
 
make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install
 
 
 
=== %files section ===
 
This section declares which files and directories are owned by the package, and thus which files and directories will be placed into the binary RPM.
 
 
 
==== %files basics ====
 
 
 
The <code>%defattr</code> set the default file permissions, and is often found at the start of the <code>%files</code> section. Note that this is no longer necessary unless the permissions need to be altered. The format of this is:
 
%defattr(<file permissions>, <user>, <group>, <directory permissions>)
 
The fourth parameter is often omitted. Usually one uses <code>%defattr(-,root,root,-)</code>, where "<code>-</code>" uses the default permissions.
 
 
 
You should then list all the files and directories to be owned by the package. Use macros for directory names where possible, which can be viewed at [[Packaging:RPMMacros]] (e.g. use <code>%{_bindir}/mycommand</code> instead of <code>/usr/bin/mycommand</code>). If the pattern begins with a "<code>/</code>" (or when expanded from the macro) then it is taken from the <code>%{buildroot}</code> directory. Otherwise, the file is presumed to be in the current directory (e.g. inside <code>%{_builddir}</code> (such as documentation files that you wish to include). If your package only installs a single file <code>/usr/sbin/mycommand</code>, then the <code>%files</code> section can simply be:
 
%files
 
%{_sbindir}/mycommand
 
 
 
To make your package less sensitive to upstream changes, declare all files within a directory to be owned by the package with a pattern match:
 
%{_bindir}/*
 
 
 
To include a single directory:
 
%{_datadir}/%{name}/
 
 
 
Note that <code>%{_bindir}/*</code> does not claim that this package owns the <code>/usr/bin</code> directory, but only the files contained within. If you list a directory, then you are claiming that the package owns that directory and all files and subdirectories contained within. Thus, do '''not''' list <code>%{_bindir}</code> and be careful of directories that may be shared with other packages.
 
 
 
An error will occur if:
 
* a pattern match does not match any file or directory
 
* a file or directory is listed or matched more than once
 
* a file or directory in the <code>%{buildroot}</code> has not been listed
 
 
 
It is also possible to exclude files from a previous match by using the <code>%exclude</code> glob. This can be useful for including almost all of the files included by a different pattern match, but note that it will also fail if it does not match anything.
 
 
 
==== %files prefixes ====
 
You may need to add one or more prefixes to lines in the <code>%files</code> section; seperate them with a space. See [http://www.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html Max RPM section on %files directives].
 
 
 
Usually, "<code>%doc</code>" is used to list documentation files within <code>%{_builddir}</code> that were not copied to <code>%{buildroot}</code>. A <code>README</code> and <code>INSTALL</code> file is usually included. They will be placed in the directory <code>/usr/share/doc/%{name}-%{version}</code>, whose ownership does not need to be declared.
 
 
 
'''Note:''' If specifying a <code>%doc</code> entry, then you can't copy files into the documentation directory during the <code>%install</code> section. If, for example, you want an "examples" subdirectory within the documentation directory, don't use <code>%doc</code>, but instead create the directories and copy files over manually into <code>%{buildroot}%{_defaultdocdir}/%{name}-%{version}</code> during the %install section. They will be correctly marked as documentation. Make sure you include <code>%{_defaultdocdir}/%{name}-%{version}/</code> as an entry in the %files section.
 
 
 
Configuration files should be placed in <code>/etc</code> and are normally specified like this (which makes sure user changes aren't overwritten on update):
 
%config(noreplace) %{_sysconfdir}/foo.conf
 
If the update uses a non-backwards-compatible configuration format, then specify them like this:
 
%config %{_sysconfdir}/foo.conf
 
 
 
"<code>%attr(mode, user, group)</code>" can be used for finer control over permissions, where a "<code>-</code>" means use the default:
 
%attr(0644, root, root) FOO.BAR
 
 
 
If a file is in particular natural language, use <code>%lang</code> to note that:
 
%lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh*
 
 
 
Programs using Locale files should follow the [[Packaging:Guidelines#Handling_Locale_Files|recommended method of handling i18n files]]:
 
* find the filenames in the <code>%install</code> step: <code> %find_lang ${name}</code>
 
* add the required build dependencies: <code>BuildRequires: gettext</code>
 
* use the found filenames: <code>%files -f ${name}.lang</code>
 
 
 
These prefixes are '''not''' valid in Fedora: <code>%license</code> and <code>%readme</code>.
 
 
 
==== %files and Filesystem Hierarchy Standard (FHS) ====
 
 
 
You should follow the [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard (FHS)]. Executables go in <code>/usr/bin</code>, global configuration files go in <code>/etc</code>, libraries go into <code>/usr/lib</code> (or <code>/usr/lib64</code>) and so on. There is one exception: executables that should not normally be executed directly by users or administrators should go in a subdirectory of <code>/usr/libexec</code>, which is referred to as <code>%{_libexecdir}/%{name}</code>.
 
 
 
Do '''not''' install files into <code>/opt</code> or <code>/usr/local</code>.
 
 
 
Unfortunately, many programs do not follow the FHS by default. In particular, architecture-independent libraries get placed in <code>/usr/lib</code> instead of <code>/usr/share</code>. The former is for architecture-dependent libraries, while the latter is for architecture-independent libraries, which means that systems with different CPU architectures can share <code>/usr/share</code>. There are many exceptions in Fedora (such as Python and Perl), but Fedora applies this rule more strictly than some distributions. <code>rpmlint</code> will generally complain if you put anything other than ELF files into <code>/usr/lib</code>.
 
 
 
==== %files example ====
 
 
 
Here's a simple example of a %files section:
 
%files
 
%doc README LICENSE
 
%{_bindir}/*
 
%{_sbindir}/*
 
%{_datadir}/%{name}/
 
%config(noreplace) %{_sysconfdir}/*.conf
 
 
 
==== Finding duplicates ====
 
 
 
You can list any duplicates of two binary packages by doing:
 
cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture
 
rpm -qlp PACKAGE1.*.rpm | sort > ,1
 
rpm -qlp PACKAGE2.*.rpm | sort > ,2
 
comm -12 ,1 ,2
 
 
 
=== Scriptlets ===
 
 
 
When an end-user installs the RPM, you may want some commands to be run. This can be achieved through scriptlets. See [[Packaging/ScriptletSnippets]].
 
 
 
Scriptlets can be run:
 
* before ('''<code>%pre</code>''') or after ('''<code>%post</code>''') a package is installed
 
* before ('''<code>%preun</code>''') or after ('''<code>%postun</code>''') a package is uninstalled
 
* at the start ('''<code>%pretrans</code>''') or end ('''<code>%posttrans</code>''') of a transaction
 
 
 
For example, every binary RPM package that stores shared library files in any of the dynamic linker's default paths, must call <code>ldconfig</code> in <code>%post</code> and <code>%postun</code>. If the package has multiple subpackages with libraries, each subpackage should also perform the same actions.
 
%post -p /sbin/ldconfig
 
%postun -p /sbin/ldconfig
 
 
 
If only running a single command, then the "<code>-p</code>" option runs the adjacent command without invoking the shell. However, for several commands, omit this option and include the shell commands beneath.
 
 
 
If you run any programs within the scriptlets, then you must specify any requirements in the form "<code>Requires(CONTEXT)</code>" (e.g. <code>Requires(post)</code>).
 
 
 
<code>%pre</code>, <code>%post</code>, <code>%preun</code>, and <code>%postun</code> provide the argument <code>$1</code>, which is the number of packages of this name which will be left on the system when the action completes. Don't compare for equality with <code>2</code>, but instead check if they are greater than or equal to <code>2</code>. For <code>%pretrans</code> and <code>%posttrans</code>, <code>$1</code> is always <code>0</code>.
 
 
 
For example, if the package installs an info manual, then the info manual index must be updated with <code>install-info</code> from the <code>info</code> package. Firstly, there is no guarantee that the <code>info</code> package will be available unless we explicitly declare it as required, and secondly, we don't want to fail completely if <code>install-info</code> fails:
 
Requires(post): info
 
Requires(preun): info
 
...
 
%post
 
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
 
%preun
 
if [ $1 = 0 ] ; then
 
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
 
fi
 
 
 
There is one other glitch related to installing info manuals. The <code>install-info</code> command will update the info directory, so we should delete the useless empty directory from the %{buildroot} during the <code>%install</code> section:
 
 
rm -f %{buildroot}%{_infodir}/dir
 
 
 
Another scriptlet-like abilility are "triggers", which can be run for your package when other packages are installed or uninstalled. See [http://rpm.org/api/4.4.2.2/triggers.html RPM Triggers].
 
 
 
=== Macros ===
 
 
 
Macros are text in the format <code>%{string}</code>. Typical macros:
 
 
 
{|
 
! Macro !! Typical Expansion !! Meaning
 
|-
 
| <code>%{_bindir}</code> || <code>/usr/bin</code> || Binary directory: where executables are usually stored.
 
|-
 
| <code>%{_builddir}</code> || <code>~/rpmbuild/BUILD</code> || Build directory: files are compiled within a subdirectory of the build directory. See <code>%buildsubdir</code>.
 
|-
 
| <code>%{buildroot}</code> || <code>~/rpmbuild/BUILDROOT</code> || Build root: where files are "installed" during the <code>%install</code> stage, which copies files from a subdirectory of <code>%{_builddir}</code> to a subdirectory of <code>%{buildroot}</code>. (Historically, <code>%{buildroot}</code> was in "/var/tmp/".)
 
|-
 
| <code>%{buildsubdir}</code> || <code>%{_builddir}/%{name}</code> || Build subdirectory: a subdirectory within <code>%{_builddir}</code> where files are compiled during the <code>%build</code> stage. It is set after <code>%setup</code>.
 
|-
 
| <code>%{_datadir}</code> || <code>/usr/share</code> || Share directory.
 
|-
 
| <code>%{_defaultdocdir}</code> || <code>/usr/share/doc</code> || Default documentation directory.
 
|-
 
| <code>%{dist}</code> || <code>.fc''NUMBER''</code> || Distribution+version short name (e.g. "<code>.fc9</code>")
 
|-
 
| <code>%{fedora}</code> || <code>''NUMBER''</code> || Number of fedora release (e.g. "<code>9</code>")
 
|-
 
| <code>%{_includedir}</code> || <code>/usr/include</code>
 
|-
 
| <code>%{_infodir}</code> || <code>/usr/share/info</code>
 
|-
 
| <code>%{_initrddir}</code> || <code>/etc/rc.d/init.d</code>
 
|-
 
| <code>%{_libdir}</code> || <code>/usr/lib</code>
 
|-
 
| <code>%{_libexecdir}</code> || <code>/usr/libexec</code>
 
|-
 
| <code>%{_localstatedir}</code> || <code>/var</code>
 
|-
 
| <code>%{_mandir}</code> || <code>/usr/share/man</code>
 
|-
 
| <code>%{name}</code> || || Name of package, set by Name: tag
 
|-
 
| <code>%{_sbindir}</code> || <code>/usr/sbin</code>
 
|-
 
| <code>%{_sharedstatedir}</code> || <code>/var/lib</code>
 
|-
 
| <code>%{_sysconfdir}</code> || <code>/etc</code>
 
|-
 
| <code>%{version}</code> || || Version of package, set by Version: tag
 
|}
 
 
 
Learn more about macros by looking in <code>/etc/rpm/*</code> and <code>/usr/lib/rpm</code>, especially <code>/usr/lib/rpm/macros</code>. Also use <code>rpm --showrc</code> to show values that RPM will use for macros (altered by <code>rpmrc</code> and macro configuration files).
 
 
 
You can set your own macro values using %global, but be sure to define them before you use them. (Macro definitions can also refer to other macros.)  For example:
 
%global date 2012-02-08
 
 
 
Use the "<code>-E</code>" option of <code>rpmbuild</code> to find the value of a macro in a SPEC file:
 
rpmbuild -E '%{_bindir}' myfile.spec
 
 
 
Also see [[Packaging/RPMMacros]] and [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch09s07.html RPM Guide chapter 9].
 
 
 
=== Other tags ===
 
 
 
In addition to Requires and BuildRequires tags, you can also use these for controlling dependencies:
 
* '''Provides''': list virtual package names that this package provides. For example, there might be a package "<code>foo</code>" that demands a particular functionality "bar" from another program. If there are several packages that can satisfy that demand, those packages can specify "<code>Provides: bar</code>" and the "<code>foo</code>" package can specify "<code>Requires: bar</code>". You could also use the [http://dailypackage.fedorabook.com/index.php?/archives/6-Wednesday-Why-The-Alternatives-System.html "alternatives" system], but avoid if multiple users on the same system might want different default, as these settings are system-wide. Use "<code>rpm -q --provides PACKAGENAME</code>" to see what a given package provides. Some examples of virtual packages in Fedora:
 
** MTA: Used for mail transport agents, such as sendmail.
 
** tex(latex): Used for latex
 
* '''Obsoletes''': remove another named package(s) when this package is installed. Use when the package name changes or when it totally replaces a different package.
 
* '''Conflicts''': state what other packages cannot be installed simultaneously to this one. Avoid this if you can. See [[Packaging/Conflicts]].
 
* '''BuildConflicts''': state what packages cannot be installed when building this package. Avoid this if you can.
 
 
 
To manage different architectures, there are two tags:
 
* '''ExcludeArch''': to exclude an architecture on which the package doesn't build. For example:
 
ExcludeArch: ppc
 
* '''ExclusiveArch''': to include only the specified architecture. Avoid this unless absolutely correct.
 
Valid architectures are listed at [[Architectures]].
 
 
 
=== Subpackages ===
 
 
 
A SPEC file can define several binary package. In other words, one SRPM with one SPEC file can result in several RPMS. Note that there is still only one creation (%prep, %build, %install etc.) process. <code>name-doc</code> and <code>name-devel</code> subpackages are common for documentation and development files respectively.
 
 
 
Use the <code>%package</code> directive to start defining a subpackage:
 
%package subpackage_name
 
 
 
After each <code>%package</code> directive, list the tags for the subpackage. This should at least include the Summary and Group tags, as well as the <code>%description subpackage_name</code> and <code>%files subpackage_name</code> directives:
 
 
 
Anything not specified by the subpackage will be inherited from its parent.
 
 
 
By default, if the package name is "<code>foo</code>" and the subpackage name is "<code>bar</code>", then the resulting subpackage will be "<code>foo-bar</code>". You can override it with the "<code>-n</code>" option (but you'll need to use it in all other directives too if you specify it here):
 
%package -n new_subpackage_name
 
 
 
[http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch10s04.html See the RPM Guide section on subpackages] for more information.
 
 
 
=== Conditionals ===
 
 
 
You can insert conditional statements, for example to test if you are creating a binary for a certain architecture:
 
%ifarch ARCHITECTURE_NAME
 
the negated version with:
 
%ifnarch ARCHITECTURE_NAME
 
or the more general conditional:
 
%if TRUE_OR_FALSE
 
 
 
There is an optional "<code>%else</code>" section; all of these are closed with "<code>%endif</code>".
 
 
 
=== Application Specific Guidelines ===
 
 
 
There are many application-specific guidelines that can help you (e.g., for specific programming languages, applications, libraries, and build systems).  Many of them are listed as part of the
 
[[Packaging/Guidelines#Application_Specific_Guidelines|Application Specific Guidelines of Packaging/Guidelines]].  Examples of application-specific guidelines are those for:
 
* [[Packaging:Cmake|Cmake]]
 
* [[Packaging:Emacs|Emacs]]
 
 
 
Failing that, some other ways of finding application-specific help are:
 
* The 'SEARCH' command on Fedoraproject.org.
 
* [[PackagingDrafts]]
 
* A [[SIGs|Special Interest Group (SIG)]]
 
* [http://fedoraproject.org/wiki/Special:PrefixIndex/Packaging Wiki pages prefixed with 'Packaging']
 
 
 
=== Miscellaneous hints ===
 
 
 
[[Packaging/FrequentlyMadeMistakes]] has information on frequently-made mistakes. There are also some recommendations and controversial tricks on
 
[[PackageMaintainers/Packaging Tricks]].
 
 
 
Try to write your SPEC files so that it is likely to work when a new release is made upstream, without any changes aside from bumping the version number and refreshing the source files. For example, if it contains *.txt files with execute bits, instead of doing
 
  chmod a-x Filename1.txt Filename2.txt Filename3.txt
 
consider doing this, which will handle new filenames that use the same file naming convention:
 
  chmod a-x *.txt
 
 
 
If you want to see lots of examples of scriptlets, you can show all the scriptlets on installed programs using:
 
  rpm -qa --queryformat "\n\nPACKAGE: %{name}\n" --scripts | less
 
 
 
Don't try to interact with the user; RPM is designed to support batch installs.  If an application needs to show a EULA, that needs to be part of its initial execution, not its installation.
 
 
 
You might not want to start services, because in a big install that could slow things down. If you install an init or systemd script, consider using <code>chkconfig</code> or <code>systemctl</code> to arrange for the service to be started/stopped on the next reboot.  Before uninstalling, you should normally try to stop its services if they are running.
 
 
 
Uninstalling should reverse most changes made during installation, but don't remove any user-created files.
 
 
 
Normally, if there are binary executables, then debugging symbols are stripped from the normal binary packages and placed into a <code>name-debug</code> subpackage. If this shouldn't happen, you can disable the stripping and creation of this subpackage by putting this at the top of your SPEC:
 
%global _enable_debug_package 0
 
%global debug_package %{nil}
 
%global __os_install_post /usr/lib/rpm/brp-compress %{nil}
 
 
 
To prevent stripping you may also need to do this in the <code>%install</code> section:
 
export DONT_STRIP=1
 
 
 
A way to check for the version of Fedora in a SPEC file for conditional builds is:
 
%if 0%{?fedora} <= <version>
 
The <code>?</code> causes the macro to evaluate to evaluate to blank if <code>%fedora</code> is not defined. This causes the end result to be the <code>0</code> (which is a number and thus fine), while not interfering with the result if there is actually a value for <code>%fedora</code>. (Note that this trick does not work in Koji "scratch" builds, where <code>%fedora</code> is set during the creation of a SRPM.)
 
 
 
GUI programs must have a desktop entry so that people can invoke it from the graphical desktop menu. For <code>.desktop</code> files, see [[Packaging/Guidelines#Desktop_files|Fedora packaging guidelines for desktop files]] and [http://standards.freedesktop.org/desktop-entry-spec/latest/ desktop entry spec]. For icons within <code>/usr/share/icons</code>, see [http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html icon theme spec].
 
 
 
== Building the binary package ==
 
 
 
=== Test with rpmlint ===
 
 
 
To catch many common errors early, run <code>rpmlint</code> on your SPEC file before trying to build anything from it:
 
$ rpmlint program.spec
 
If the reported error doesn't make sense, run it again with the "<code>-i</code>" option for longer messages.
 
 
 
Aim to have no errors, but sometimes <code>rpmlint</code> reports false positives. The [[Packaging/Guidelines#Use_rpmlint|Fedora packaging guidelines]]
 
explains which ones to ignore.
 
 
 
=== Create binary RPMS from the SPEC file ===
 
 
 
Once you've created your SPEC file, build the SRPM and binary RPMS by running this:
 
$ rpmbuild -ba program.spec
 
 
 
If successful, RPMS will be created within <code>~/rpmbuild/RPMS</code> and SRPMS will be created within <code>~/rpmbuild/SRPMS</code>.
 
 
 
If it fails, go to the appropriate directory and see what is left over. To help debug, you can skip earlier stages that succeeded with the "<code>--short-circuit</code> option. For example, to restart at the <code>%install</code> stage (skipping earlier stages), do this:
 
$ rpmbuild -bi --short-circuit program.spec
 
 
 
If you just want to create an SRPM (which does not run the <code>%prep</code> or <code>%build</code> or other stages), run this:
 
rpmbuild -bs program.spec
 
 
 
=== Testing binary RPMS with rpmlint ===
 
 
 
<code>rpmlint</code> can be run on SPEC files, RPMS and SRPMS to check for errors. You need to eliminate or justify warnings before posting a package. If you are in the SPECS directory, do this:
 
$ rpmlint ''NAME''.spec ../RPMS/*/''NAME''*.rpm ../SRPMS/''NAME''*.rpm
 
 
 
Enter the <code>~/rpmbuild/RPMS</code> directory and into the architecture subdirectory. You will find some binary RPMS. Quickly see their files and permissions (to check whether they are correct) by doing:
 
$ rpmls *.rpm
 
 
 
If they look fine, install them as root:
 
# rpm -ivp package1.rpm package2.rpm package3.rpm ...
 
 
 
Test the programs in a few different ways to see if everything works correctly. If it is a GUI tool, make sure it shows up in the desktop menu, otherwise the <code>.desktop</code> entry is wrong.
 
 
 
Uninstall packages later by doing:
 
# rpm -e package1 package2 package3
 
 
 
== Mock and Koji ==
 
 
 
[[Projects/Mock|Mock]] is a powerful tool that uses the SRPM you have created to build binary packages within a nearly empty environment. This can reveal if you have accurate build dependencies. If it fails, then you forgot to list something in BuildRequires. See [[Using Mock to test package builds]]. Once your account is a member of the "<code>mock</code>" group, you can run commands like this to do local testing:
 
$ mock -r fedora-9-i386 rebuild path_to_source_RPM
 
 
 
You can use Koji (which uses <code>mock</code>) to do builds on many different systems, some of which you may not have. [[PackageMaintainers/Join]] and [[PackageMaintainers/UsingKoji]] have more information about Koji. Once it's set up, you can test your SRPM on a variety of platforms by running commands like:
 
$ koji build --scratch dist-f9 path_to_source_RPM
 
 
 
Replace <code>dist-f9</code> with any later release of Fedora, but don't use <code>dist-rawhide</code>. Remember, the values of <code>%fedora</code>, <code>%fc9</code> and so on will not be correct for a scratch build, so this won't work if your SPEC file does something different based on those values.
 
 
 
Your Koji builds can only depend on packages that are actually in the TARGET distribution repository.  Thus, you can't use Koji to build for released distributions if your package depends on other new packages that Bodhi hasn't released yet. If you need to build against a package that is not yet a stable released update, you can file a ticket with rel-eng at: https://fedorahosted.org/rel-eng/newticket and request that that package be added as a buildroot override.
 
 
 
== Helpful tools ==
 
 
 
The <code>rpmdevtools</code> package has a number of helpful tools; "<code>rpm -qil rpmdevtools</code>" will show you what it installs.
 
* <code>rpmdev-bumpspec</code> : bump the release tag in the spec file and add a changelog comment with the right date and version format:
 
rpmdev-bumpspec --comment=COMMENT --userstring=NAME+EMAIL_STRING SPECFILES
 
 
 
The <code>yum-utils</code> package also has some useful tools:
 
* <code>yumdownloader</code> : download the SRPM of the package by running:
 
yumdownloader --source PACKAGENAME
 
 
 
The <code>auto-buildrequires</code> package has a pair of nice tools for helping to figure out the proper BuildRequires entries.  After installing this package, replace "<code>rpmbuild</code>" with "<code>auto-br-rpmbuild</code>" and you'll see an automatically generated BuildRequires list.
 
 
 
You might find [http://rust.sourceforge.net/ RUST] useful (GPL), though it does not create SPEC files of suitable quality for Fedora packages. [http://kitenet.net/~joey/code/alien/ Alien] converts between package formats. It won't produce clean SRPMS, but converting an existing package might provide helpful information.
 
 
 
== Guidelines and rules ==
 
 
 
When you create your packages, you'll need to follow the following rules and guidelines:
 
* [[Join the package collection maintainers|How to join the Fedora Package Collection Maintainers]]
 
* [[Packaging:Guidelines|Packaging Guidelines]]
 
* [[Packaging:NamingGuidelines|Package Naming Guidelines]]
 
* [[Packaging:LicensingGuidelines|Package Licensing Guidelines]]
 
* [[Packaging:DistTag|Dist Tag Guidelines]]
 
* [[Packaging:ReviewGuidelines|Package Review Guidelines]]
 
 
 
There are many official guidelines that will help you with specific circumstances (e.g. Java programs, OCaml programs, GNOME programs). You can also learn more from the [[SIGs]] and [[:Category:Package Maintainers|Package Maintainers]] sections. [https://fedoraproject.org/wiki/Special:Prefixindex/Packaging You can also see the list of all Wiki pages about Packaging] to see if any apply.
 
 
 
Failing that, you might find some useful recommendations in the unofficial [https://fedoraproject.org/wiki/Special:Search?ns0=1&search=PackagingDrafts%2F&searchx=Search Packaging Drafts] and [[PackagingDrafts|Packaging Drafts To Do]].
 
 
 
== Maintaining the package ==
 
 
 
Once your package has been accepted, you and your co-maintainers will need to maintain it. See [[Package update HOWTO]] and [[Package update guidelines]]. If you update the version in multiple releases of Fedora, do it backwards in time (e.g. release for Fedora N, then once that's accepted, Fedora N-1). The system presumes that later versions of Fedora have the same or later versions of programs.
 
 
 
Encourage the upstream developers to use standard source code release conventions. Using standard conventions makes packaging much easier. For more information, see:
 
* [http://www.dwheeler.com/essays/releasing-floss-software.html Releasing Free/Libre/Open Source Software (FLOSS) for Source Installation] (a quick summary)
 
* [http://www.gnu.org/prep/standards/html_node/Managing-Releases.html GNU Coding Standards release process]
 
* [http://en.tldp.org/HOWTO/Software-Release-Practice-HOWTO/ Software Release Practice HOWTO]
 
* [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard (FHS)]
 
* [http://offog.org/articles/packaging/ Packaging Unix software]
 
 
 
== For more information ==
 
 
 
The [[:Category:Package Maintainers|Package Maintainers]] page links to many other useful pages, and the
 
[[Package update HOWTO]] describes how to update an existing package you already maintain in Fedora.
 
 
 
For more information, outside of the Fedora Wiki, see:
 
* [http://www.g-loaded.eu/2006/04/05/how-to-build-rpm-packages-on-fedora/ How to build RPM packages on Fedora] - very brief run-through
 
* Packaging software with RPM (developerWorks) [http://www.ibm.com/developerworks/library/l-rpm1/ Part 1], [http://www.ibm.com/developerworks/library/l-rpm2/ Part 2], and [http://www.ibm.com/developerworks/library/l-rpm3.html Part 3]
 
* Fedora Classroom had a IRC session on packaging and you can refer to the logs at https://fedoraproject.org/wiki/Building_RPM_packages_%2820090405%29
 
* [http://koti.welho.com/vskytta/packagers-handbook/packagers-handbook.html Fedora Packager's Handbook]
 
* [http://www.redhatmagazine.com/2008/02/28/when-sally-met-eddie-the-fedora-package-story/ When Sally met Eddie] - a simple tale, but little detail
 
* [http://rpm.org/max-rpm-snapshot/ Maximum RPM Book] - most complete information, but in some cases old/obsolete
 
* [http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html RPM Guide, section on creating RPMs] - this has lots of good information, and is slightly more up-to-date, but is a draft
 
* [http://docs.fedoraproject.org/developers-guide/ch-rpm-building.html Developer's guide, section on building RPMs]
 
* [http://www.gurulabs.com/GURULABS-RPM-LAB/GURULABS-RPM-GUIDE-v1.0.PDF Creating RPMS slides] from Guru Labs
 
* [http://freshrpms.net/docs/fight/ The fight, my first attempt to make a readable rpm package building introduction.]
 
* [http://www-uxsup.csx.cam.ac.uk/talks/rpmbuild/rpmbuild.pdf Cambridge RPM tutorial] is a presentation on creating basic RPMs
 
* [http://en.tldp.org/HOWTO/RPM-HOWTO/index.html RPM HOWTO: RPM at Idle by Donnie Barnes]
 
* [http://home.fnal.gov/~dawson/rpms/howto/index.html RPM HowTo] by Dawson
 
* [http://en.opensuse.org/Build_Service/cross_distribution_package_how_to Cross-distribution package HOWTO] has hints if you're building one RPM for many distributions.
 
* [http://wiki.mandriva.com/en/Development/Howto/RPM Mandriva Rpm HowTo (en)] is an RPM tutorial, though for Mandriva (nee Mandrake).  Note: In Fedora, do ''not'' recompress original tarballs, as Mandriva suggests, because that would change their cryptographic hashes.
 
* [http://linuxshellaccount.blogspot.com/2008/03/creating-your-own-linux-rpms-initial.html Creating Your Own Linux RPM's - The Initial Software Build] is another brief intro, but it makes the point that "The process of building RPM's is much simpler than creating packages for Solaris... Fewer steps, and the ability to add all of your software information into one specification file, makes for a much tighter (and easier to modify or reproduce) software packaging system."
 
* [http://fedoranews.org/alex/tutorial/rpm/ All you need to know about RPM] (more about installing packages than creating them)
 
* The [http://wiki.rpm.org/ rpm.org Wiki] has some useful information, such as the [http://wiki.rpm.org/Problems list of known RPM problems]
 
 
 
Note: The [http://rpm5.org/ rpm5.org] site has some documentation, but do not depend on it; that is the home of a ''fork'' of RPM maintained by Jeff Johnson.  The RPM used by Fedora (and Novell/SuSE) is instead based at [http://www.rpm.org rpm.org].
 
[http://lwn.net/Articles/236029/ lwn.net has a brief article] about this.
 
 
 
[[Category:Package Maintainers]]
 
[[Category:How to]]
 

Latest revision as of 20:57, 26 May 2021