From Fedora Project Wiki
La traduzione di questa pagina è incompleta

Questa è una guida pratica sulla costruzione dei pacchetti RPM, mostra rapidamente come creare dei semplici pacchetti software sorgente e binari. Si presume di possedere una certa disinvoltura nell'uso dei pacchetti precompilati e con il processo d costruzione di software FOSS.

Per informazioni complete su come creare file RPM inclusi suggirimenti dettagliati, fare riferimento alla pagina How to create an RPM package/it. Se si intende creare un pacchetto RPM per i repository Fedora, seguire il processo su come far parte dei manutentori del Fedora Package Collection seguendone le varie indicazioni.

Questo tutorial mostra la pacchettizzazione del progetto GNU "Hello World". Sebbene sia banale ottenere un printing della dicitura "Hello World", la versione GNU contiene contiene la maggior parte dei componenti usuali associati ad un tipico progetto di software FOSS, includendo configuration/build/install, documentazione, internazionalizzazione, etc. Lo stesso comunque consiste tradizionalmente in un file .tar contenente il codice sorgente e gli script configure/make, ma non include informazioni sulla pacchettizzazione. E' utile per far pratica con la costruzione degli RPM.

Ambiente di sviluppo

Per costruire gli RPM servono degli strumenti di sviluppo. Si tratta di una configurazione da fare una sola volta e consiste in un'installazione attraverso i seguenti comandi dati come amministratore di sistema (root):

# yum install @development-tools
# yum install fedora-packager

Se si preferisce testare la procedura di costruzione in una root dedicata, bisogna configurare il proprio utente come membro del guppo mock:

# usermod -a -G mock <your username>

Questi sono i soli comandi che richiedono i privilegi di root. Tutto il restante lavoro dovrebbe essere fatto dal normale utente o da un accout creato appositamente per lo sviluppo. I moderni sistemi basati su RPM, inclusa Fedora, sono configurati per costruire e testare i pacchetti RPM puramente all'interno di un account senza privilegi. Il comando

$ rpmdev-setuptree

imposta un'area di lavoro all'interno di ~/rpmbuild. Questa cartella conterrà diverse sottocartelle per il codice sorgente, i file di configurazione e per i risultanti pacchetti sorgente e binari.

Costruire un rpm "Hello World"

Innanzitutto serve il codice sorgente del progetto software da pacchettizzare, solitamente proveniente dall'upstream (progetto madre). Una volta scaricato dal sito web del progetto, sarà salvato nella cartella ~/rpmbuild/SOURCE, ottenendo un archivio compresso di tipo tarball che sembra essere il preferito da tanti.

$ cd ~/rpmbuild/SOURCES
$ wget http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz

L'RPM è configurato attraverso i file .spec. Si crea un file hello.spec campione nella cartella appropriata:

$ cd ~/rpmbuild/SPECS
$ rpmdev-newspec hello

Recenti versioni di Emacs e vi hanno modalità di editing del file .spec che ripropongono modelli simili durante la creazione di un nuovo file. Quindi basterebbe usare il seguente comando per esempio per modifcare un file modello (template) automaticamente.

vi hello.spec

All'interno di un file .spec

I campi del fiel .spec necessitano di poche modifiche. Seguire le regole Fedora per questi campi. In questo caso, il file potrebbe iniziare così:

Name:     hello
Version:  2.8
Release:  1
Summary:  The "Hello World" program from GNU
License:  GPLv3+
URL:      http://ftp.gnu.org/gnu/hello    
Source0:  http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz

%description
The "Hello World" program, done with all bells and whistles of a proper FOSS 
project, including configuration, build, internationalization, help files, etc.

%changelog
* Thu Jul 07 2011 The Coon of Ty <Ty@coon.org> - 2.8-1
- Initial version of the package

The Version should mirror upstream while Release numbers our work within Fedora.

The first letter of the Summary should be uppercase to avoid rpmlint complaints.

It is your responsibility to check the License status of the software, by inspecting the source files and/or their LICENSE files, and/or by talking to the authors.

The Group tag was historically used to classify the package in accordance to the list in /usr/share/doc/rpm-<version>/GROUPS. It is being phased out so you will not see it added by default. However, it doesn't hurt to add it anyway.

The %changelog should document the work on preparing the RPM, especially if there are security and bug patches included on top of the base upstream source. Changelog data can be displayed by rpm --changelog -q <packagename>, which is very useful for instance to find out if specific bug and security patches were included in the installed software, thanks to diligent Fedora packagers who include this info with the relevant [[1]] numbers.

The changelog entry should include the version string to avoid rpmlint complaints.

Multi-line sections like %changelog or %description start on a line under the directive, and end with an empty line.

Lines which aren't needed (e.g. BuildRequires and Requires) 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:

$ rpmbuild -ba hello.spec

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 %files section. Do not hardcode names like /usr/bin/, but use macros, like %{_bindir}/hello instead. The manual pages should be declared in the %doc subsection: %doc %{_mandir}/man1/hello.1.gz.

This is an iterative process: after editing the .spec file, rerun rpmbuild.

Since our program uses translations and internationalization, we are seeing a lot of undeclared i18 files. The recommended method to declare them is:

  • find the filenames in the %install step: %find_lang %{name}
  • add the required build dependencies: BuildRequires: gettext
  • use the found filenames %files -f %{name}.lang

If the program uses GNU info files, you need to make sure the installation and uninstallation of the package does not interfere with other software on the system, by using this boilerplate:

  • delete the 'dir' file in %install: rm -f %{buildroot}/%{_infodir}/dir
  • Requires(post): info and Requires(preun): info
  • add those steps:
%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :

%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi

A complete hello.spec file

Here's the initial version of hello.spec:

Name:           hello
Version:        2.8
Release:        1%{?dist}
Summary:        The "Hello World" program from GNU

License:        GPLv3+
URL:            http://ftp.gnu.org/gnu/%{name}
Source0:        http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz

BuildRequires: gettext
      
Requires(post): info
Requires(preun): info

%description 
The "Hello World" program, done with all bells and whistles of a proper FOSS 
project, including configuration, build, internationalization, help files, etc.

%prep
%setup -q

%build
%configure
make %{?_smp_mflags}

%install
%make_install
%find_lang %{name}
rm -f %{buildroot}/%{_infodir}/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

%files -f %{name}.lang
%doc AUTHORS ChangeLog COPYING NEWS README THANKS TODO
%{_mandir}/man1/hello.1.gz
%{_infodir}/%{name}.info.gz
%{_bindir}/hello

%changelog
* Tue Sep 06 2011 The Coon of Ty <Ty@coon.org> 2.8-1
- Initial version of the package

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 rpmlint on the spec file and all RPMs:

$ rpmlint hello.spec ../SRPMS/hello* ../RPMS/*/hello*

If there are no warnings or errors, we've succeeded. Otherwise, append the error messages to the rpmlint -i command to see a more verbose description of the rpmlint diagnostics.

The mock builds

To check that the package build will succeed in the Fedora restricted build environment, check it with mock.

$ mock -r fedora-15-i386 --rebuild ../SRPMS/hello-2.7-1.fc15.src.rpm

References

History

Przemek Klosowski wrote this tutorial when he worked through Christoph Wickert's IRC session on building RPMs using Rahul Sundaram suggestion of GNU "Hello World" as a test case. After he wrote up his experience, he found out about the excellent and extensive How to create an RPM package page on this wiki, as well as the Christian Lyder Jacobsen's website. However, Christian isn't planning to update his site, and it seemed that a 5-minute 'fast food' alternative to the more extensive article might suit some people. More in-depth information on using and building RPM packages is available from other sources.