From Fedora Project Wiki

(→‎%build section: Point to some documentation)
(Replace with a deprecation notice and a link to docs.fp.o)
Tag: Replaced
 
(442 intermediate revisions by 75 users not shown)
Line 1: Line 1:
== Creating Package HOWTO ==
{{autolang|base=yes}}


This page describes the basic mechanics of how to create an RPM package specifically for Fedora (such as
{{admon/important|deprecated|As part of documentation move to docs.fp.o, this page has moved to https://docs.fedoraproject.org/en-US/quick-docs/creating-rpm-packages}}
how to create a .spec file).  It also gives some practical warnings about stuff that will or won't work, which may save you hours of time later.
This is ''not'' the list of official package guidelines for Fedora (though it ''should'' be compatible with them).
This doesn't go into depth on some issues, but it does point to other documents that do.  Unlike many RPM Howto documents, this document tends to be more up-to-date and explains the specifics for Fedora, because it is maintained through the Fedora Wiki.
 
If you plan to create an RPM package for the Fedora repository, follow the process for
[[PackageMaintainers/Join|How to join the Fedora Package Collection Maintainers]],
including following the various Fedora guidance.
 
Nearly all Linux distributions can install and uninstall programs as "packages".
Fedora, and many other Linux distributions, use the "RPM" format for packages.
There are tools that make it easy to create RPM packages; the key is to write
a ".spec" file that explains to RPM how to build and install the program.
This page describes how to create RPM packages specifically for Fedora, concentrating
on that very important ".spec" file.
 
== Setting up ==
 
Before you create RPM packages on Fedora, you need to install some core
development tools and set up the account(s) you will use.  As root (don't type the "#"!):
  # yum groupinstall "Development Tools"
  # yum install rpmdevtools
 
It's strongly recommended that you create a new "dummy user" specifically for
creating rpm packages.  That way, if something goes terribly wrong, the
program or build process can't trash your files, or
send your private files/keys to the world. At the very least,
you should normally ''not'' create your packages as user root.
You can create a new user named "makerpm" quickly by doing:
  # /usr/sbin/useradd makerpm
 
Then log in as that special dummy user (makerpm).
 
Once you're logged in as the user who is creating packages,
create the directory structure in your home directory by executing (don't type the "$"):
  $ rpmdev-setuptree
 
The "rpmdev-setuptree" program will create an "rpmbuild" directory in your $HOME
directory. Underneath "rpmbuild" are a set of subdirectories
(such as SPECS and BUILD), which you will use for creating your packages.
The "rpmdev-setuptree" also creates an "~/.rpmmacros" file which will cause
rpm and rpmbuild to use them when appropriate.
 
One you've set up your system and user account, you won't normally need
to do these again.
 
== Setting up to package a particular program ==
 
If there are special programs that are required to build or run the program you are packaging, install those
other programs and write down what they were (you'll need that information).
 
To package a program, you ''must'' package pristine (original) sources, along
with the patches and build instructions.
It's generally ''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 your "makerpm" account).
 
Read through the manual installation instructions for your program;
you're going to be automating this by editing a ".spec" file, so you have
to understand what you're supposed to do first.
It's probably best if you try a "dry run", going through its installation
procedure without trying to do it via RPM first
(that's especially true if you're not familiar with RPM).
 
Try to reuse what you can.
Obviously, make sure you aren't packaging something that is already packaged;
you can find a list of existing packages in Fedora Package Collection in the [https://admin.fedoraproject.org/pkgdb/packages/ Fedora Package Database].
Also check the [[PackageMaintainers/InProgressReviewRequests | In Progress Review Requests]] (for packages that are currently being reviewed)
and the [[PackageMaintainers/RetiredPackages | Retired Packages]] list.
Failing that, see if someone has already started to package it for Fedora.
Google for "PROGRAMNAME Fedora rpm" or similar... maybe you can pick up where
they started.
You can use
http://cvs.fedoraproject.org/viewcvs/rpms/
directly view .spec files (and patches) of any similar packages already in Fedora.
You can download the source RPMs and install them, too;
go to a [http://mirrors.fedoraproject.org/publiclist Fedora mirror]'s http or ftp page,
select releases/9/Everything/source/SRPMS
(replace "9" with the Fedora release you want),
and download the source RPMs you want (they end in .src.rpm).
If you followed the directions above, you can install the source RPM
(which places its .spec file into ~/rpmbuild/SPECS and source files in ~/rpmbuild/SOURCES)
by running:
$ rpm -ivh PROGRAMNAME-*.src.rpm
 
''Sometimes'' it's easiest to start with an existing package, and then clean it up for Fedora.
[http://rpmfind.net/ RPM Find] may help you find rpm's for non-Fedora systems.
(You can install source RPMs for other systems the same way as for Fedora).
Failing that, you might look at the source package files (not the .deb binary package files)
for [http://packages.ubuntu.com/ Ubuntu] or
[http://www.debian.org/distrib/packages Debian]
(source package files are standard tarballs with a "debian/" subdirectory, possibly
associated with patch files).
If the [http://www.freebsd.org/ports/installing.html FreeBSD ports collection] has it,
you could
[ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz download the FreeBSD ports tarball]
and see if their packaging information helps as a starting point.
'''However''', this is sometimes not helpful at all.
Different distributions have different rules, and what they do may be quite
inappropriate for Fedora.
 
== Creating a spec file ==
 
You now need to create a ".spec" file in the "~/rpmbuild/SPECS" directory.
Generally, you'll name it after the program, e.g., "program.spec".
 
=== Creating a blank spec file ===
 
When you're creating a spec file for the first time, create its initial version using emacs or vim;
they will automatically create a template for you.  E.G.:
  $ cd ~/rpmbuild/SPECS
  $ vi program.spec
 
Here's an example of what that template will look like:
Name:
Version:
Release: 1%{?dist}
Summary:
Group:
License:
URL:
Source0:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires:
Requires:
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%doc
%changelog
 
 
You may have $RPM_BUILD_ROOT instead of %{buildroot}; just be consistent.
 
=== An example: eject ===
 
Here's a simple example, a Fedora 9 package for the "eject" program:
 
Summary: A program that ejects removable media using software control.
Name: eject
Version: 2.1.5
Release: 11%{dist}
License: GPL
Group: System Environment/Base
Source: http://metalab.unc.edu/pub/Linux/utils/disk-management/%{name}-%{version}.tar.gz
Source1: eject.pam
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
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
URL: http://www.pobox.com/~tranter
ExcludeArch: s390 s390x
BuildRequires: gettext
BuildRequires: automake
BuildRequires: autoconf
BuildRequires: libtool
%description
The eject program allows the user to eject removable media (typically
CD-ROMs, floppy disks or Iomega Jaz or Zip disks) using software
control. Eject can also control some multi-disk CD changers and even
some devices' auto-eject features.
Install eject if you'd like to eject removable media using software
control.
%prep
%setup -q -n %{name}
%patch1 -p1 -b .versbose
%patch2 -p1 -b .timeout
%patch3 -p0 -b .opendevice
%patch4 -p0 -b .spaces
%patch5 -p0 -b .lock
%patch6 -p1 -b .umount
%build
%configure
make
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
# pam stuff
install -m 755 -d %{buildroot}/%{_sysconfdir}/pam.d
install -m 644 %{SOURCE1} %{buildroot}/%{_sysconfdir}/pam.d/%{name}
install -m 755 -d %{buildroot}/%{_sysconfdir}/security/console.apps/
echo "FALLBACK=true" > %{buildroot}/%{_sysconfdir}/security/console.apps/%{name}
install -m 755 -d %{buildroot}/%{_sbindir}
pushd %{buildroot}/%{_bindir}
mv eject ../sbin
ln -s consolehelper eject
popd
%find_lang %{name}
%clean
rm -rf %{buildroot}
%files -f %{name}.lang
%defattr(-,root,root)
%doc README TODO COPYING ChangeLog
%attr(644,root,root) %{_sysconfdir}/security/console.apps/*
%attr(644,root,root) %{_sysconfdir}/pam.d/*
%{_bindir}/*
%{_sbindir}/*
%{_mandir}/man1/*
%changelog
* Wed Apr 02 2008 Zdenek Prikryl <zprikryl at, redhat.com> 2.1.5-11
- Added check if device is hotpluggable
- Resolves #438610
 
This is an old spec file, so its "BuildRoot:" value is old;
you should normally use the "BuildRoot:" entry from the template instead.
 
=== Spec file pieces explained ===
The [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch-creating-rpms.html RPM Guide, section on creating RPMs],
describes the details of how to fill in a spec file.
The developWorks series "Packaging software with RPM" [http://www.ibm.com/developerworks/library/l-rpm1/ Part 1], [http://www.ibm.com/developerworks/library/l-rpm2/ Part 2], and [http://www.ibm.com/developerworks/library/l-rpm3.html Part 3] is also handy.
[http://rpm.org/max-rpm-snapshot/ Maximum RPM] has the most complete information, but is dated.
 
You will need to follow the Fedora guidelines, such as the
[[Packaging/NamingGuidelines| Package Naming Guidelines]],
[[Packaging/Guidelines| Packaging Guidelines]], and
[[Packaging/ReviewGuidelines|Package review guidelines]].
 
You can insert comments with a leading "#" character, but
don't insert potentially-multiline-macros (words beginning with "%") in a comment
(macros are expanded first); if you're commenting out a line, double the percent signs ("%%").  Also, don't use inline comments ("#") on the same line after
a script command.
 
Here are the major fields/areas that you will need to fill in:
* Name: The (base) name of the package.  It must follow the [[Packaging/NamingGuidelines| Package Naming Guidelines]].
* Version: The upstream version number. See [http://fedoraproject.org/wiki/Packaging/NamingGuidelines#Package_Version Packaging/Naming guidelines - package version] for more information. If the version is non-numeric (contains tags that are not numbers or digits), you may need to include the additional non-numeric characters in the release field.
* Release: This starts as "1%{?dist}"; increment the number every time you release a new package for the same version of software.  If a new version of the software being packaged is released, the version number should be changed to reflect the new software version, and the release number should be reset to 1.  See [http://fedoraproject.org/wiki/Packaging/NamingGuidelines#Package_Release Name Guidelines - package release] for more. [[Packaging/DistTag]] describes the "dist" tag, which isn't required but can be useful.
* Summary: A brief, one-line summary of the package. Use American English, and ''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.  If you create a sub-package "...-doc" with documentation, use the group "Documentation".
* License: Its license; for software, this must be an open source software license.  Use a standard abbreviation, e.g., "GPLv2+".  Try to be specific, e.g., use "GPLv2+" (GPL version 2 or greater) instead of just "GPL" or "GPLv2" where it's true.  See the [[Packaging/LicensingGuidelines| Licensing Guidelines]] for more information.  Call this tag "License"; don't use the older, inaccurately named tag "Copyright".
* URL: The URL for more information about the program, e.g., the project website.  Note: This is NOT where the original source code came from, see "Source" (next!).
* Source0: The URL for the compressed archive containing (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.  (Note: This is different than "URL", which provides the URL to the project website.)  As noted in the guidelines, "When downloading sources, patches etc, consider using a client that preserves the upstream timestamps. For example wget -N or curl -R. To make the change global for wget, add this to your ~/.wgetrc: timestamping = on, and for curl, add to your ~/.curlrc: -R."
* BuildRoot: This is where files will be "installed" during the "%install" process (which happens after the %build compilation process).  Normally you should just leave this line alone; under the usual Fedora setup, this will be a special newly-created directory under /var/tmp.
* BuildRequires: A comma-separated list of packages required for building.  These are ''not'' automatically determined, so you need to work to include ''everything'' needed to build the program.  There are a few packages that are so common in builds that you don't need to mention them, such as "gcc"; see the [[Packaging/Guidelines| Packaging Guidelines]] for the complete list of the packages you may omit.  You can also specify minimum versions, if necessary.
* Requires: A comma-separate list of packages that are required to execute.  Note that the list of packages for ''Requires'' (what's required when running) and ''BuildRequires'' (what's required to build the binary RPM) are independent; a package may be in one list but not the other.  The "Requires" list is automatically determined by rpm, so normally you don't need to put anything here. But if you want to highlight some specific packages as being required, or require a package that rpm can't detect should be required, then add it here.
* %description - A longer, multi-line description of the program.  Use American English. All lines must be 80 characters or less.
* %prep - Script commands to "prepare" the program, that is, to uncompress it so that it will be ready for building (compiling).  Typically this is just "%setup -q" or some variation of it; a common variation is "%setup -q -n NAME" if the source file unpacks into NAME. See the "%prep" section below for more.
* %build - Script commands to "build" the program, that is, 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} (which would be under ~/rpmbuild/BUILD) into the buildroot directory, %{buildroot} (which would normally be under /var/tmp). See the "%install" section below for more.
* %clean - instructions to clean out the build root. Typically:
rm -rf %{buildroot}
* %files - the list of files that will be installed.  See the "%files" section below for more.
* %changelog - Changes in the package.  Use the format example above.
* ExcludeArch: If the package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in an ExcludeArch 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.  The scriptlets in %pre and %post are run before and after a package is installed (respectively). The scriptlets %preun and %postun are run before and after a package is uninstalled. The scriptlets %pretrans and %posttrans are run at start and end of a transaction.  See [[Packaging/ScriptletSnippets]] for more examples and details.  For example, every binary RPM package which stores shared library files (not just symlinks) in any of the dynamic linker's default paths, must call ldconfig in %post and %postun (post-install and post-uninstall). If the package has multiple subpackages with libraries, each subpackage should also have a %post/%postun section that calls /sbin/ldconfig. For example:
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
 
Don't use the tags "Packager" or "Vendor".  Don't use "Copyright" - use "License" instead.
Don't create a "relocatable" package - they don't add value in Fedora yet they make things more complicated.
 
RPM supports subpackages, that is, a single spec file can generate many
binary packages.  For example, if the documentation is very large, you might generate
a separate "doc" subpackage.
[http://docs.fedoraproject.org/drafts/rpm-guide-en/ch10s04.html RPM Guide chapter 10] discusses how to create subpackages.
 
=== %prep section ===
The "%prep" section describes how to unpack the compressed packages so that they can be built.
Typically, this is a set of "%setup" and/or %patch commands, which reference the Source0:, Source1:, etc. lines above.
See the [http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html Maximum RPM section on %setup and %patch] for more details. 
 
Don't use in-line comments (a "#" comment on the same line after a command), and don't put macros (words beginning with "%") in a comment unless you quote the "%" as "%%" (macros can cause failures if they are in a comment).
 
Sometimes, you'll package just a straight file that doesn't need to be uncompressed, e.g., a "Source1:" that is just a simple PDF file.  You can "prep" those into the build directory by doing this (replace "1" with whatever number it is):
  cp -p %SOURCE1 .
 
=== %build section ===
 
The "%build" section is sometimes complicated; here you configure and compile/build the files to be installed.
 
Many programs follow the GNU configure approach (or some variation).  By default, they will install to a prefix of "/usr/local" (/usr/local/bin, /usr/local/lib, etc.), which is a reasonable default for unpackaged files - but since you ''are'' packaging it, you will want to change the prefix to "/usr". Often some variation of this will work:
  %configure
  make %{?_smp_mflags}
 
Sometimes you'll want to override the variables of a makefile; you can easily do that by passing them as parameters to make, like this:
make %{?_smp_mflags} CFLAGS="${CFLAGS:-%optflags}" BINDIR=%{_bindir}
 
If you need to do something complicated with GNU-generated configure, take a look at [http://sourceware.org/autobook/ "GNU autoconf, automake, and libtool"].  A good presentation on these as well as "make" is [http://www.suse.de/~sh/automake/automake.pdf "Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer].
 
=== %install section ===
 
The "%install" section is a set of script commands to "install" the program. The commands in this section should copy the files from the "build directory" %{_builddir} (which would be under ~/rpmbuild/BUILD) into the build root directory, %{buildroot} (which would normally be under /var/tmp).
 
'''Watch out''': Some of the terminology is very misleading:
* The "build directory" (where compilations occur during %build) and the "build root" (where files are copies in to during the %install) are '''different'''.  The point of the %install process is to copy files from %{builddir} to the right place in %{buildroot}.
* The "%install" script is ''not'' used when the binary rpm package is installed by the end-user!! The term "%install" is misleading, in fact, the script must ''not'' install the programs in the REAL final locations (e.g., in /usr/bin), but under the buildroot %{buildroot}.
 
Normally, the install script would first erase the %{buildroot} directory, and then do some variation of "make install" (using DESTDIR=%{buildroot}, if the program supports it).  As noted in the guidelines,  "when adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, eg. cp -p or install -p". So if there is no "make install", it would do some sort of sequence that would create directories that weren't already created by the "BuildRequires" packages (typically using install -d), followed by copying of files from the current directory (inside the build directory) into the buildroot directory.  Here's an example of an %install section:
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
 
=== %files section ===
The %files section identifies what files and directories were added by the package - and thus, which files and directories are ''owned'' by the package.  Ownership is important - when you type "rpm -qif ''blah''",  you'll see who owns ''blah''.
 
The %files section normally begins with a "%defattr" line which sets the default file permissions; usually this is:
%defattr(-,root,root,-)
 
This is followed by names or patterns of the directories or files to be installed and owned by this package. You should use macros for directory names, e.g., use %{_bindir}/myfile instead of /usr/bin/myfile, and %{_sbindir}/killaccount instead of /usr/sbin/killaccount.  If a name or pattern begins with "/" when expanded, then it is presumed to have been copied into the %{buildroot} followed by that pattern; when installed on the final system, it will be copied into that name ''without'' the buildroot prefix.  If you don't precede the pattern with "/", then it is presumed to be in the current directory (e.g., inside the build directory) - this is used for "documentation" files.  So if your package just installs /usr/bin/mycommand, then your %files section ''could'' simply say:
%defattr(-,root,root,-)
%{_sbindir}/mycommand
 
Any file or directory identified in the %files section is ''owned'' by the defining package. You should make sure that you declare ownership of every new file or directory the package creates.  You can use wildcards (*) which match a set of files - this makes the package less sensitive to changes. For example, you can declare that all the files that were copied into %{buildroot}/usr/bin are owned by this package by declaring:
%{_bindir}/*
 
Note that "%{_bindir}/*" does not claim that this package owns the /usr/bin directory - it claims that all the files that were installed inside the ''build root'' 's /usr/bin are owned by the package.
If you list a ''directory'' in the %files section, then you are claiming that this package owns that subdirectory and all files and directories in it, recursively (''all'' the way down).  Do not try to claim ownership of /usr/bin!  But if you create a subdirectory in %{_datadir} (/usr/share), you ''should'' include in the %files list:
%{_datadir}/%{name}/
 
It's usually easier to just use wildcards, and that's also better at coping with changes in upstream.  Older RPM documentation typically shows long lists under %files with individual names, such as /usr/bin/program1 followed by /usr/bin/program2.  Fedora spec files now use buildroots, so that is no longer necessary.
 
It's an error if ''no'' file matches the wildcard of a line, so only note the directories that actually matter.  Also, you can't identify the same file or directory more than once.
 
Typically there is a "%doc" entry with a list of documentation files that didn't get copied into the buildroot; usually there is at least a README and LICENSE file (you ''must'' include the license file, if there is one). You may prefix some of these with %attr(mode, user, group) to set the file permission mode / user / group.  You don't need to claim ownership of the /usr/share/doc/%{name} directory, that's automatic.
 
If you save configuration files (under /etc - don't put them under /usr), you should normally prefix them with %config(noreplace) unless this program version uses a non-backwards-compatible configuration format (in which case, use %config).
 
You should follow the [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard (FHS)], i.e., ordinary application executables go into /usr/bin, global configuration files go into /etc, ordinary libraries go into /usr/lib, and so on, with one exception: executables that should ''not'' normally be executed directly by users or administrators should go into a subdirectory of /usr/libexec; usually you'd refer to the necessary directory as "%{_libexecdir}/%{name}".
 
Here's a simple example:
%defattr(-,root,root,-)
%doc README LICENSE
%{_bindir}/*
%{_sbindir}/*
 
=== Macros ===
 
Spec files may contain "macro" references (text beginning with "%"), which are replaced with other values.
You can follow % by a word, e.g., "%name", but just like shell variables you must bracket the name with {...}
if letters or digits immediately follow, e.g., "%{name}".
 
As noted in the
[[Packaging/Guidelines| Packaging Guidelines]],
There are two styles for referring some values such as the rpm Build Root and Optimization Flags:
* "macro style": %{buildroot}, %{optflags}
* "variable style": $RPM_BUILD_ROOT, $RPM_OPT_FLAGS
Pick a style and use it consistently throughout your packaging; this document uses "macro style".
 
Here are some typical macros:
 
{|
! Macro !! Typical Expansion
|-
| %{_bindir} || /usr/bin
|-
| %{_builddir} || ~/rpmbuild/BUILD/... (build directory, where files are built)
|-
| %{buildroot} || /var/tmp... (buildroot, where files are installed)
|-
| %{_datadir} || /usr/share
|-
| %{_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} || /usr/com
|-
| %{_sysconfdir} || /etc
|-
| %{version} || Version of package, set by Version: tag
|}
 
To see more about macros you
can look in /etc/rpm/* and the "macros" files under "/usr/lib/rpm/".
You can also invoke rpm, using "rpm --showrc" (to show all the configuration values)
or "rpm --eval '%{macro}'" (to see the default value of a particular macro).
 
You can set your own macro values using %define; be sure to define them before you use them. Macro definitions
can refer to other macros.  For example:
%define myvalue 50
 
[[Packaging/RPMMacros]] has more information on macros, as does
[http://docs.fedoraproject.org/drafts/rpm-guide-en/ch09s07.html RPM Guide chapter 9].
 
=== Miscellaneous hints ===
 
'''Beware''': Comments (beginning with #) do not work as you might expect.
'''Do not''' include macros (words beginning with "%") in a comment, because they are expanded even inside comments;
if the macro is multi-line it cause weird errors (change the "%" to "%%" to escape them).
Also, '''do not''' use in-line comments (a # not at the beginning of a line);
in-line comments often don't work properly in a spec file.
Instead, use a comment-only line (without macros).
 
Use scriplets to make programs run before and after events (e.g., installing and uninstalling on the real system).
[[Packaging/ScriptletSnippets|Scriptlet Snippets]] has some useful examples of scriptlets.
'''Beware:''' the "-p" option of %pre, etc.,
[http://osdir.com/ml/freshrpms.user/2003-10/msg00233.html selects the program that will execute your script].
If you only have a single program that ignores input, then using "-p" is slightly more efficient, but
if you're writing a shell script you typically do ''not'' want to use "-p".
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
 
[[Packaging/FrequentlyMadeMistakes]] has information on frequently-made mistakes.
 
Some older documents about RPM have the most information, but older documents tend to assume that
all rpm work happens in a shared /usr/src/redhat directory.  This is an obsolete way of
using rpm and ''not'' recommended.
They may also claim that "rpm" creates packages; it once did, but now that capability
is in the separate "rpmbuild" program.
 
== Quick test with rpmlint ==
 
Before trying to build anything from it, you might want to run ''rpmlint'' on the spec file:
rpmlint program.spec
This will catch many errors early.
 
Generally, you should not have errors from rpmlint, but sometimes
rpmlint is excessively noisy.
The
[http://fedoraproject.org/wiki/Packaging/Guidelines#Use_rpmlint Fedora packaging guidelines]
explain which ones to ignore, e.g., ignore "no-packager-tag" and "no-signature" errors.
 
== Creating RPMs from the spec file ==
 
Once you've create a spec file, say "program.spec", you can create
source and binary RPMs by simply running this:
  $ rpmbuild --clean -ba program.spec
 
This will attempt to perform the following stages:
* %prep (preparation) stage, which uncompresses and installs the sources and patches into %_builddir (a subdirectory of ~/rpmbuild/BUILD)
* %build stage, which builds (e.g., compiles) the files to be installed in %_builddir. Usually this is some equivalent of "make".
* %install stage, which copies the files from the build directory %_builddir (which would be under ~/rpmbuild/BUILD) into the buildroot directory, %{buildroot}.  The buildroot directory is set by the earlier "BuildRoot:"; if you leave it to its normal value beginning %{_tmppath}/%{name}..., then the buildroot will be inside /var/tmp.
* Create the binary and source RPM packages (.rpm and .src.rpm files).  The binary RPM files are created using the information from the %files list.
 
Watch out: the "build directory" (where compilations occur during %build) and the "build root" (where files are installed during the %install) are ''different''.
 
When things go wrong, you can "cd" into the appropriate directory and see what's left over.
If you want to skip earlier stages, use the "--short-circuit" option; this is handy if you had a successful build, but have an error in the %install section.  For example, to restart at the %install stage (skipping earlier stages), do this:
  $ rpmbuild -bi --short-circuit program.spec
 
If it is successful, you'll find your binary RPM(s) in the "~/rpmbuild/RPMS/"
subdirectory, and the source RPM in "~/rpmbuild/SRPMS".
 
If you just want to create a source RPM (.src.rpm), do this in the SPECS directory:
rpmbuild -bs program.spec
This will create the source RPM in ~/rpmbuild/SRPMS.  Creating ''only'' a source rpm (.src.rpm) is quite quick, because rpm simply needs to copy the .spec file and associated SOURCES files into a .src.rpm file.  Creating a binary rpm typically takes ''much'' longer, because this requires running the %prep, %build, and %install scripts.
 
== Testing RPMs you've built ==
 
If you "cd" to the "~/rpmbuild/RPMS" directory, to the architecture subdirectory,
and then find some rpms, you can quickly see what's in each rpm by using rpmls:
$ rpmls *.rpm
 
If those look okay, you can become root and try to install them:
# rpm -ivp XYZ1.rpm XYZ2.rpm XYZ3.rpm ...
 
Then, you can test them out.  If it's a command-line tool, can you invoke it
without prepending /usr/bin?  If it's a GUI tool, does it show up in the menu
(if it doesn't, something is wrong with your .desktop entry).
 
You can uninstall them later using:
# rpm -e XYZ1 XYZ2 XYZ3
 
If that all works, you can use Mock to do a rigorous test that you have
accurate build requirements.  See [[PackageMaintainers/MockTricks]]
for more information about how to use Mock.
 
== Guidelines and rules ==
 
When you create your packages, you'll need to follow the following rules and guidelines:
* [[PackageMaintainers/Join| How to join the Fedora Package Collection Maintainers]] - describes the process for becoming a Fedora package maintainer
* [[Packaging/Guidelines|Packaging Guidelines]]
* [[Packaging/NamingGuidelines| Package Naming Guidelines]]
* [[Packaging/DistTag| Dist Tag Guidelines]]
* [[Packaging/ReviewGuidelines| Package Review Guidelines]]
 
There are many guidelines that will help you with specific circumstances
(Java programs, OCaml programs, GNOME programs, etc.); the
[[Packaging/Guidelines|Packaging Guidelines] include cross-references to those guidelines.
You can also learn more from the [[SIGs]] and
[[PackageMaintainers|Package Maintainers]] sections.
[https://fedoraproject.org/wiki/Special:Prefixindex/Packaging You can also see the list of all Wiki pages about Packaging] to see if any apply.
 
== For more information ==
 
The [[PackageMaintainers|Package Maintainers]] page links to many other useful pages, and the
[[PackageMaintainers/UpdatingPackageHowTo|Updating Package HOWTO]] describes how to update
an existing package you already maintain in Fedora.
 
For more information, outside of the Fedora Wiki, see:
* [http://www.g-loaded.eu/2006/04/05/how-to-build-rpm-packages-on-fedora/ How to build RPM packages on Fedora] - very brief run-through
* Packaging software with RPM (developerWorks) [http://www.ibm.com/developerworks/library/l-rpm1/ Part 1], [http://www.ibm.com/developerworks/library/l-rpm2/ Part 2], and [http://www.ibm.com/developerworks/library/l-rpm3.html Part 3]
* [http://koti.welho.com/vskytta/packagers-handbook/packagers-handbook.html Fedora Packager's Handbook]
* [http://www.redhatmagazine.com/2008/02/28/when-sally-met-eddie-the-fedora-package-story/ When Sally met Eddie] - a simple tale, but little detail
* [http://rpm.org/max-rpm-snapshot/ Maximum RPM Book] - most complete information, but in some cases old/obsolete
* [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch-creating-rpms.html RPM Guide, section on creating RPMs] - this has lots of good information and focuses on Fedora, but is a draft
* [http://docs.fedoraproject.org/developers-guide/ch-rpm-building.html Developer's guide, section on building RPMs]
* [http://www.gurulabs.com/GURULABS-RPM-LAB/GURULABS-RPM-GUIDE-v1.0.PDF Creating RPMS slides] from Guru Labs
* [http://freshrpms.net/docs/fight/ The fight, my first attempt to make a readable rpm package building introduction.]
* [http://genetikayos.com/code/repos/rpm-tutorial/trunk/rpm-tutorial.html RPM Tutorial (Fullhart)]
* [http://en.tldp.org/HOWTO/RPM-HOWTO/index.html RPM HOWTO: RPM at Idle by Donnie Barnes]
* [http://en.opensuse.org/SUSE_Build_Tutorial SuSE build tutorial] - but about SuSE, not Fedora. [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://fedoranews.org/alex/tutorial/rpm/ All you need to know about RPM] (more about installing packages than creating them)
 
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.

Latest revision as of 20:57, 26 May 2021