|
|
(516 intermediate revisions by 75 users not shown) |
Line 1: |
Line 1: |
| == Creating Package HOWTO == | | {{autolang|base=yes}} |
|
| |
|
| This page describes the mechanics of how to create an RPM package 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).
| |
| | |
| 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.
| |
| | |
| == 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:
| |
| # 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:
| |
| $ 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.
| |
| | |
| 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 it, install them
| |
| 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.
| |
| | |
| ''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.
| |
| 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".
| |
| | |
| 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 $RPM_BUILD_ROOT
| |
| make install DESTDIR=$RPM_BUILD_ROOT
| |
|
| |
| %clean
| |
| rm -rf $RPM_BUILD_ROOT
| |
|
| |
| %files
| |
| %defattr(-,root,root,-)
| |
| %doc
| |
|
| |
| %changelog
| |
|
| |
| | |
| === 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.
| |
| | |
| === 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.
| |
| 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).
| |
| | |
| [[Packaging/ScriptletSnippets|Scriptlet Snippets]] has some useful examples of scriptlets.
| |
| | |
| 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.
| |
| | |
| == 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 %_builddir (under ~/rpmbuild/BUILD) into the "BuildRoot:". The recommended setting of BuildRoot begins %{_tmppath}/%{name}..., and thus is typically inside /var/tmp.
| |
| * Create the binary (and maybe source) packages; this uses the information from the %files list to determine what files in the RPM BuildRoot to use.
| |
| | |
| 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 "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.
| |
| | |
| You can uninstall them later using:
| |
| # rpm -e XYZ1 XYZ2 XYZ3
| |
| | |
| == 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]]
| |
| | |
| == For more information ==
| |
| | |
| The [[PackageMaintainers|Package Maintainers]] page links to many other useful pages, and the
| |
| 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] - quick 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://www.redhatmagazine.com/2008/02/28/when-sally-met-eddie-the-fedora-package-story/ When Sally met Eddie]
| |
| * [http://rpm.org/max-rpm-snapshot/ Maximum RPM Book]
| |
| * [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch-creating-rpms.html RPM Guide, section on creating RPMs]
| |
| * [http://docs.fedoraproject.org/developers-guide/ch-rpm-building.html Developer's guide, section on building RPMs]
| |
| * [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)]
| |