From Fedora Project Wiki

m
(Replace with notica about the new location at docs.fp.o)
Tag: Replaced
 
(71 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>
 

Latest revision as of 20:50, 26 May 2021