2017-10-26 21:20:01 +00:00
|
|
|
|
= How to create an RPM package
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
2017-10-27 20:44:00 +00:00
|
|
|
|
[IMPORTANT]
|
2017-10-26 21:20:01 +00:00
|
|
|
|
======
|
|
|
|
|
|
|
|
|
|
This page was automatically converted from https://fedoraproject.org/wiki/How_to_create_an_RPM_package
|
|
|
|
|
|
|
|
|
|
It is probably
|
|
|
|
|
|
|
|
|
|
* Badly formatted
|
2017-11-06 17:34:22 +00:00
|
|
|
|
* Missing graphics and tables that do not convert well from mediawiki
|
2017-10-26 21:20:01 +00:00
|
|
|
|
* Out-of-date
|
|
|
|
|
* In need of other love
|
|
|
|
|
|
|
|
|
|
Please fix it, remove this notice, and then add to `_topic_map.yml`
|
|
|
|
|
|
2017-11-10 15:16:19 +00:00
|
|
|
|
Pull requests accepted at https://pagure.io/fedora-docs/quick-docs
|
2017-10-26 21:20:01 +00:00
|
|
|
|
|
|
|
|
|
Once that is live, go to the original wiki page and add an `{{old}}`
|
|
|
|
|
tag, followed by a note like
|
|
|
|
|
|
|
|
|
|
....
|
|
|
|
|
{{admon/note|This page has a new home!|
|
|
|
|
|
This wiki page is no longer maintained. Please find the up-to-date
|
|
|
|
|
version at: https://docs.fedoraproject.org/whatever-the-url
|
|
|
|
|
}}
|
|
|
|
|
....
|
|
|
|
|
|
|
|
|
|
======
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__TOC__
|
|
|
|
|
|
|
|
|
|
[[introduction]]
|
|
|
|
|
Introduction
|
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
This page describes in detail how to create an RPM package, and in
|
|
|
|
|
particular how to create a specfile. Unlike other RPM guides, this page
|
|
|
|
|
explains the specifics for Fedora with links to Fedora-specific
|
|
|
|
|
guidelines and usage of Fedora-specific utilities. Despite the focus on
|
|
|
|
|
Fedora, much of this document does apply to other RPM-based
|
|
|
|
|
distributions.
|
|
|
|
|
|
|
|
|
|
Fedora Documentation had released a draft guide for packagers, see
|
|
|
|
|
http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide[Packagers
|
|
|
|
|
Guide]. It is archived.
|
|
|
|
|
|
|
|
|
|
Please note that this document is merely a gentle introduction and will
|
|
|
|
|
leave out many of the details which you may need in order to package
|
|
|
|
|
more complicated software. It also assumes that you have familiarity
|
|
|
|
|
with the shell and are familiar with the process of building and
|
|
|
|
|
installing (outside of RPM) the software you wish to package. Finally,
|
|
|
|
|
this document is *NOT* an official Fedora packaging guideline. This page
|
|
|
|
|
is open for editing by the general Fedora packaging community, while the
|
|
|
|
|
actual packaging guidelines are managed by the
|
|
|
|
|
Packaging:Committee[Packaging Committee]. For reference, here are some
|
|
|
|
|
of the most referenced guideline pages:
|
|
|
|
|
|
|
|
|
|
* Packaging:Guidelines[Packaging Guidelines]
|
|
|
|
|
* Packaging:LicensingGuidelines[Licensing Guidelines]
|
|
|
|
|
* Packaging:Naming[ Package Naming Guidelines]
|
|
|
|
|
* Packaging:DistTag[ Dist Tag Guidelines]
|
|
|
|
|
* Packaging:ReviewGuidelines[ Package Review Guidelines]
|
|
|
|
|
* Packaging:Scriptlets[ Recipes for RPM scriptlets]
|
|
|
|
|
|
|
|
|
|
Packaging:Guidelines and Packaging:Naming contain the main guidelines.
|
|
|
|
|
Having said that, this page should be compatible with them, though the
|
|
|
|
|
guidelines do change over time and this page may diverge from them on
|
|
|
|
|
occasion.
|
|
|
|
|
|
|
|
|
|
If you plan to submit a package to the official Fedora repository, you
|
|
|
|
|
will also want to follow the procedure depicted in
|
|
|
|
|
link:Join_the_package_collection_maintainers[Join the package collection
|
|
|
|
|
maintainers].
|
|
|
|
|
|
|
|
|
|
[[some-terminology]]
|
|
|
|
|
Some terminology
|
|
|
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
RPM::
|
|
|
|
|
The package manager used by Fedora, Red Hat Enterprise Linux, Mageia,
|
|
|
|
|
OpenSUSE and others. Originally RPM stood for "Red Hat Package
|
|
|
|
|
Manager" but now it's just the recursive acronym "RPM Package
|
|
|
|
|
Manager".
|
|
|
|
|
|
|
|
|
|
specfile::
|
|
|
|
|
A plain text file containing information about a package and
|
|
|
|
|
instructions used by RPM for actually compiling the included software.
|
|
|
|
|
It is named by appending `.spec` to the name of the package.
|
|
|
|
|
|
|
|
|
|
tag::
|
|
|
|
|
A string, generally capitalized and followed by a colon, which appears
|
|
|
|
|
at the top of the specfile to provide some important data about the
|
|
|
|
|
RPM, such as `Name:`, `Version:` or `Summary:`.
|
|
|
|
|
|
|
|
|
|
section::
|
|
|
|
|
A segment of the specfile which tells RPM how to perform some portion
|
|
|
|
|
of the package construction process. Many, but not all, sections
|
|
|
|
|
contain code that is simply passed to the shell, though RPM has
|
|
|
|
|
significant flexibility around this which will not be covered at all
|
|
|
|
|
in this document.
|
|
|
|
|
|
|
|
|
|
section header::
|
|
|
|
|
A short string, starting with `%` at the beginning of a line, which
|
|
|
|
|
introduces a section. Examples include `%description`, `%prep` and
|
|
|
|
|
`%files`.
|
|
|
|
|
|
|
|
|
|
macro::
|
|
|
|
|
A short string, always prefixed by `%` and generally surrounded by
|
|
|
|
|
curly brackets (`{}`) which RPM will convert to a different and
|
|
|
|
|
usually longer string. Some macros can take arguments and some can be
|
|
|
|
|
quite complex. Some macros are provided by RPM, some are part of and ,
|
|
|
|
|
but many other packages also provide them. If you're curious, running
|
|
|
|
|
`rpm --showrc` will show you all of the macros currently available on
|
|
|
|
|
your system, but note that you really don't want to use most of the
|
|
|
|
|
ones you see there. Note that some macros have named prefixed by
|
|
|
|
|
underscores; the reasons for this are mostly lost to time.
|
|
|
|
|
+
|
|
|
|
|
The packaging guidelines have various
|
|
|
|
|
Packaging:Guidelines#Macros[suggestions and restrictions] regarding
|
|
|
|
|
the use of various sets of macros. This document will use what the
|
|
|
|
|
guidelines recommend, but won't necessarily explain the reasons in
|
|
|
|
|
detail.
|
|
|
|
|
+
|
|
|
|
|
You may, in looking at other packages, see macros used without curly
|
|
|
|
|
brackets. There are situations where this isn't strictly necessary,
|
|
|
|
|
but these guidelines will use them wherever possible to make it more
|
|
|
|
|
obvious when macros are being used and to avoid going into the rules
|
|
|
|
|
about when the brackets are needed and when they aren't.
|
|
|
|
|
|
|
|
|
|
mock::
|
|
|
|
|
A system for building RPMs within their own separate small Fedora
|
|
|
|
|
installation. This avoids the need to have a full set of build
|
|
|
|
|
dependencies installed into your regular operating system
|
|
|
|
|
installation, allows you to build packages for different Fedora
|
|
|
|
|
releases, and in general is a good thing.
|
|
|
|
|
|
|
|
|
|
koji::
|
|
|
|
|
The main Fedora build system: https://koji.fedoraproject.org[1].
|
|
|
|
|
|
|
|
|
|
[[editors-for-editing-rpm-spec-files]]
|
|
|
|
|
Editors for editing RPM spec files
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Many editors (like text editors and IDEs) that are in the official
|
|
|
|
|
repositories of Fedora have out-of-the-box syntax-highlighting support
|
|
|
|
|
for RPM spec files, these include:
|
|
|
|
|
|
|
|
|
|
* CodeEditor. It does not syntax-highlight the shell script code found
|
|
|
|
|
in RPM spec files.
|
|
|
|
|
* gedit. It does not syntax-highlight the shell script code found in RPM
|
|
|
|
|
spec files.
|
|
|
|
|
* link:GNU_nano[GNU nano]. It does not syntax-highlight the shell script
|
|
|
|
|
code found in RPM spec files.
|
|
|
|
|
* Joe. It does not syntax-highlight the shell script code found in RPM
|
|
|
|
|
spec files.
|
|
|
|
|
* Kate. It does not syntax-highlight the shell script code found in RPM
|
|
|
|
|
spec files.
|
|
|
|
|
* KWrite. It does not syntax-highlight the shell script code found in
|
|
|
|
|
RPM spec files.
|
|
|
|
|
* Pluma. It does not syntax-highlight the shell script code found in RPM
|
|
|
|
|
spec files.
|
|
|
|
|
* Vim (and, of course, its graphical counterpart, gVim). It also
|
|
|
|
|
syntax-highlights the shell script code found in RPM spec files.
|
|
|
|
|
|
|
|
|
|
while the following are present in the official Fedora repositories but
|
|
|
|
|
do not come with out-of-the-box syntax-highlighting for RPM Spec files,
|
|
|
|
|
but do gain said support when optional packages/plugins are installed:
|
|
|
|
|
|
|
|
|
|
* Eclipse can develop RPM spec file editing support when the
|
|
|
|
|
https://apps.fedoraproject.org/packages/eclipse-rpm-editor[RPM Spec file
|
|
|
|
|
editor] package is also installed. This package also provides code
|
|
|
|
|
linting (checking for RPM packaging errors) and make it easier to
|
|
|
|
|
navigate the spec file.
|
|
|
|
|
* link:GNU_Emacs[GNU Emacs] has editing support for RPM spec files when
|
|
|
|
|
the https://apps.fedoraproject.org/packages/emacs-rpm-spec-mode[RPM spec
|
|
|
|
|
mode] package is installed.
|
|
|
|
|
|
|
|
|
|
Editors that are not in the official repositories of Fedora but are
|
|
|
|
|
available for Fedora and, with the appropriate plugins, can
|
|
|
|
|
syntax-highlight RPM spec files include:
|
|
|
|
|
|
|
|
|
|
* Atom, with the
|
|
|
|
|
https://atom.io/packages/language-rpm-spec[language-rpm-spec] package.
|
|
|
|
|
* link:Visual_Studio_Code[Visual Studio Code], with the
|
|
|
|
|
https://marketplace.visualstudio.com/items?itemName=1dot75cm.RPMSpec[RPM
|
|
|
|
|
Spec] extension.
|
|
|
|
|
|
|
|
|
|
[[preparing-your-system]]
|
|
|
|
|
Preparing your system
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Before you create RPM packages on Fedora, you need to install some
|
|
|
|
|
packaging tools and set up the account(s) you will use. Run this as
|
|
|
|
|
root:
|
|
|
|
|
|
|
|
|
|
`dnf install fedora-packager fedora-review`
|
|
|
|
|
|
|
|
|
|
This will install the utilities needed to work with and build packages
|
|
|
|
|
in the same manner used to maintain official Fedora packages, including
|
|
|
|
|
the tool used by package reviewers to check package quality.
|
|
|
|
|
|
|
|
|
|
As root, add yourself to the mock group:
|
|
|
|
|
|
|
|
|
|
`usermod -a -G mock yourusername`
|
|
|
|
|
|
|
|
|
|
This should be the last time you need root unless you wish to install
|
|
|
|
|
packages you have developed.
|
|
|
|
|
|
|
|
|
|
You may afterwards need to run `newgrp` or log out and back in for this
|
|
|
|
|
change to take effect. Run the `id` command to see if the "mock" group
|
|
|
|
|
appears in your group list.
|
|
|
|
|
|
|
|
|
|
If you have already obtained a Fedora account and accepted the
|
|
|
|
|
contributor agreement, you can also set up your fedora certificates and
|
|
|
|
|
such. Just run (as your user, not as root):
|
|
|
|
|
|
|
|
|
|
`fedora-packager-setup`
|
|
|
|
|
|
|
|
|
|
If you wish, you can also create a separate user and use it for doing
|
|
|
|
|
RPM development. You should make sure that user is part of the "mock"
|
|
|
|
|
group and has run `fedora-packager-setup`.
|
|
|
|
|
|
|
|
|
|
[[first-steps]]
|
|
|
|
|
First steps
|
|
|
|
|
~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
To create an RPM package, you will need to create a directory to hold
|
|
|
|
|
the package and, within that directory, the specfile. This file provides
|
|
|
|
|
information about the software being packaged, instructions for
|
|
|
|
|
unpacking it, building it and installing it, as well as a list of files
|
|
|
|
|
which will be included in the package. You then run the `fedpkg` command
|
|
|
|
|
with appropriate options, which will go through a series of steps to
|
|
|
|
|
produce your package.
|
|
|
|
|
|
|
|
|
|
The construction of the specfile is often done iteratively (one relevant
|
|
|
|
|
piece at a time), and that's what we'll do here. But first we'll need
|
|
|
|
|
someplace to make our package as well as something to package. Run the
|
|
|
|
|
following to create a directory to hold packaging work (called
|
|
|
|
|
`packaging-work`), within it a place to hold our package (called
|
|
|
|
|
"`howdy`), and within that a simple program to package (also called
|
|
|
|
|
"`howdy`). You can use any location you like but the directory name for
|
|
|
|
|
the package should match the name of the package.
|
|
|
|
|
|
|
|
|
|
`mkdir -p ~/packaging-work/howdy` +
|
|
|
|
|
`cd ~/packaging-work/howdy` +
|
|
|
|
|
`cat << EOF > howdy` +
|
|
|
|
|
`#!/bin/bash` +
|
|
|
|
|
`echo "Howdy, partner!"` +
|
|
|
|
|
`EOF` +
|
|
|
|
|
`chmod 644 howdy`
|
|
|
|
|
|
|
|
|
|
You should be able to run `bash howdy` and receive the expected output.
|
|
|
|
|
Now we have something we can package, so let's start making a specfile.
|
|
|
|
|
We'll start with a very minimal template (which will have to be expanded
|
|
|
|
|
for anything more complicated than this example). Just start your editor
|
|
|
|
|
on a new file called `howdy.spec`" and paste this in. Please use spaces
|
|
|
|
|
and not tabs. It's not necessary to have everything like up but it does
|
|
|
|
|
make it look nice.
|
|
|
|
|
|
|
|
|
|
....
|
|
|
|
|
Name: howdy
|
|
|
|
|
Version: 1
|
|
|
|
|
Release: 1%{?dist}
|
|
|
|
|
Summary: Say hello, Texas style
|
|
|
|
|
|
|
|
|
|
License: Public Domain
|
|
|
|
|
Source0: howdy
|
|
|
|
|
|
|
|
|
|
%description
|
|
|
|
|
A simple program to greet the user, Texas style.
|
|
|
|
|
|
|
|
|
|
%install
|
|
|
|
|
|
|
|
|
|
%files
|
|
|
|
|
|
|
|
|
|
%changelog
|
|
|
|
|
....
|
|
|
|
|
|
|
|
|
|
So we've described the package, indicated a version and listed the one
|
|
|
|
|
source file we have. We have an `%install` and a `%files` section, both
|
|
|
|
|
of which are empty. Save your edits and run
|
|
|
|
|
|
|
|
|
|
`fedpkg --release f`` local`
|
|
|
|
|
|
|
|
|
|
This is called a "local build". Assuming no typos or other issues, you
|
|
|
|
|
should get some output and two RPM files. One should be the source
|
|
|
|
|
package, which contains everything necessary for someone else (or the
|
|
|
|
|
Fedora build system) to build their own copy of your package. The other
|
|
|
|
|
is a binary package. It doesn't actually have anything in it at this
|
|
|
|
|
point, though, because we didn't tell RPM to actually include any files.
|
|
|
|
|
(It would not even have been created if we hadn't included the empty
|
|
|
|
|
`%files` section.)
|
|
|
|
|
|
|
|
|
|
If you like, you can look at either package using `rpm -qip`, or just
|
|
|
|
|
`less`.
|
|
|
|
|
|
|
|
|
|
[[a-useful-package]]
|
|
|
|
|
A useful package
|
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
So now we have a minimally functional specfile which builds and produces
|
|
|
|
|
a rather useless binary package.
|
|
|
|
|
|
|
|
|
|
In order to actually make a package which does something, we must tell
|
|
|
|
|
RPM how to install the program. Edit the specfile and add this to the
|
|
|
|
|
`%install` section (immediately after the line containing `%install`):
|
|
|
|
|
|
|
|
|
|
`mkdir -p %{buildroot}/%{_bindir}` +
|
|
|
|
|
`install -p -m 755 %{SOURCE0} %{buildroot}/%{_bindir}`
|
|
|
|
|
|
|
|
|
|
The contents of the `%install` section is just a shell script! Note that
|
|
|
|
|
we've used three macros:
|
|
|
|
|
|
|
|
|
|
* `%{buildroot}` is set to a temporary directory called "the buildroot"
|
|
|
|
|
that's set up by RPM to hold the complete tree of files we'll install.
|
|
|
|
|
* `%{_bindir}` is just /usr/bin.
|
|
|
|
|
* `%{SOURCE0}` refers to the file listed earlier in the spec with the
|
|
|
|
|
`Source0:` tag.
|
|
|
|
|
|
|
|
|
|
This saves us from having to care about exactly where those files and
|
|
|
|
|
directories are located on the filesystem while the package is built;
|
|
|
|
|
instead we only care about where those files are ending up. And without
|
|
|
|
|
`%{buildroot}` we'd end up installing those files directly onto our
|
|
|
|
|
development machine, which would be bad, especially if running as root.
|
|
|
|
|
|
|
|
|
|
Now do a local build. It failed! But why? Well, because of this:
|
|
|
|
|
|
|
|
|
|
`error: Installed (but unpackaged) file(s) found:` +
|
|
|
|
|
` /usr/bin/howdy`
|
|
|
|
|
|
|
|
|
|
We installed a file but didn't tell RPM about it. RPM maybe could just
|
|
|
|
|
include everything we install, but there are plenty of good reasons why
|
|
|
|
|
it doesn't just do that. So tell RPM about that file, by adding this to
|
|
|
|
|
the `%files` section:
|
|
|
|
|
|
|
|
|
|
`%{_bindir}/howdy`
|
|
|
|
|
|
|
|
|
|
Note that `%files` is generally about files we've actually installed
|
|
|
|
|
into the buildroot. You do not use the `%{buildroot}` macro when listing
|
|
|
|
|
files there.
|
|
|
|
|
|
|
|
|
|
Now do another local build. If all goes well, you should have two
|
|
|
|
|
updated RPMs, and the binary one should contain a file. But there's one
|
|
|
|
|
more thing we should add to the spec to make this a complete package.
|
|
|
|
|
Since all we're packaging is a shell script, there is no reason at all
|
|
|
|
|
for this to be built separately on each architecture Fedora supports. So
|
|
|
|
|
edit the spec once more and add the following immediately after the
|
|
|
|
|
`Source0:` line:
|
|
|
|
|
|
|
|
|
|
`BuildArch: noarch`
|
|
|
|
|
|
|
|
|
|
This tells RPM that there's nothing architecture-specific about a
|
|
|
|
|
particular package. You can reindent the spec if you like to make things
|
|
|
|
|
line up, but please use spaces and not tabs. Delete the existing `.rpm`
|
|
|
|
|
files in this directory and do another local build. Now you should have
|
|
|
|
|
a pair of rpms: one with the updated source, and one ending in
|
|
|
|
|
`.noarch.rpm` indicating an architecture-independent package. You should
|
|
|
|
|
now have your first complete package that you built yourself! If you
|
|
|
|
|
like, install it and try it out. You'll probably want to remove it once
|
|
|
|
|
you're done, unless you just like Texas-style greetings.
|
|
|
|
|
|
|
|
|
|
[[further-things-to-do-with-our-package]]
|
|
|
|
|
Further things to do with our package
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Have a glance at our current spec if you like.
|
|
|
|
|
|
|
|
|
|
....
|
|
|
|
|
|
|
|
|
|
Name: howdy
|
|
|
|
|
Version: 1
|
|
|
|
|
Release: 1%{?dist}
|
|
|
|
|
Summary: Say hello, Texas style
|
|
|
|
|
|
|
|
|
|
License: Public Domain
|
|
|
|
|
Source0: howdy
|
|
|
|
|
BuildArch: noarch
|
|
|
|
|
|
|
|
|
|
%description
|
|
|
|
|
A simple program to greet the user, Texas style.
|
|
|
|
|
|
|
|
|
|
%install
|
|
|
|
|
mkdir -p %{buildroot}/%{_bindir}
|
|
|
|
|
install -p -m 755 %{SOURCE0} %{buildroot}/%{_bindir}
|
|
|
|
|
|
|
|
|
|
%files
|
|
|
|
|
%{_bindir}/howdy
|
|
|
|
|
|
|
|
|
|
%changelog
|
|
|
|
|
....
|
|
|
|
|
|
|
|
|
|
You may recall that RPM handles dependencies, but we didn't indicate
|
|
|
|
|
anything about that in the specfile. Let's look.
|
|
|
|
|
|
|
|
|
|
` rpm -qp --requires howdy-1-1.fc``.noarch.rpm`
|
|
|
|
|
|
|
|
|
|
You'll see that RPM added some internal `rpmlib` dependencies, plus one
|
|
|
|
|
on `/bin/bash` which matches up with the first line of the howdy
|
|
|
|
|
program. Often RPM will handle dependencies for your binary packages
|
|
|
|
|
automatically. Often times it won't, and we'll look into that later.
|
|
|
|
|
|
|
|
|
|
You can also replace `--requires` by `--provides` to see the other side
|
|
|
|
|
of the dependency equation. There's not much of interest there, but if
|
|
|
|
|
something did depend on `howdy` then this package would provide it.
|
|
|
|
|
|
|
|
|
|
Next thing to do is run some checks on our package:
|
|
|
|
|
|
|
|
|
|
` fedpkg --release f`` lint`
|
|
|
|
|
|
|
|
|
|
This will spit out a few complaints. Four total about the lack of
|
|
|
|
|
`%prep` and `%build` sections, one about the lack of a `URL:` tag, and
|
|
|
|
|
one about the lack of a proper changelog. You may also see other
|
|
|
|
|
complaints, perhaps about permissions. The full set of complaints may
|
|
|
|
|
change over time as the checking program, itself changes. You may even
|
|
|
|
|
have noticed these complaints earlier if your editor was configured to
|
|
|
|
|
automatically check specfiles as you edit them.
|
|
|
|
|
|
|
|
|
|
We will ignore the complaints about the lack of the two sections and a
|
|
|
|
|
URL. We could make the complaints go away by adding empty sections and a
|
|
|
|
|
dummy URL, but that's not productive and our next experiment will have
|
|
|
|
|
them.
|
|
|
|
|
|
|
|
|
|
It would indeed be nice to have a changelog section, though. Your editor
|
|
|
|
|
may have the capability to add one automatically; in it's (unless you've
|
|
|
|
|
changed the leader key) and in it's . If you want to do it manually,
|
|
|
|
|
have a look at the relevant Packaging:Guidelines#Changelogs[guidelines].
|
|
|
|
|
I'll add mine here:
|
|
|
|
|
|
|
|
|
|
`* Mon Sep 19 2016 Jason L Tibbitts III <tibbs@math.uh.edu> - 1-1` +
|
|
|
|
|
`- Initial packaging.`
|
|
|
|
|
|
|
|
|
|
[[building-in-mock]]
|
|
|
|
|
Building in mock
|
|
|
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
The next interesting thing to do would be to see if our package will
|
|
|
|
|
build in the way that the Fedora build system would do it. To do this,
|
|
|
|
|
just run:
|
|
|
|
|
|
|
|
|
|
`fedpkg --release f`` mockbuild`
|
|
|
|
|
|
|
|
|
|
This will build your package in . Running mock will set up a complete
|
|
|
|
|
minimal Fedora installation inside a directory and then build the
|
|
|
|
|
package within that.
|
|
|
|
|
|
|
|
|
|
The end result should be a significant amount of output, a results_howdy
|
|
|
|
|
directory, and a couple of levels deep a three log files and two
|
|
|
|
|
packages. Feel free to look at those.
|
|
|
|
|
|
|
|
|
|
You can also build for other releases in this manner, by changing what
|
|
|
|
|
you pass to the `--release` option. This can be useful for testing, but
|
|
|
|
|
it takes another big download so we'll skip that now.
|
|
|
|
|
|
|
|
|
|
[[building-in-koji]]
|
|
|
|
|
Building in koji
|
|
|
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
If you had your Fedora account set up at the time you started following
|
|
|
|
|
this document, you can build your package in the central Fedora build
|
|
|
|
|
system, though the syntax can be a bit odd:
|
|
|
|
|
|
|
|
|
|
`fedpkg --release f`` scratch-build --target f`` --srpm`
|
|
|
|
|
|
|
|
|
|
This will create a source package, upload it to the build servers, and
|
|
|
|
|
give you some output including a URL you can visit to watch the process
|
|
|
|
|
and download the built packages afterwards. This can be useful to test
|
|
|
|
|
that your package builds on the various different architectures that
|
|
|
|
|
Fedora supports, although your current test package doesn't need such
|
|
|
|
|
testing.
|
|
|
|
|
|
|
|
|
|
[[running-fedora-review]]
|
|
|
|
|
Running fedora-review
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
Package reviewers use as part of the process of accepting new packages
|
|
|
|
|
into the distribution. You can run this tool yourself as a useful set of
|
|
|
|
|
informative checks. First, clean up your package directory:
|
|
|
|
|
|
|
|
|
|
`rm -rf *rpm results*`
|
|
|
|
|
|
|
|
|
|
Then create a source package and run the utility:
|
|
|
|
|
|
|
|
|
|
`fedpkg --release f`` srpm` +
|
|
|
|
|
`fedora-review -n howdy`
|
|
|
|
|
|
|
|
|
|
This will use mock to build your package and run a number of checks on
|
|
|
|
|
it. It will be silent while mock runs, so it may appear as if it has
|
|
|
|
|
hung when in reality it is doing a large amount of downloading. You can
|
|
|
|
|
add `-v` to make it somewhat more verbose.
|
|
|
|
|
|
|
|
|
|
When done, you should have a `review-howdy` directory with various files
|
|
|
|
|
and directories. `rpmlint.txt` should have some additional rpmlint
|
|
|
|
|
output for you. `review.txt` is the template that a reviewer would fill
|
|
|
|
|
in (in addition to checking the functionality of the software in your
|
|
|
|
|
package, etc.) Most of that is probably not of interest to you, but it
|
|
|
|
|
doesn't hurt to have a look.
|
|
|
|
|
|
|
|
|
|
[[on-to-a-more-complex-program]]
|
|
|
|
|
On to a more complex program
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Now that we've covered the absolute basics, we can move on to packaging
|
|
|
|
|
something more complicated, which comes from a real upstream and has to
|
|
|
|
|
be unpacked and built. A good package to use as an example is
|
|
|
|
|
https://www.gnu.org/software/hello/[GNU Hello]. Have a look there, note
|
|
|
|
|
the current version of Hello (2.10 as this document is being written)
|
|
|
|
|
and the download URL, licensing information and such. It's helpful to
|
|
|
|
|
keep that page open for referenceLet's create a directory and work in
|
|
|
|
|
it:
|
|
|
|
|
|
|
|
|
|
` mkdir -p ~/packaging-work/hello` +
|
|
|
|
|
` cd ~/packaging-work/hello`
|
|
|
|
|
|
|
|
|
|
And create the following specfile named `hello.spec`:
|
|
|
|
|
|
|
|
|
|
....
|
|
|
|
|
Name: hello
|
|
|
|
|
Version: 2.10
|
|
|
|
|
Release: 1%{?dist}
|
|
|
|
|
Summary: GNU Hello
|
|
|
|
|
URL: https://www.gnu.org/software/hello/
|
|
|
|
|
License: GPLv3+
|
|
|
|
|
|
|
|
|
|
Source0: https://ftp.gnu.org/gnu/hello/hello-%{version}.tar.gz
|
|
|
|
|
|
|
|
|
|
%description
|
|
|
|
|
The GNU hello program produces a familiar, friendly greeting. It allows
|
|
|
|
|
nonprogrammers to use a classic computer science tool which would otherwise be
|
|
|
|
|
unavailable to them. Because it is protected by the GNU General Public License,
|
|
|
|
|
users are free (in perpetuity) to share and change it.
|
|
|
|
|
|
|
|
|
|
%prep
|
|
|
|
|
|
|
|
|
|
%build
|
|
|
|
|
|
|
|
|
|
%install
|
|
|
|
|
|
|
|
|
|
%files
|
|
|
|
|
|
|
|
|
|
%changelog
|
|
|
|
|
....
|
|
|
|
|
|
|
|
|
|
We've filled in a few things here. There's now a `URL:` tag, pointing to
|
|
|
|
|
the Hello homepage. The `%description` was cribbed from the homepage.
|
|
|
|
|
The `License:` tag has changed, since the bottom of the homepage says
|
|
|
|
|
that the license is "under the terms of the GNU General Public License
|
|
|
|
|
as published by the Free Software Foundation; either version 3 of the
|
|
|
|
|
License, or (at your option) any later version.". Licensing is a
|
|
|
|
|
difficult subject, and we'll cover it in more depth later, but for now
|
|
|
|
|
it's sufficient to note that Fedora indicates this type of license with
|
|
|
|
|
"GPLv3+".
|
|
|
|
|
|
|
|
|
|
Perhaps the most interesting change is to the `Source0:` tag. It now has
|
|
|
|
|
a URL instead of a filename: using a URL tells everyone, including the
|
|
|
|
|
relevant Fedora utilities, where to actually get the source. And there's
|
|
|
|
|
a macro in there: `%{version}` is automatically set to whatever you used
|
|
|
|
|
for the `Version:` tag. Combining the two lets things automatically get
|
|
|
|
|
an updated copy of the source whenever the version changes. But how do
|
|
|
|
|
we actually get that source, since now we can't cut and paste that URL?
|
|
|
|
|
Try `spectool`:
|
|
|
|
|
|
|
|
|
|
`spectool -g *spec`
|
|
|
|
|
|
|
|
|
|
This quickly grabs all of the sources mentioned in the spec, and will
|
|
|
|
|
leave us with `hello-2.10.tar.gz` in our package directory. Have a look
|
|
|
|
|
with that file:
|
|
|
|
|
|
|
|
|
|
`less *tar.gz`
|
|
|
|
|
|
|
|
|
|
and we see that everything in there unpacks unto a single directory
|
|
|
|
|
named `hello-2.10`. We'll need to tell RPM how to unpack that archive
|
|
|
|
|
and how to find the files within. Add this to the `%prep` section:
|
|
|
|
|
|
|
|
|
|
`%autosetup`
|
|
|
|
|
|
|
|
|
|
This is a rather complicated macro which RPM will replace with plain old
|
|
|
|
|
shell code to unpack the archive, change into a directory and fix up
|
|
|
|
|
some permissions. It by default expects the directory to be named
|
|
|
|
|
`%{name}-%{version}` (where `%{name}` is, you guessed it, what you gave
|
|
|
|
|
for the `Name:` tag). This can be changed by passing the `-n` option,
|
|
|
|
|
but in our case the default is just what we need. You can see exactly
|
|
|
|
|
what it does by executing the `%prep` section with:
|
|
|
|
|
|
|
|
|
|
`fedpkg --release f`` prep`
|
|
|
|
|
|
|
|
|
|
This will call just the `%prep` section of your specfile, and should
|
|
|
|
|
leave you with a directory named `hello-2.10` in your package directory.
|
|
|
|
|
Have a look around in there. You'll see this is a standard GNU package
|
|
|
|
|
with a `configure` file, and that tells us most of what we need to know
|
|
|
|
|
in order to build it. Add this to the `%build` section:
|
|
|
|
|
|
|
|
|
|
`%configure` +
|
|
|
|
|
`%make_build`
|
|
|
|
|
|
|
|
|
|
This just calls the `configure` file with all of the arguments necessary
|
|
|
|
|
to build in Fedora, and then calls `make` with the necessary options.
|
|
|
|
|
And while we're at it, let's add this to `%install`:
|
|
|
|
|
|
|
|
|
|
`%make_install`
|
|
|
|
|
|
|
|
|
|
This calls the usual `make install` with Fedora's special macros to get
|
|
|
|
|
everything into the buildroot. If you do a mockbuild at this point,
|
|
|
|
|
you'll see that the build fails, just like with the previous package,
|
|
|
|
|
there are installed but unpackaged files. The list of files below the
|
|
|
|
|
error heading in the output, tells us what we need to do next, but
|
|
|
|
|
because there's an info page, a manpage and some locale files, we have a
|
|
|
|
|
few different rules to follow.
|
|
|
|
|
|
|
|
|
|
[[old-document-below]]
|
|
|
|
|
Old document below
|
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
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 `.tar.gz` file) in the
|
|
|
|
|
`~/rpmbuild/SOURCES` 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.
|
|
|
|
|
|
|
|
|
|
[[creating-a-spec-file]]
|
|
|
|
|
Creating a SPEC file
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
You now need to create a SPEC file in the `~/rpmbuild/SPECS` directory.
|
|
|
|
|
You should name it after the program name (e.g. "`program.spec`"). Use
|
|
|
|
|
the archive name or the name advocated by the software author where you
|
|
|
|
|
can, but be sure to follow the link:Packaging/NamingGuidelines[Package
|
|
|
|
|
Naming Guidelines].
|
|
|
|
|
|
|
|
|
|
[[spec-templates-and-examples]]
|
|
|
|
|
SPEC templates and examples
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
[[templates]]
|
|
|
|
|
Templates
|
|
|
|
|
+++++++++
|
|
|
|
|
|
|
|
|
|
You may use the `rpmdev-newspec` command to create a SPEC file for you.
|
|
|
|
|
`rpmdev-newspec <package-name>` 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 `/etc/rpmdevtools/spectemplate-*.spec` for
|
|
|
|
|
available templates, and see `rpmdev-newspec --help` for more
|
|
|
|
|
information. For example, to create a new SPEC file for a python module:
|
|
|
|
|
|
|
|
|
|
`cd ~/rpmbuild/SPECS` +
|
|
|
|
|
`rpmdev-newspec python-antigravity` +
|
|
|
|
|
`vim python-antigravity.spec`
|
|
|
|
|
|
|
|
|
|
According to the
|
|
|
|
|
Packaging:Guidelines#Writing_a_package_from_scratch[packaging
|
|
|
|
|
guidelines], new spec files should be created this way. Vim and emacs
|
|
|
|
|
can automatically create simple templates, but these are different than
|
|
|
|
|
those made with `rpmdev-newspec`. This is especially true for templates
|
|
|
|
|
with names beginning with `python-` or `-perl`.
|
|
|
|
|
|
|
|
|
|
Here is an example auto-generated `.spec` template:
|
|
|
|
|
|
|
|
|
|
`Name: testprogram` +
|
|
|
|
|
`Version: ` +
|
|
|
|
|
`Release: 1%{?dist}` +
|
|
|
|
|
`Summary: ` +
|
|
|
|
|
+
|
|
|
|
|
`License: ` +
|
|
|
|
|
`URL: ` +
|
|
|
|
|
`Source0: ` +
|
|
|
|
|
+
|
|
|
|
|
`BuildRequires: ` +
|
|
|
|
|
`Requires: ` +
|
|
|
|
|
+
|
|
|
|
|
`%description` +
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
`%prep` +
|
|
|
|
|
`%setup -q` +
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
`%build` +
|
|
|
|
|
`%configure` +
|
|
|
|
|
`%make_build` +
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
`%install` +
|
|
|
|
|
`%make_install` +
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
`%files` +
|
|
|
|
|
`%doc` +
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
`%changelog` +
|
|
|
|
|
`* Sun Apr 3 2016 makerpm` +
|
|
|
|
|
`-`
|
|
|
|
|
|
|
|
|
|
[[examples]]
|
|
|
|
|
Examples
|
|
|
|
|
++++++++
|
|
|
|
|
|
|
|
|
|
[[eject]]
|
|
|
|
|
eject
|
|
|
|
|
|
|
|
|
|
Here's a simple example showing a Fedora specfile for the `eject`
|
|
|
|
|
program:
|
|
|
|
|
|
|
|
|
|
....
|
|
|
|
|
Summary: A program that ejects removable media using software control
|
|
|
|
|
Name: eject
|
|
|
|
|
Version: 2.1.5
|
|
|
|
|
Release: 21%{?dist}
|
|
|
|
|
License: GPLv2+
|
|
|
|
|
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
|
|
|
|
|
%autosetup -n %{name}
|
|
|
|
|
|
|
|
|
|
%build
|
|
|
|
|
%configure
|
|
|
|
|
%make_build
|
|
|
|
|
|
|
|
|
|
%install
|
|
|
|
|
%make_install
|
|
|
|
|
|
|
|
|
|
install -m 755 -d %{buildroot}/%{_sbindir}
|
|
|
|
|
ln -s ../bin/eject %{buildroot}/%{_sbindir}
|
|
|
|
|
|
|
|
|
|
%find_lang %{name}
|
|
|
|
|
|
|
|
|
|
%files -f %{name}.lang
|
|
|
|
|
%license COPYING
|
|
|
|
|
%doc README TODO 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)
|
|
|
|
|
....
|
|
|
|
|
|
|
|
|
|
[[section]]
|
|
|
|
|
|
|
|
|
|
[[spec-file-overview]]
|
|
|
|
|
SPEC file overview
|
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Other useful guides:
|
|
|
|
|
|
|
|
|
|
* http://docs-old.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/[Part 3].
|
|
|
|
|
* http://ftp.rpm.org/max-rpm/[Maximum RPM] has the most complete
|
|
|
|
|
information, but is dated.
|
|
|
|
|
|
|
|
|
|
You will need to follow the Fedora guidelines:
|
|
|
|
|
link:Packaging/NamingGuidelines[Package Naming Guidelines],
|
|
|
|
|
link:Packaging/Guidelines[Packaging guidelines], and
|
|
|
|
|
link:Packaging/ReviewGuidelines[Package review guidelines].
|
|
|
|
|
|
|
|
|
|
Insert comments with a leading "`#`" character, and beware of macros
|
|
|
|
|
(beginning with `%`) that are potentially multi-line, as they are
|
|
|
|
|
expanded first. When commenting out a line, double the percent signs
|
|
|
|
|
(`%%`) of the macros appearing after the "`#`". Also avoid inline
|
|
|
|
|
comments on the same line as script commands.
|
|
|
|
|
|
|
|
|
|
The major tags are listed below. Note that the macros `%{name}`,
|
|
|
|
|
`%{version}` and `%{release}` 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 link:Packaging/NamingGuidelines[Package
|
|
|
|
|
Naming Guidelines] and generally be lowercase.
|
|
|
|
|
* *Version*: The upstream version number. See
|
|
|
|
|
link: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 `yy.mm[dd]` (e.g. `2008-05-01` becomes `8.05`).
|
|
|
|
|
* *Release*: The initial value should normally be `1%{?dist}`. 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 `1`. See
|
|
|
|
|
link:Packaging/NamingGuidelines#Release_Tag[Release tag section] of the
|
|
|
|
|
packaging guidelines. The optional link: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 "`less /usr/share/doc/rpm/GROUPS`" to
|
|
|
|
|
see the complete list. Use the group "Documentation" for any
|
|
|
|
|
sub-packages (e.g. `kernel-doc`) containing documentation. __'__Note:
|
|
|
|
|
This tag is deprecated since Fedora 17. See
|
|
|
|
|
https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide/chap-Packagers_Guide-Spec_File_Reference-Preamble.html[Spec
|
|
|
|
|
File Reference Preamble] _'_
|
|
|
|
|
* *License*: The license, which must be an open source software license.
|
|
|
|
|
Do _not_ use the old Copyright tag. Use a standard abbreviation (e.g.
|
|
|
|
|
"`GPLv2+`") and be specific (e.g. use "`GPLv2+`" for GPL version 2 or
|
|
|
|
|
greater instead of just "`GPL`" or "`GPLv2`" where it's true). See
|
|
|
|
|
Licensing and the link:Packaging/LicensingGuidelines[Licensing
|
|
|
|
|
Guidelines]. You can list multiple licenses by combining them with
|
|
|
|
|
"`and`" and "`or`" (e.g. "`GPLv2 and BSD`").
|
|
|
|
|
* *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. "`Source`" is
|
|
|
|
|
synonymous with "`Source0`". If you give a full URL (and you should),
|
|
|
|
|
its basename will be used when looking in the `SOURCES` directory. If
|
|
|
|
|
possible, embed `%{name}` and `%{version}`, 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 `Source1`, `Source2` 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 link: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
|
|
|
|
|
`~/rpmbuild/SOURCES` 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
|
|
|
|
|
"`BuildArch: noarch`". The architecture for the binary RPM will then be
|
|
|
|
|
"`noarch`".
|
|
|
|
|
* *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 "`%{_topdir}/BUILDROOT/`".
|
|
|
|
|
* *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. It is possible to ensure you have specified all necessary build
|
|
|
|
|
requires by link:Using_Mock_to_test_package_builds[performing a "mock
|
|
|
|
|
build"] of your package. You can specify a minimum version if necessary
|
|
|
|
|
(e.g. "`ocaml >= 3.08`"). If you need the file `/EGGS`, determine the
|
|
|
|
|
package that owns it by running "`rpm -qf /EGGS`". If you need the
|
|
|
|
|
program `EGGS`, determine the package that owns it by running
|
|
|
|
|
"`rpm -qf \`which EGGS\``". Keep dependencies to a minimum (e.g. use
|
|
|
|
|
`sed` instead of `perl` 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 package 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, `rpmbuild` 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
|
|
|
|
|
https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/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
|
|
|
|
|
"`%autosetup`"; a common variation is "`%autosetup -n NAME`" if the
|
|
|
|
|
source file unpacks into `NAME`. 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.
|
|
|
|
|
* *%install*: Script commands to "install" the program. The commands
|
|
|
|
|
should copy the files from the `BUILD` directory `%{_builddir}` into the
|
|
|
|
|
buildroot directory, `%{buildroot}`. See the %install section below for
|
|
|
|
|
more.
|
|
|
|
|
* *%check*: Script commands to "test" the program. This is run after the
|
|
|
|
|
%install procedure, so place it there if you have this section. Often it
|
|
|
|
|
simply contains "`make test`" or "`make check`". This is separated from
|
|
|
|
|
%build so that people can skip the self-test if they desire.
|
|
|
|
|
* *%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.
|
|
|
|
|
*Do NOT put software's changelog at here.This changelog is for RPM
|
|
|
|
|
itself.*
|
|
|
|
|
* *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
|
|
|
|
|
link:How_to_create_an_RPM_package#Subpackages[subpackages]) from a
|
|
|
|
|
single SPEC file, such as `name-libs` and `name-devel` packages.
|
|
|
|
|
|
|
|
|
|
Do *not* create a "relocatable" package; they don't add value in Fedora
|
|
|
|
|
and make things more complicated.
|
|
|
|
|
|
|
|
|
|
[[spec-file-sections-explained]]
|
|
|
|
|
SPEC file sections explained
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
[[prep-section]]
|
|
|
|
|
%prep section
|
|
|
|
|
^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
The %prep section describes how to unpack the compressed packages so
|
|
|
|
|
that they can be built. Typically, this includes the "`%autosetup`"
|
|
|
|
|
command. Alternatively, you can use "`%setup`" and "`%patch`" commands
|
|
|
|
|
with reference to the Source0 (and Source1 etc.) lines. See the
|
|
|
|
|
http://ftp.rpm.org/max-rpm/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 and %autosetup
|
|
|
|
|
is not what you want, then you can do:
|
|
|
|
|
|
|
|
|
|
`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-autosetup-command]]
|
|
|
|
|
%prep section: %autosetup command
|
|
|
|
|
+++++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
|
|
The "`%autosetup`" command unpacks a source package. Switches include:
|
|
|
|
|
|
|
|
|
|
* *`-n` _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 "`%autosetup -n FOO`".
|
|
|
|
|
* *`-c` _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.
|
|
|
|
|
|
|
|
|
|
If you use "`%setup`" command instead, then _`-q`_' is commonly used to
|
|
|
|
|
suppress unecessary output.
|
|
|
|
|
|
|
|
|
|
There are http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html[more
|
|
|
|
|
%setup options if you are unpacking multiple files], which is primarily
|
|
|
|
|
useful if you are creating subpackages (see below). The key ones are:
|
|
|
|
|
|
|
|
|
|
[cols=",",]
|
|
|
|
|
|=======================================================================
|
|
|
|
|
|`-a number` |Only unpack the Source directive of the given number after
|
|
|
|
|
changing directory (e.g. "`–a 0`" for Source0).
|
|
|
|
|
|
|
|
|
|
|`-b number` |Only unpack the Source directive of the given number
|
|
|
|
|
before changing directory (e.g. "`–b 0`" for Source0).
|
|
|
|
|
|
|
|
|
|
|`-D` |Do not delete the directory before unpacking.
|
|
|
|
|
|
|
|
|
|
|`-T` |Disable the automatic unpacking of the archives.
|
|
|
|
|
|=======================================================================
|
|
|
|
|
|
|
|
|
|
[[prep-section-patch-commands]]
|
|
|
|
|
%prep section: %patch commands
|
|
|
|
|
++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
|
|
If you have used "`%autosetup`" command, the following manual patch
|
|
|
|
|
management is not necessary. If you have complex requirements or need
|
|
|
|
|
compatibility with EPEL, you may still need this. The "`%patch0`"
|
|
|
|
|
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 "`-pNUMBER`" option applies, which passes that
|
|
|
|
|
argument onto the program `patch`.
|
|
|
|
|
|
|
|
|
|
Patch file names often look like "`telnet-0.17-env.patch`", which is the
|
|
|
|
|
format `%{name} - %{version} - REASON.patch`" (though sometimes version
|
|
|
|
|
is omitted). Patch files are typically the result of "`diff -u`"; if you
|
|
|
|
|
do this from the subdirectory of `~/rpmbuild/BUILD` then you won't have
|
|
|
|
|
to specify a `-p` 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 `BUILD` and then do subdirectory diffs. After you have
|
|
|
|
|
changed directory to "`~rpmbuild/BUILD/NAME`", do the following:
|
|
|
|
|
|
|
|
|
|
`cp -pr ./ ../PACKAGENAME.orig/` +
|
|
|
|
|
`... many edits ...` +
|
|
|
|
|
`diff -ur ../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 "`.orig`" before editing
|
|
|
|
|
them. Then, you can use "`gendiff`" (in the `rpm-build` package) to
|
|
|
|
|
create a patch with the differences.
|
|
|
|
|
|
|
|
|
|
Try to ensure that your patch match the context exactly. The default
|
|
|
|
|
"fuzz" value is "`0`", requiring matches to be exact. You can work
|
|
|
|
|
around this by adding "`%global _default_patch_fuzz 2`" 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]]
|
|
|
|
|
%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 `SOURCE1` refers to the relevant Source file):
|
|
|
|
|
|
|
|
|
|
`cp -p %SOURCE1 .`
|
|
|
|
|
|
|
|
|
|
[[build-section]]
|
|
|
|
|
%build section
|
|
|
|
|
^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
The "%build" section is sometimes complicated; here you configure and
|
|
|
|
|
compile/build the files to be installed.
|
|
|
|
|
|
|
|
|
|
Many programs follow the GNU `configure` approach (or some variation).
|
|
|
|
|
By default, they will install to a prefix of "`/usr/local`", which is
|
|
|
|
|
reasonable for unpackaged files. However, since you are packaging it,
|
|
|
|
|
change the prefix to "`/usr`". Libraries should be installed to either
|
|
|
|
|
`/usr/lib` or `/usr/lib64` depending on the architecture.
|
|
|
|
|
|
|
|
|
|
Since GNU `configure` is so common, the macro "`%configure`" can be used
|
|
|
|
|
to automatically invoke the correct options (e.g. change the prefix to
|
|
|
|
|
`/usr`). Some variation of this often works:
|
|
|
|
|
|
|
|
|
|
` %configure` +
|
|
|
|
|
` %make_build`
|
|
|
|
|
|
|
|
|
|
To override makefile variables, pass them as parameters to `make`:
|
|
|
|
|
|
|
|
|
|
` %make_build CFLAGS="%{optflags}" BINDIR=%{_bindir}`
|
|
|
|
|
|
|
|
|
|
More more information, see http://sourceware.org/autobook/["GNU
|
|
|
|
|
autoconf, automake, and libtool"] and
|
|
|
|
|
http://web.archive.org/web/20090411003817/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 `cmake`. See Packaging/cmake.
|
|
|
|
|
|
|
|
|
|
[[install-section]]
|
|
|
|
|
%install section
|
|
|
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
This section involves script commands to "install" the program, copying
|
|
|
|
|
the relevant files from `%{_builddir}` to `%{buildroot}` (which usually
|
|
|
|
|
means from `~/rpmbuild/BUILD` to `~/rpmbuild/BUILDROOT`) and creating
|
|
|
|
|
directories inside `%{buildroot}` as necessary.
|
|
|
|
|
|
|
|
|
|
Some of the terminology can be misleading:
|
|
|
|
|
|
|
|
|
|
* The "build directory", also known as `%{_builddir}` is not the same as
|
|
|
|
|
the "build root", also known as `%{buildroot}`. 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
|
|
|
|
|
`%{buildsubdir}`, which is the subdirectory within `%{_builddir}` that
|
|
|
|
|
was created during %prep stage. This is usually something like
|
|
|
|
|
`~/rpmbuild/BUILD/%{name}-%{version}`.
|
|
|
|
|
* 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 "`make install`" is performed here:
|
|
|
|
|
|
|
|
|
|
`%install` +
|
|
|
|
|
`%make_install`
|
|
|
|
|
|
|
|
|
|
Ideally you should use %make_install which is equivalent to
|
|
|
|
|
http://www.gnu.org/prep/standards/html_node/DESTDIR.html[`DESTDIR=%{buildroot}`]
|
|
|
|
|
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 `DESTDIR` (and only if), you can
|
|
|
|
|
workaround it in one of several (inferior) ways:
|
|
|
|
|
|
|
|
|
|
* Patch the makefile so that is supports `DESTDIR`. Create directories
|
|
|
|
|
inside `DESTDIR` where necessary and submit the patch upstream.
|
|
|
|
|
* Use the "`%makeinstall`" macro. This method might work, but can lead
|
|
|
|
|
to subtle failures. It expands to something like
|
|
|
|
|
"`make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install`",
|
|
|
|
|
which can result in some programs failing to work properly. Create
|
|
|
|
|
directories inside `%{buildroot}` where necessary.
|
|
|
|
|
* Consider using the `auto-destdir` package. This requires
|
|
|
|
|
"`BuildRequires: auto-destdir`", and changing "`make install`" to
|
|
|
|
|
"`make-redir DESTDIR=%{buildroot} install`". This only works well if the
|
|
|
|
|
installation uses only certain common commands to install files, like
|
|
|
|
|
`cp` and `install`.
|
|
|
|
|
* Perform the installation by hand. This would involve creating the
|
|
|
|
|
necessary directories under `%{buildroot}` and copying files from
|
|
|
|
|
`%{_builddir}` to `%{buildroot}`. Be especially careful with updates,
|
|
|
|
|
which often contain new or changed filenames. An example of this
|
|
|
|
|
procedure:
|
|
|
|
|
|
|
|
|
|
`%install` +
|
|
|
|
|
`mkdir -p %{buildroot}%{_bindir}/` +
|
|
|
|
|
`cp -p mycommand %{buildroot}%{_bindir}/`
|
|
|
|
|
|
|
|
|
|
[[check-section]]
|
|
|
|
|
%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 %install section, since files in %buildroot may be tested)
|
|
|
|
|
instead of within the %build section itself, so that they can be easily
|
|
|
|
|
skipped when necessary.
|
|
|
|
|
|
|
|
|
|
Often, this section contains:
|
|
|
|
|
|
|
|
|
|
`make test`
|
|
|
|
|
|
|
|
|
|
Sometimes it can be:
|
|
|
|
|
|
|
|
|
|
`make check`
|
|
|
|
|
|
|
|
|
|
Please explore the Makefile and choose the appropriate way.
|
|
|
|
|
|
|
|
|
|
[[files-section]]
|
|
|
|
|
%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]]
|
|
|
|
|
%files basics
|
|
|
|
|
+++++++++++++
|
|
|
|
|
|
|
|
|
|
The `%defattr` sets the default file permissions, and is often found at
|
|
|
|
|
the start of the `%files` section. Note that this is no longer necessary
|
|
|
|
|
unless the permissions need to be altered. The format of this is:
|
|
|
|
|
|
|
|
|
|
`%defattr(``, ``, ``, ``)`
|
|
|
|
|
|
|
|
|
|
The fourth parameter is often omitted. Usually one uses
|
|
|
|
|
`%defattr(-,root,root,-)`, where "`-`" 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 `%{_bindir}/mycommand` instead
|
|
|
|
|
of `/usr/bin/mycommand`). If the pattern begins with a "`/`" (or when
|
|
|
|
|
expanded from the macro) then it is taken from the `%{buildroot}`
|
|
|
|
|
directory. Otherwise, the file is presumed to be in the current
|
|
|
|
|
directory (e.g. inside `%{_builddir}`, such as documentation files that
|
|
|
|
|
you wish to include). If your package only installs a single file
|
|
|
|
|
`/usr/sbin/mycommand`, then the `%files` 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 `%{_bindir}/*` does not claim that this package owns the
|
|
|
|
|
`/usr/bin` 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
|
|
|
|
|
`%{_bindir}` 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 `%{buildroot}` has not been listed
|
|
|
|
|
|
|
|
|
|
It is also possible to exclude files from a previous match by using the
|
|
|
|
|
`%exclude` 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]]
|
|
|
|
|
%files prefixes
|
|
|
|
|
+++++++++++++++
|
|
|
|
|
|
|
|
|
|
You may need to add one or more prefixes to lines in the `%files`
|
|
|
|
|
section; seperate them with a space. See
|
|
|
|
|
http://ftp.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html[Max
|
|
|
|
|
RPM section on %files directives].
|
|
|
|
|
|
|
|
|
|
Usually, "`%doc`" is used to list documentation files within
|
|
|
|
|
`%{_builddir}` that were not copied to `%{buildroot}`. A `README` and
|
|
|
|
|
`INSTALL` file is usually included. They will be placed in an
|
|
|
|
|
appropriate directory under `/usr/share/doc`, whose ownership does not
|
|
|
|
|
need to be declared.
|
|
|
|
|
|
|
|
|
|
*Note:* If specifying a `%doc` entry, rpmbuild < 4.9.1 removes the doc
|
|
|
|
|
directory it installs files into before installing them. This means that
|
|
|
|
|
files already in it, for example installed in the `%install` section,
|
|
|
|
|
are removed and do not end up in the package. If you want to install
|
|
|
|
|
some files in the `%install` section, install them into a temporary
|
|
|
|
|
staging directory inside the build dir (not build root), for example
|
|
|
|
|
`_docs_staging`, and include them in the in the `%files` list like
|
|
|
|
|
`%doc _docs_staging/*`.
|
|
|
|
|
|
|
|
|
|
Configuration files should be placed in `/etc` 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`
|
|
|
|
|
|
|
|
|
|
"`%attr(mode, user, group)`" can be used for finer control over
|
|
|
|
|
permissions, where a "`-`" means use the default:
|
|
|
|
|
|
|
|
|
|
`%attr(0600, root, root) FOO.BAR`
|
|
|
|
|
|
|
|
|
|
If a file is in particular natural language, use `%lang` 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 `%install` step: `%find_lang ${name}`
|
|
|
|
|
* add the required build dependencies: `BuildRequires: gettext`
|
|
|
|
|
* use the found filenames: `%files -f ${name}.lang`
|
|
|
|
|
|
|
|
|
|
The `%readme` prefix is *not* valid in Fedora.
|
|
|
|
|
|
|
|
|
|
[[files-and-filesystem-hierarchy-standard-fhs]]
|
|
|
|
|
%files and Filesystem Hierarchy Standard (FHS)
|
|
|
|
|
++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
|
|
You should follow the http://www.pathname.com/fhs/[Filesystem Hierarchy
|
|
|
|
|
Standard (FHS)]. Executables go in `/usr/bin`, global configuration
|
|
|
|
|
files go in `/etc`, libraries go into `/usr/lib` (or `/usr/lib64`) and
|
|
|
|
|
so on. Executables that should not normally be executed directly by
|
|
|
|
|
users or administrators should (but are executed by other parts of your
|
|
|
|
|
package) go in a subdirectory of `/usr/libexec`, which is referred to as
|
|
|
|
|
`%{_libexecdir}/%{name}`.
|
|
|
|
|
|
|
|
|
|
Do *not* install files into `/opt` or `/usr/local`.
|
|
|
|
|
(Packaging:Guidelines#Limited_usage_of_.2Fopt.2C_.2Fetc.2Fopt.2C_and_.2Fvar.2Fopt[reference])
|
|
|
|
|
|
|
|
|
|
Unfortunately, many programs do not follow the FHS by default. In
|
|
|
|
|
particular, architecture-independent libraries get placed in `/usr/lib`
|
|
|
|
|
instead of `/usr/share`. 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
|
|
|
|
|
`/usr/share`. There are many exceptions in Fedora (such as Python, Perl
|
|
|
|
|
and Systemd), but Fedora applies this rule more strictly than some
|
|
|
|
|
distributions. `rpmlint` will generally complain if you put anything
|
|
|
|
|
other than ELF files into `/usr/lib`.
|
|
|
|
|
|
|
|
|
|
[[files-example]]
|
|
|
|
|
%files example
|
|
|
|
|
++++++++++++++
|
|
|
|
|
|
|
|
|
|
Here's a simple example of a %files section:
|
|
|
|
|
|
|
|
|
|
`%files` +
|
|
|
|
|
`%doc README` +
|
|
|
|
|
`%license LICENSE COPYING` +
|
|
|
|
|
`%{_bindir}/*` +
|
|
|
|
|
`%{_sbindir}/*` +
|
|
|
|
|
`%{_datadir}/%{name}/` +
|
|
|
|
|
`%config(noreplace) %{_sysconfdir}/*.conf`
|
|
|
|
|
|
|
|
|
|
[[finding-duplicates]]
|
|
|
|
|
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]]
|
|
|
|
|
Scriptlets
|
|
|
|
|
^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
When an end-user installs the RPM, you may want some commands to be run.
|
|
|
|
|
This can be achieved through scriptlets. See Packaging:Scriptlets.
|
|
|
|
|
|
|
|
|
|
Scriptlets can be run:
|
|
|
|
|
|
|
|
|
|
* before (*`%pre`*) or after (*`%post`*) a package is installed
|
|
|
|
|
* before (*`%preun`*) or after (*`%postun`*) a package is uninstalled
|
|
|
|
|
* at the start (*`%pretrans`*) or end (*`%posttrans`*) 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 `ldconfig` in
|
|
|
|
|
`%post` and `%postun`. 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 "`-p`" 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 "`Requires(CONTEXT)`" (e.g. `Requires(post)`).
|
|
|
|
|
|
|
|
|
|
`%pre`, `%post`, `%preun`, and `%postun` provide the argument `$1`,
|
|
|
|
|
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 `2`,
|
|
|
|
|
but instead check if they are greater than or equal to `2`. For
|
|
|
|
|
`%pretrans` and `%posttrans`, `$1` is always `0`.
|
|
|
|
|
|
|
|
|
|
For example, if the package installs an info manual, then the info
|
|
|
|
|
manual index must be updated with `install-info` from the `info`
|
|
|
|
|
package. Firstly, there is no guarantee that the `info` package will be
|
|
|
|
|
available unless we explicitly declare it as required, and secondly, we
|
|
|
|
|
don't want to fail completely if `install-info` 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
|
|
|
|
|
`install-info` command will update the info directory, so we should
|
|
|
|
|
delete the useless empty directory from the %\{buildroot} during the
|
|
|
|
|
`%install` section:
|
|
|
|
|
|
|
|
|
|
`rm -f %{buildroot}%{_infodir}/dir`
|
|
|
|
|
|
|
|
|
|
Another scriptlet-like ability are "triggers", which can be run for your
|
|
|
|
|
package when other packages are installed or uninstalled. See
|
|
|
|
|
http://ftp.rpm.org/api/4.4.2.2/triggers.html[RPM Triggers].
|
|
|
|
|
|
|
|
|
|
[[macros]]
|
|
|
|
|
Macros
|
|
|
|
|
^^^^^^
|
|
|
|
|
|
|
|
|
|
Macros are text in the format `%{string}`. Typical macros:
|
|
|
|
|
|
|
|
|
|
[cols=",,",options="header",]
|
|
|
|
|
|=======================================================================
|
|
|
|
|
|Macro |Typical Expansion |Meaning
|
|
|
|
|
|`%{_bindir}` |`/usr/bin` |Binary directory: where executables are
|
|
|
|
|
usually stored.
|
|
|
|
|
|
|
|
|
|
|`%{_builddir}` |`~/rpmbuild/BUILD` |Build directory: files are compiled
|
|
|
|
|
within a subdirectory of the build directory. See `%buildsubdir`.
|
|
|
|
|
|
|
|
|
|
|`%{buildroot}` |`~/rpmbuild/BUILDROOT/%{name}...` |Build root: where
|
|
|
|
|
files are "installed" during the `%install` stage, which copies files
|
|
|
|
|
from a subdirectory of `%{_builddir}` to a subdirectory of
|
|
|
|
|
`%{buildroot}`. (Historically, `%{buildroot}` was in "/var/tmp/".)
|
|
|
|
|
|
|
|
|
|
|`%{buildsubdir}` |`%{_builddir}/%{name}` |Build subdirectory: a
|
|
|
|
|
subdirectory within `%{_builddir}` where files are compiled during the
|
|
|
|
|
`%build` stage. It is set after `%autosetup`.
|
|
|
|
|
|
|
|
|
|
|`%{_datadir}` |`/usr/share` |Share directory.
|
|
|
|
|
|
|
|
|
|
|`%{_defaultdocdir}` |`/usr/share/doc` |Default documentation directory.
|
|
|
|
|
|
|
|
|
|
|`%{dist}` |`.fc`__`NUMBER`__ |Distribution+version short name (e.g.
|
|
|
|
|
"`.fc`")
|
|
|
|
|
|
|
|
|
|
|`%{fedora}` |_`NUMBER`_ |Number of fedora release (e.g. "")
|
|
|
|
|
|
|
|
|
|
|`%{_includedir}` |`/usr/include`
|
|
|
|
|
|
|
|
|
|
|`%{_infodir}` |`/usr/share/info`
|
|
|
|
|
|
|
|
|
|
|`%{_initrddir}` |`/etc/rc.d/init.d`
|
|
|
|
|
|
|
|
|
|
|`%{_libdir}` |`/usr/lib`
|
|
|
|
|
|
|
|
|
|
|`%{_libexecdir}` |`/usr/libexec`
|
|
|
|
|
|
|
|
|
|
|`%{_localstatedir}` |`/var`
|
|
|
|
|
|
|
|
|
|
|`%{_mandir}` |`/usr/share/man`
|
|
|
|
|
|
|
|
|
|
|`%{name}` | |Name of package, set by Name: tag
|
|
|
|
|
|
|
|
|
|
|`%{_sbindir}` |`/usr/sbin`
|
|
|
|
|
|
|
|
|
|
|`%{_sharedstatedir}` |`/var/lib`
|
|
|
|
|
|
|
|
|
|
|`%{_sysconfdir}` |`/etc`
|
|
|
|
|
|
|
|
|
|
|`%{version}` | |Version of package, set by Version: tag
|
|
|
|
|
|=======================================================================
|
|
|
|
|
|
|
|
|
|
Learn more about macros by looking in `/etc/rpm/*` and `/usr/lib/rpm`,
|
|
|
|
|
especially `/usr/lib/rpm/macros`. Also use `rpm --showrc` to show values
|
|
|
|
|
that RPM will use for macros (altered by `rpmrc` 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 "`-E`" option of `rpmbuild` to find the value of a macro in a
|
|
|
|
|
SPEC file:
|
|
|
|
|
|
|
|
|
|
`rpmbuild -E '%{_bindir}' myfile.spec`
|
|
|
|
|
|
|
|
|
|
Also see Packaging/RPMMacros and
|
|
|
|
|
https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s07.html[RPM
|
|
|
|
|
Guide chapter 9].
|
|
|
|
|
|
|
|
|
|
[[other-tags]]
|
|
|
|
|
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 "`foo`" that demands a particular
|
|
|
|
|
functionality "bar" from another program. If there are several packages
|
|
|
|
|
that can satisfy that demand, those packages can specify
|
|
|
|
|
"`Provides: bar`" and the "`foo`" package can specify "`Requires: bar`".
|
|
|
|
|
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
|
|
|
|
|
"`rpm -q --provides PACKAGENAME`" 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]]
|
|
|
|
|
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. `name-doc` and
|
|
|
|
|
`name-devel` subpackages are common for documentation and development
|
|
|
|
|
files respectively.
|
|
|
|
|
|
|
|
|
|
Use the `%package` directive to start defining a subpackage:
|
|
|
|
|
|
|
|
|
|
`%package subpackage_name`
|
|
|
|
|
|
|
|
|
|
After each `%package` directive, list the tags for the subpackage. This
|
|
|
|
|
should at least include the Summary and Group tags, as well as the
|
|
|
|
|
`%description subpackage_name` and `%files subpackage_name` directives:
|
|
|
|
|
|
|
|
|
|
Anything not specified by the subpackage will be inherited from its
|
|
|
|
|
parent.
|
|
|
|
|
|
|
|
|
|
By default, if the package name is "`foo`" and the subpackage name is
|
|
|
|
|
"`bar`", then the resulting subpackage will be "`foo-bar`". You can
|
|
|
|
|
override it with the "`-n`" 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-old.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]]
|
|
|
|
|
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 "`%else`" section; all of these are closed with
|
|
|
|
|
"`%endif`".
|
|
|
|
|
|
|
|
|
|
[[application-specific-guidelines]]
|
|
|
|
|
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
|
|
|
|
|
link: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 link:SIGs[Special Interest Group (SIG)]
|
|
|
|
|
* Special:PrefixIndex/Packaging[Wiki pages prefixed with 'Packaging']
|
|
|
|
|
|
|
|
|
|
[[miscellaneous-hints]]
|
|
|
|
|
Miscellaneous hints
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
Packaging/FrequentlyMadeMistakes has information on frequently-made
|
|
|
|
|
mistakes. There are also some recommendations and controversial tricks
|
|
|
|
|
on link:PackageMaintainers/Packaging_Tricks[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 `chkconfig` or `systemctl` 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 `name-debug`
|
|
|
|
|
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 `%install`
|
|
|
|
|
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} <= `
|
|
|
|
|
|
|
|
|
|
The `?` causes the macro to evaluate to evaluate to blank if `%fedora`
|
|
|
|
|
is not defined. This causes the end result to be the `0` (which is a
|
|
|
|
|
number and thus fine), while not interfering with the result if there is
|
|
|
|
|
actually a value for `%fedora`. (Note that this trick does not work in
|
|
|
|
|
Koji "scratch" builds, where `%fedora` 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 `.desktop` files, see
|
|
|
|
|
link: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 `/usr/share/icons`, see
|
|
|
|
|
http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html[icon
|
|
|
|
|
theme spec].
|
|
|
|
|
|
|
|
|
|
[[building-the-binary-package]]
|
|
|
|
|
Building the binary package
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
[[test-with-rpmlint]]
|
|
|
|
|
Test with rpmlint
|
|
|
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
To catch many common errors early, run `rpmlint` 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 "`-i`"
|
|
|
|
|
option for longer messages.
|
|
|
|
|
|
|
|
|
|
Aim to have no errors, but sometimes `rpmlint` reports false positives.
|
|
|
|
|
The link:Packaging/Guidelines#Use_rpmlint[Fedora packaging guidelines]
|
|
|
|
|
explains which ones to ignore.
|
|
|
|
|
|
|
|
|
|
[[create-binary-rpms-from-the-spec-file]]
|
|
|
|
|
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 `~/rpmbuild/RPMS` and SRPMS
|
|
|
|
|
will be created within `~/rpmbuild/SRPMS`.
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
"`--short-circuit`" option. For example, to restart at the `%install`
|
|
|
|
|
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 `%prep` or
|
|
|
|
|
`%build` or other stages), run this:
|
|
|
|
|
|
|
|
|
|
`rpmbuild -bs program.spec`
|
|
|
|
|
|
|
|
|
|
[[testing-binary-rpms-with-rpmlint]]
|
|
|
|
|
Testing binary RPMS with rpmlint
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
`rpmlint` can be run on SPEC files, RPMS and SRPMS to check for errors.
|
|
|
|
|
You need to eliminate or justify warnings before posting a package.
|
|
|
|
|
link:Common_Rpmlint_issues[This page] offers explanations for some of
|
|
|
|
|
the common issues that come up. If you are in the SPECS directory, do
|
|
|
|
|
this:
|
|
|
|
|
|
|
|
|
|
`$ rpmlint `__`NAME`__`.spec ../RPMS/*/`__`NAME`__`*.rpm ../SRPMS/`__`NAME`__`*.rpm`
|
|
|
|
|
|
|
|
|
|
Enter the `~/rpmbuild/RPMS` 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 `.desktop` entry is wrong.
|
|
|
|
|
|
|
|
|
|
Uninstall packages later by doing:
|
|
|
|
|
|
|
|
|
|
`# rpm -e package1 package2 package3`
|
|
|
|
|
|
|
|
|
|
[[mock-and-koji]]
|
|
|
|
|
Mock and Koji
|
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
link: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
|
|
|
|
|
link:Using_Mock_to_test_package_builds[Using Mock to test package
|
|
|
|
|
builds]. Once your account is a member of the "`mock`" group, you can
|
|
|
|
|
run commands like this to do local testing:
|
|
|
|
|
|
|
|
|
|
`$ mock -r fedora-23-i386 rebuild path_to_source_RPM`
|
|
|
|
|
|
|
|
|
|
You can use Koji (which uses `mock`) 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 f23 path_to_source_RPM`
|
|
|
|
|
|
|
|
|
|
Replace `f23` with any later release of Fedora, or `rawhide`.
|
|
|
|
|
|
|
|
|
|
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, submit a Koji buildroot
|
|
|
|
|
override request via Bodhi. If it's not your own package you depend on,
|
|
|
|
|
contact its maintainer(s). [Before Bodhi could handle Koji buildroot
|
|
|
|
|
override requests, the old method has been to 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]]
|
|
|
|
|
Helpful tools
|
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The `rpmdevtools` package has a number of helpful tools;
|
|
|
|
|
"`rpm -qil rpmdevtools`" will show you what it installs.
|
|
|
|
|
|
|
|
|
|
* `rpmdev-bumpspec` : 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`
|
|
|
|
|
|
|
|
|
|
DNF download plugin (from core DNF plugins) is also useful:
|
|
|
|
|
|
|
|
|
|
* `dnf download` : download the SRPM of the package by running:
|
|
|
|
|
|
|
|
|
|
`dnf download --source PACKAGENAME`
|
|
|
|
|
|
|
|
|
|
The `auto-buildrequires` package has a pair of nice tools for helping to
|
|
|
|
|
figure out the proper BuildRequires entries. After installing this
|
|
|
|
|
package, replace "`rpmbuild`" with "`auto-br-rpmbuild`" 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.
|
|
|
|
|
|
|
|
|
|
If you are thinking about packing your rpm for Fedora, be sure you run
|
|
|
|
|
your packages through https://fedorahosted.org/FedoraReview/[Fedora
|
|
|
|
|
Review], which helps ensure that you comply to the
|
|
|
|
|
Packaging:Guidelines[Packaging Guidelines].
|
|
|
|
|
|
|
|
|
|
Finally,
|
|
|
|
|
https://github.com/alanfranz/docker-rpm-builder[docker-rpm-builder] (APL
|
|
|
|
|
2.0) uses http://www.docker.com[Docker] to build RPM packages; while
|
|
|
|
|
using rpmbuild requires building on the same host distro as the target,
|
|
|
|
|
and mock works fine on Fedora/Centos/RHEL distributions for any target,
|
|
|
|
|
*this last tool works fine whenever Docker can run*.
|
|
|
|
|
|
|
|
|
|
If you want to build your package for diferent distribution and
|
|
|
|
|
architectures and to have publicly accesible dnf repository, you can
|
|
|
|
|
submit your src.rpm to https://copr.fedoraproject.org[Copr].
|
|
|
|
|
|
|
|
|
|
If you need to sign your new package, use `rpmsign` tool from `rpm-sign`
|
|
|
|
|
package.
|
|
|
|
|
|
|
|
|
|
[[guidelines-and-rules]]
|
|
|
|
|
Guidelines and rules
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
When you create your packages, you'll need to follow the following rules
|
|
|
|
|
and guidelines:
|
|
|
|
|
|
|
|
|
|
* link: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.
|
|
|
|
|
|
|
|
|
|
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 :Category:Packaging_guidelines_drafts[draft guidelines
|
|
|
|
|
category] and link:PackagingDrafts[Packaging Drafts To Do].
|
|
|
|
|
|
|
|
|
|
You might find ideas from http://en.opensuse.org/Packaging[SuSE],
|
|
|
|
|
http://www.debian.org/doc/debian-policy/[Debian], but
|
|
|
|
|
http://www.mail-archive.com/distributions@lists.freedesktop.org/msg00156.html[distributions
|
|
|
|
|
differ in their rules], so do not presume they can be used directly.
|
|
|
|
|
|
|
|
|
|
*The .spec files that you create must be open source software, as noted
|
|
|
|
|
in the Legal:Fedora_Project_Contributor_Agreement[FPCA].*
|
|
|
|
|
|
|
|
|
|
[[maintaining-the-package]]
|
|
|
|
|
Maintaining the package
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Once your package has been accepted, you and your co-maintainers will
|
|
|
|
|
need to maintain it. See link:Package_update_HOWTO[Package update HOWTO]
|
|
|
|
|
and link:Package_update_guidelines[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]]
|
|
|
|
|
For more information
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The :Category:Package_Maintainers[Package Maintainers] page links to
|
|
|
|
|
many other useful pages, and the link:Package_update_HOWTO[Package
|
|
|
|
|
update HOWTO] describes how to update an existing package you already
|
|
|
|
|
maintain in Fedora.
|
|
|
|
|
|
|
|
|
|
For more information, outside of the Fedora Wiki, see:
|
|
|
|
|
|
|
|
|
|
* https://developer.fedoraproject.org/deployment/rpm/about.html[A brief
|
|
|
|
|
RPM Packaging overview] on the Fedora Developer Portal
|
|
|
|
|
* 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 an IRC session on packaging and you can refer to
|
|
|
|
|
the logs at
|
|
|
|
|
https://fedoraproject.org/wiki/Building_RPM_packages_%2820090405%29
|
|
|
|
|
|
|
|
|
|
* http://ftp.rpm.org/max-rpm/[Maximum RPM Book] - most complete
|
|
|
|
|
information, but in some cases old/obsolete
|
|
|
|
|
* http://docs-old.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://web.archive.org/web/20100109050207/http://docs.fedoraproject.org/developers-guide/ch-rpm-building.html[Developer's
|
|
|
|
|
guide, section on building RPMs] - via archive.org, disappeared in 2010
|
|
|
|
|
|
|
|
|
|
* http://freshrpms.net/docs/fight/["The fight", Mattias Saou's first
|
|
|
|
|
attempt to make a readable rpm package building introduction. ca. 2003]
|
|
|
|
|
|
|
|
|
|
* http://en.tldp.org/HOWTO/RPM-HOWTO/index.html[RPM HOWTO: RPM at Idle
|
|
|
|
|
by Donnie Barnes]
|
|
|
|
|
|
|
|
|
|
* 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://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:Package Maintainers]
|
|
|
|
|
Category:How_to[Category:How to]
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
See a typo, something missing or out of date, or anything else which can be
|
2017-11-10 15:16:19 +00:00
|
|
|
|
improved? Edit this document at https://pagure.io/fedora-docs/quick-docs.
|