include("site.inc"); $template = new Page; $template->initCommon(); $template->displayHeader(); ?>
This chapter attempts to discuss how to build RPMs so that the package conforms to Fedora Project standards. It does not attempt to explain everything there is to know about RPM or building RPMs.
A good source for learning more about RPM is the Red Hat RPM Guide by Eric Foster-Johnson; Red Hat Press.
This section describes how the spec file should be written.
Name: foo
Summary: The foo package does foo
Version: 1.0
Release: 1
License: GPL
Group: Applications/Internet
URL: http://www.example.org/
Source0: %{name}-%{version}.tar.gz
Patch0: foo-1.0-iconfix.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
Requires: anything
Prereq: something
BuildPrereq: something-else
%description
This package performs the foo operation.
%prep
%setup -q
%patch0 -p1 -b .iconfix
%build
%configure
make
%install
rm -fr %{buildroot}
%makeinstall
%clean
rm -fr %{buildroot}
%post
/sbin/chkconfig --add foo
/sbin/ldconfig
%preun
if [ "$1" = 0 ]; then
/sbin/service foo stop > /dev/null 2>&1
/sbin/chkconfig --del foo
fi
%postun
if [ "$1" -ge "1" ]; then
/sbin/service foo condrestart > /dev/null 2>&1
/sbin/ldconfig
fi
%files
%defattr(-,root,root)
%{_bindir}/*
%{_mandir}/*
%{_datadir}/*
%{_doc}/*
%changelog
* Mon Jun 16 2003 Some One <one@example.com>
— fixed the broken frobber (#86434)
Name
The name of the package.
Summary
A short summary of the purpose of the package, should not include the name of the package in the summary as this is redundant information.
Version
The version of the package. Should match the version of the (main) tarball of the source. If the "real" version has dashes in it, replace them with underscores.
Release
This is the Fedora Project release count for the package. Each time it is modified for the Fedora Project (sent through the build system) this number must be incremented. NEVER rebuild a package without incrementing this number, as this gives a totally false impression to the user — that the package has not changed at all. Whenever a package is rebuilt, it changes, even if the source code was not updated.
License
One of GPL, LGPL, BSD(-like), Artistic, etc. Most old packages erroneously call this the "Copyright" field. This is incorrect but the two are synonyms for each other. Fix old packages to have the correct tag if found.
Group
This must be one of the canonical groups from the
/usr/share/doc/rpm-
file. Do not make up group names.<version>
/GROUPS
URL
The Web address for the package, if one exists.
Source
Start numbering the sources at 0
(Source0
,
Source1
, etc.). A tag of
Source
is implicitly source
0. Include the full URL or path to the source package if
necessary. If a filename without a URL or path is given as the
source, the file should be in the SOURCES
directory under your top level directory —
/usr/src/redhat/SOURCES/
by default or define
the top level directory in your ~/.rpmmacros
file.
Use the special macros %name
and %version
where possible so
that updating these particular fields automatically update the
source field.
Patch
Start numbering patch files with 0
(Patch0
,
Patch1
, etc.). To make patches,
name them in the format
<name>
-<version>
-<whatisfixed>
.patch.
Do not use the %name
and
%version
macros here; chances are
these patches may be needed even when you upgrade the package
source code after generating the initial patch, and it will
probably apply without modifications. If you use the macros, you
will have to rename or regenerate your
patch. Please send any patches that you make
to the upstream package maintainer at the time you generate them,
as well as any hacks you have to do in your spec file to get
things to build cleanly. Only if we make a better effort to do
this will the tons of little changes we have to make in our own
packages be integrated upstream over time.
To create a patch, follow this process:
Enter the directory where the source code for the package
is, and copy the original file to the same name as the file
with the <whatisfixed>
string
appended to it. For example, if the the old file was called
sourcecode.c
, copy it to
sourcecode.c.iconfix
.
Then, make your edits/changes/fixes to the file
sourcecode.c
.
Go into the directory one level above the sourcecode,
usually the directory ../BUILD
. Use the
gendiff
command from the
rpm
package to generate the patch
file:
gendiff <source-dir>
<fixed-extension>
> ../SOURCES/<source-dir>
-<fixed-extension>
.patch
For example, if the source code is in the directory
program-1.0/
, and the backup file was
appended with the string iconfix
, the
command would be as follows:
gendiff sourcecode-1.0 .iconfix > ../SOURCES/sourcecode-1.0-iconfix.patch
Buildroot
Make sure you use the special
%{_tmppath}
macro. Do not
hard code /tmp/
or
/var/tmp/
because users or the build system
may have configured RPM to put temporary files elsewhere or may
declared a different location for temporary files. Use the name
and version macros so that two different versions of the package
can be built at the same time without collisions.
Requires
If your package requires other packages to be on the system at
the time of installation, list them here. Include versions if
necessary (for example, somepackage >= 2.0). Multiple entries must
be separated by a space or a comma. Explicit file dependencies may
be listed rather than package dependencies by giving the full path
(for example, /sbin/chkconfig
).
Prereq
Similar to Requires
, except
that this tag lists packages or files that are required to be
present before the package is actually installed. Very important
if you are packaging something that needs to make use of other
programs in %pre
or
%post
sections.
BuildPrereq
If your package needs other packages installed to build, list
them after this tag. Examples include
gtk2-devel
and
db3-devel
.
%description
Make your description as complete as possible, but not more than 10-15 lines of text. If other packages are necessary, or this package works with others, it is probably wise to describe the specifics of that operation here.
%prep
This phase should unpack the source code and apply any patches
necessary for the build. Additionally, if autoconf and/or automake
needs to be rerun, do so here. You usually unpack source code with
the %setup
macro, and usually
provide the -q
flag so that it is quiet while
unpacking:
%setup -q
Other options to %setup
include:
-a
,
where <num>
<num>
is the number
given the source file such as 0 for source0, means that only
the source files specifies should be unpacked. The files are
unpacked after changing to the
directory.
-b
,
where <num>
<num>
is the number
given the source file such as 0 for source0, means that only
the source files specifies should be unpacked. The files are
unpacked before changing to the
directory.
-c
is used to create the
directory before unpacking the sources.
-n
can be
used to specify the directory name<name>
-D
specifies that the
directory should not be deleted before unpacking.
While applying patches, be sure to provide the
-b
argument followed by the string you used in
the name of the patch file:
%patch0 -p1 -b .<fixupstring>
%build
Include the command necessary to build the program in this
section (for example, make
).
Always use the %configure
macro where possible. This macro expands to automatically
configure properly packaged programs that use autoconf and
automake. It sets up all the paths and optimized CFLAGS correctly
for whatever version of Fedora Core you are building on. If you need to
provide extra flags, do so after the
%configure
entry. Example:
%configure --extra-flag=yes
%install
Include all the command needed to install the package.
Usually you want to clean out any old buildroots that might be lying around before actually installing files into it:
rm -fr %{buildroot}
%makeinstall
Like the %configure
macro,
the %makeinstall
macro correctly
installs a autoconf/automake style package into your
buildroot. Use it where possible.
%clean
Supply a command to clean up your buildroot. Usually the
command rm -fr %{buildroot}
suffices.
%post
Include anything that needs to happen immediately after
package installation. For example, if the package includes an
initscript that needs to be run to start the service. Another
example is if the ldconfig
command needs to be
run after installing or upgrading any system libraries. Provide
the full path to the commands.
%preun
Similar to the %post
section,
but run right before a package is removed. For example, it can
check what the package reference count is. This is important to
know whether you are upgrading a package (which involves
installing a new version and then removing an old version) or just
uninstalling the package. In an upgrade, the reference count check
on the $1 variable returns a number greater than 1 (corresponding
to the number of packages with that name still installed). When
it is being uninstalled, it will return 0.
If you are going to stop a service and remove it from use in your %preun section, you want to make sure you are really removing the package, and not just upgrading.
%postun
Similar to the %preun
section, but run after a package is removed. In this example, the
service is restarted if and only if it remains on the system. We
do this in the postuninstall phase of the "old" package. If the
reference count on the package name is greater than or equal to
one, we know the package is still on the system (for example, it
was upgraded, not removed), and the service is restarted if it was
already running with the condrestart
directive.
Warning | |
---|---|
All script sections of an RPM, including
|
%files
List the files that should be included in the package. The
files listed here are displayed when the rpm
-ql
command is issued for the package.
A package should not put a file in a directory that it does not own and that none of its dependencies own. If this happens, the file is removed when the package is removed, but the directory is not.
Another common mistake is to put a file in a directory that
another package owns without adding a dependency on that
package. For example, assume mypkg
owns the
/foo/
directory and
yourpkg
owns the
/foo/bar
file. If both packages are installed
and then mypkg
is removed, the
/foo
directory is not removed because it is
not empty. And when yourpkg
is removed, the
file is removed, but the directory is not.
In summary, make sure the package owns all the directories it uses or you depend on packages that do.
Use the FHS transparent macros that are defined on a per-platform basis so the package is portable back to older versions of Fedora Core if the locations for these special directories change.
Other macros for directories include:
%{_bindir}
—
bin
directory for the system
%{_mandir}
—
the default directory for manual pages
%{_datadir}
—
the default share
directory location
%{_defaultdocdir}
—
the default directory for documentation
The %defattr
macro
specifies what the default permissions, user, and group are for files
found in the %files
section. In
almost every case specify the following:
%defattr(-,root,root,-)
It is is in the form (
. If a dash (-) is
specified for any field, whatever the actual
permissions/ownership of the file in the buildroot are at
packaging time are used instead.file
permissions
, owner
,
group
, directory
permissions
)
If necessary, specify attributes on a particular file can also
be specified to make sure they are correct. For instance, to make
sure a file has the mode
0400
:
%attr(0400,root,root) /etc/readonlyrootfile
If the file is a directory, it can be marked as a directory
with the %dir
prefix.
%dir
is only required if the
directory only (and not the files under it) should be packaged
(or package the files under it with different flags).
Listing a directory only includes the directory, not the file in
it and not any of its subdirectories.
%dir %{_datadir}/%{name}
If the file is a documentation file, mark it with the
%doc
prefix. The paths are
relative to the RPM build directory. For example:
%doc doc/*
If it is a configuration file it should be marked as follows:
%config <filename>
If the configuration file should not be replaced when the RPM is upgraded, mark it as follows:
%config(noreplace) <filename>
For files that should be included in the list of files so that they are uninstalled when the package is removed but may not exist until they are created during post-install should be marked as follows:
%config(missingok) <filename>
%changelog
Supply a changelog entry whenever a change to a package is
made. It must be in proper format as shown in the example. Be as
descriptive as possible; sentences such as fixed
bug
does not example what has been fixed. If the
changes include a fix for a bug filed in Bugzilla, include the
Bugzilla number in the changelog entry.