|
|
(70 intermediate revisions by 35 users not shown) |
Line 1: |
Line 1: |
| This is a hands-on tutorial on writing RPM files, suitable for an impatient
| | {{autolang|base=yes}} |
| person who wants to quickly step up to create source and binary software packages. I assume familiarity with using pre-made RPM packages, and with the FOSS software building process. More in-depth information on using and building RPM packages is available from [https://fedoraproject.org/wiki/Tools/RPM other sources].
| |
|
| |
|
| This tutorial demonstrates packaging of the GNU "Hello World" project. While 'Hello World" is a trivial program, the GNU project | | {{admon/important|This page is deprecated|As part of documentation move to docs.fp.o, this page has moved to https://docs.fedoraproject.org/en-US/quick-docs/create-hello-world-rpm/}} |
| contains most of the usual peripheral components associated with a typical FOSS software distribution,
| |
| including the configuration/build/install environment, documentation, internationalization, etc.
| |
| As you will see, it's a reasonable vehicle to practice building RPMs on.
| |
| | |
| I wrote this tutorial when I worked through
| |
| [http://fedoraproject.org/wiki/Building_RPM_packages_%2820090405%29 Christoph Wickert's IRC class on building RPMs] using Rahul Sundaram suggestion of GNU "Hello World" as a test case. After I wrote up my experience,
| |
| I found out David A. Wheeler's excellent, extensive
| |
| [http://fedoraproject.org/wiki/How_to_create_an_RPM_package RPM building guide] on this wiki, as well as the
| |
| [http://www.absolutepanic.org/blog/2009/07/building-a-gnu-hello-world-rpm Christian Lyder Jacobsen's website].
| |
| I decided to keep my version up for the time being, because Christian told me he isn't planning to update his
| |
| site, and I think a 5-minute 'fast food' alternative to David's article might suit some people.
| |
| | |
| == Development environment ==
| |
| | |
| To build RPMs we need a set of development tools. This is a one-time-only setup,
| |
| installed by running those commands from a system administration (<code>root</code>) account:
| |
| | |
| <pre>
| |
| yum groupinstall development-tools
| |
| yum install rpm-build rpmdevtools
| |
| </pre>
| |
| | |
| If you want to test the build procedure in the context of Fedora anonymous package build
| |
| system, you need to configure your non-privileged account to be a member of the 'mock' group:
| |
| <pre>
| |
| usermod -a -G mock <yourAccountName>
| |
| </pre>
| |
| | |
| Those are the only commands requiring <code>root</code> privileges. All the remaining
| |
| work should be done from your regular, non-privileged account, or even from a separate
| |
| account created just for development work. Modern RPM-based
| |
| systems, including Fedora, are set up to build and test RPM packages purely from
| |
| within a non-privileged account. The command
| |
| | |
| <pre>rpmdev-setuptree</pre>
| |
| | |
| sets up a RPM build
| |
| area in your <code>~/rpmbuild</code>. This directory will contain several subdirectories,
| |
| for the project source code, RPM configuration files and for the resulting source and binary
| |
| packages.
| |
| | |
| == Building a "Hello World" RPM==
| |
| | |
| We need the source code of the project we are packaging, often referred
| |
| to as the 'upstream' source. We will download it from the project's website into the <code>~/rpmbuild/SOURCE</code>
| |
| directory. We are getting the compressed tarball archive, which happens to be a preferred distribution form for
| |
| most FOSS projects.
| |
| <pre>
| |
| cd ~/rpmbuild/SOURCE
| |
| wget http://ftp.gnu.org/gnu/hello/hello-2.5.tar.gz
| |
| </pre>
| |
| | |
| The RPM package is configured by <code>.spec</code> files. We will create a template
| |
| file <code> hello.spec</code> in the appropriate directory:
| |
| <pre>
| |
| cd ~/rpm/SPECS
| |
| rpmdev-newspec hello
| |
| </pre>
| |
| | |
| Recent versions of <code>Emacs</code> and <code>vi</code> have .spec file editing modes which will
| |
| also bring up a similar template upon creating a new file.
| |
| | |
| === Inside a <code>.spec</code> file ===
| |
| | |
| The fields in our <code>.spec</code> file need slight editing. Please follow the
| |
| [https://fedoraproject.org/wiki/How_to_create_an_RPM_package#Spec_file_pieces_explained Fedora rules]
| |
| for these fields. In our case, the file might start as follows:
| |
| | |
| <pre>
| |
| Name: hello
| |
| Version: 2.5
| |
| Release: 1
| |
| Summary: The "Hello World" program
| |
| License: GPLv3
| |
| URL: http://ftp.gnu.org/gnu/hello
| |
| Source0: http://ftp.gnu.org/gnu/hello/hello-2.5.tar.gz
| |
| %description:
| |
| The "Hello World" program, done with all bells and whistles of a proper FOSS
| |
| project, including configuration, build, internationalization, helpfiles, etc.
| |
| | |
| %changelog
| |
| * Tue Mar 30 2010 The Coon of Ty <Ty@coon.org> 2.5-1
| |
| - Initial version of the package
| |
| | |
| </pre>
| |
| | |
| The <code>Version</code> should mirror upstream while <code> Release</code> numbers our work
| |
| within Fedora.
| |
| | |
| The first letter of the <code> Summary</code> should be uppercase to avoid
| |
| rpmlint complaints.
| |
| | |
| It is your responsibility to check the <code>License</code> status of the software, by
| |
| inspecting the source files and/or their LICENSE files, and/or by talking to the authors.
| |
| | |
| The <code> Group </code> tag is being phased out, but it doesn't hurt to classify it
| |
| in accordance to the list in <code>/usr/share/doc/rpm-4.6.0/GROUPS</code>.
| |
| | |
| The <code> %changelog</code> should document the work on preparing the RPM , and should include the version string to avoid
| |
| rpmlint complains.
| |
| | |
| Multi-line sections like <code> %changelog</code> or <code> %description</code> start on a line under
| |
| the directive, and end with an empty line.
| |
| | |
| Lines which aren't needed (e.g. <code>BuildRequires</code> and <code>Requires</code>) can be commented out with a hash ('#') for now.
| |
| | |
| Many lines in the template don't need to be changed at all in many cases, at least for the initial attempt.
| |
| | |
| === Building the package ===
| |
| | |
| We are ready for the first run to build source, binary and debugging packages:
| |
| | |
| <pre>
| |
| rpmbuild -ba hello.spec
| |
| </pre>
| |
| | |
| It will complain and list the unpackaged files, i.e. the files that would be
| |
| installed in the system that weren't declared as belonging to the package. We need to declare them in the
| |
| <code>%files</code> section. Do not hardcode names like
| |
| <code>/usr/bin/</code>, but use macros, like <code>%{_bindir}/hello</code> instead.
| |
| The manual pages should be declared in the <code>%doc</code> subsection:
| |
| <code>%doc %{_mandir}/man1/hello.1.gz</code>.
| |
| | |
| This is an iterative process: after editing the <code>.spec</code> file, rerun rpmbuild.
| |
| | |
| Since our program uses translations and internationalization, we are getting a lot of
| |
| undeclared i18 files. The
| |
| [https://fedoraproject.org/wiki/Packaging/Guidelines#Handling_Locale_Files recommended method]:
| |
| to declare them is:
| |
| | |
| * find the filenames in the <code>%install</code> step: <code> %find_lang ${name}</code>
| |
| * add the required build dependencies: <code>BuildRequires: gettext</code>
| |
| * use the found filenames <code>%files -f ${name}.lang</code>
| |
| | |
| If the program uses GNU info files, you need to make sure the installation and unistallation
| |
| of the package does not interfere with other software on the system:
| |
| | |
| * delete the 'dir' file in %install: <code>rm -f $RPM_BUILD_ROOT/usr/share/info/dir</code>
| |
| * <code>Requires(post): info</code> and <code>Requires(preun): info</code>
| |
| * add those steps:
| |
| <pre>
| |
| %post
| |
| /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
| |
| | |
| %preun
| |
| if [ $1 = 0 ] ; then
| |
| /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
| |
| fi
| |
| </pre>
| |
| | |
| === A complete <code>hello.spec</code> file ===
| |
| | |
| Here's the initial version of <code>hello.spec</code>:
| |
| | |
| <pre>
| |
| Name: hello
| |
| Version: 2.5
| |
| Release: 1%{?dist}
| |
| Summary: The "hello world" program from GNU
| |
| | |
| Group: Applications/Text
| |
| License: GPLv3
| |
| URL: http://ftp.gnu.org/gnu/hello
| |
| Source0: http://ftp.gnu.org/gnu/hello/hello-2.5.tar.gz
| |
| BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
| |
| | |
| BuildRequires: gettext
| |
| # Requires:
| |
| Requires(post): info
| |
| Requires(preun): info
| |
| | |
| %description
| |
| The "hello world" program from GNU, with bells and whistles
| |
| | |
| | |
| %prep
| |
| %setup -q
| |
| | |
| | |
| %build
| |
| %configure
| |
| make %{?_smp_mflags}
| |
| | |
| | |
| %install
| |
| rm -rf $RPM_BUILD_ROOT
| |
| make install DESTDIR=$RPM_BUILD_ROOT
| |
| %find_lang %{name}
| |
| rm -f $RPM_BUILD_ROOT/usr/share/info/dir
| |
| | |
| %post
| |
| /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
| |
| | |
| %preun
| |
| if [ $1 = 0 ] ; then
| |
| /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
| |
| fi
| |
| | |
| %clean
| |
| rm -rf $RPM_BUILD_ROOT
| |
| | |
| | |
| %files -f %{name}.lang
| |
| %defattr(-,root,root,-)
| |
| %{_bindir}/hello
| |
| %doc %{_mandir}/man1/hello.1.gz
| |
| %doc %{_infodir}/%{name}.info.gz
| |
| | |
| %changelog
| |
| * Tue Mar 30 2010 The Coon of Ty <Ty@coon.org> 2.5-1
| |
| - Initial version of the package
| |
| </pre>
| |
| | |
| With this spec file, you should be able to successfully complete the
| |
| build process, and create the source and binary RPM packages.
| |
| | |
| Next you should check them for conformance with RPM design
| |
| rules, by running <code>rpmlint</code> on the spec file and all RPMs:
| |
| | |
| <pre>
| |
| rpmlint hello.spec ../SRPMS/hello* ../RPMS/*/hello*
| |
| </pre>
| |
| | |
| If there are no warnings or errors, we've succeeded. Otherwise,
| |
| append the error messages to the <code>rpmlint -I</code>
| |
| command to see a more verbose description of the <code>rpmlint</code> diagnostics.
| |
| | |
| === The <code>mock</code> builds ===
| |
| | |
| To check that the package build will succeed in the Fedora restricted
| |
| build environment, check it with mock.
| |
| | |
| <pre>
| |
| mock -r fedora-12-i386 --rebuild ../SRPMS/hello-2.5-1.fc12.src.rpm
| |
| </pre>
| |