From Fedora Project Wiki
Line 6: Line 6:
Questa pagina descrive in dettaglio i meccanismi di base su come creare un pacchetto RPM ed in particolare come creare uno SPEC file. A differenza di altre guide su RPM, questa pagina spiega le specifiche per Fedora legate alle linee guida ufficiali. Da quando è mantenuta su Fedora wiki, è probabile che sia più aggornata rispetto ad altre guide. Nonostante tutto, non tutto l'intero documento è applicabile anche ad altre distro basate su RPM. Se "si vogliono stringere i tempi" leggere [[How to create a GNU Hello RPM package]].
Questa pagina descrive in dettaglio i meccanismi di base su come creare un pacchetto RPM ed in particolare come creare uno SPEC file. A differenza di altre guide su RPM, questa pagina spiega le specifiche per Fedora legate alle linee guida ufficiali. Da quando è mantenuta su Fedora wiki, è probabile che sia più aggornata rispetto ad altre guide. Nonostante tutto, non tutto l'intero documento è applicabile anche ad altre distro basate su RPM. Se "si vogliono stringere i tempi" leggere [[How to create a GNU Hello RPM package]].
   
   
Da notare che questa pagina ''non'' mostra le linee guida ufficiali sulla creazione dei pacchetti per Fedora; a questo proposito, vedere la [Packaging:Guidelines|  Packaging Guidelines]] e [[Packaging:NamingGuidelines|  Package Naming Guidelines]]). Questa pagina ''dovrebbe'', comunque, essere compatibile con loro.
Da notare che questa pagina ''non'' mostra le linee guida ufficiali sulla creazione dei pacchetti per Fedora; a questo proposito, vedere la [[Packaging:Guidelines|  Packaging Guidelines]] e [[Packaging:NamingGuidelines|  Package Naming Guidelines]]). Questa pagina ''dovrebbe'', comunque, essere compatibile con loro.


Se si prevede di creare un pacchetto RPM per il repository di Fedora, seguire la procedura [[Join the package collection maintainers|Come diventare manutentori dei pacchetti Fedora Collection]].
Se si prevede di creare un pacchetto RPM per il repository di Fedora, seguire la procedura [[Join the package collection maintainers|Come diventare manutentori dei pacchetti Fedora Collection]].

Revision as of 12:58, 28 April 2012

La traduzione di questa pagina è completa ma ancora in fase di revisione

Introduzione

Questa pagina descrive in dettaglio i meccanismi di base su come creare un pacchetto RPM ed in particolare come creare uno SPEC file. A differenza di altre guide su RPM, questa pagina spiega le specifiche per Fedora legate alle linee guida ufficiali. Da quando è mantenuta su Fedora wiki, è probabile che sia più aggornata rispetto ad altre guide. Nonostante tutto, non tutto l'intero documento è applicabile anche ad altre distro basate su RPM. Se "si vogliono stringere i tempi" leggere How to create a GNU Hello RPM package.

Da notare che questa pagina non mostra le linee guida ufficiali sulla creazione dei pacchetti per Fedora; a questo proposito, vedere la Packaging Guidelines e Package Naming Guidelines). Questa pagina dovrebbe, comunque, essere compatibile con loro.

Se si prevede di creare un pacchetto RPM per il repository di Fedora, seguire la procedura Come diventare manutentori dei pacchetti Fedora Collection.

Impostazione del sistema

Prima di creare pacchetti RPM in Fedora, bisogna installare alcuni strumenti di sviluppo e settare l'account (o gli account) che si userà. Come root (non digitare il '#' !)

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

E' possibile creare un "utente dedicato" appositamente per costruire pacchetti rpm. In questo modo, se qualcosa dovesse andare male, il programma o il processo di costruzione non cancellerà dati personali o non invierà file o chiavi private al mondo esterno.

Non si dovrebbero mai creare pacchetti come utente root.

Creare un nuovo utente chiamato semplicemente "makerpm", impostarne la password eseguendo:

 # /usr/sbin/useradd makerpm
 # passwd makerpm

Poi loggarsi come utente speciale (makerpm).

Una volta loggatosi, si dovrà creare una struttura nella propria cartella home eseguendo (non digitare il '$'):

 $ rpmdev-setuptree

Il programma "rpm-setuptree" creerà una cartella ~/rpmbuild. All'interno di "rpmbuild" ci sono una serie di sottocartelle (come SPECS e BUILD) che si useranno per creare i propri pacchetti. Sarà inoltre creato il file ~/.rpmmacros, usato per impostare opzioni aggiuntive.

Le linee guida per il packaging raccomandano l'uso di comandi che preservano il timestamps dei file; è possibile farlo automaticamente usando wget o curl per procurarsi i file sorgente. Se si usa wget assicurarsi di aggiungere il comando "timestamping = on" al file ~/.wgetrc. allo stesso modo se si usa curl, nel file ~/.curlrc dev'essere presente il testo "-R".

Una volta fatto questi passaggi per la creazione dell'account, normalmente non sarà necessario rifarli ancora.

Le basi della creazione di pacchetti RPM

Per creare un pacchetto RPM, è necessario creare un file di testo ".spec" che fornisce informazioni sul software che viene pacchettizzato. Quindi si esegue il comando "rpmbuild" sul file spec, che completa una serie di passi per produrre il pacchetto.

Normalmente si opera collocando il sorgente originale (incontaminato), ad esempio un file tar.gz degli sviluppatori originali, in "~ /rpmbuild/SOURCES". Si consiglia di inserire il file .spec in "~/rpmbuild/SPECS" chiamandolo "NAME.spec" , dove NAME è il nome base del pacchetto. Per creare tutti i pacchetti (sia binari che pacchetti sorgenti), si dove passare alla directory "~/rpmbuild/SPECS" ed eseguire:

$ rpmbuild -ba NAME.spec

Quando viene richiamato in questo modo rpmbuild legge il file .spec e tenta di passare attraverso le seguenti fasi (in questo ordine: i nomi che iniziano con % sono macro predefinite come descritto di seguito):

Fase Letture Scritture Azioni
%prep %_sourcedir %_builddir Legge i sorgenti e le patch nella directory %_sourcedir. Questa fase scompatta il sorgente in una sotto-directory inferiore alla directory di build %_builddir (di solito ~/rpmbuild/BUILD/) e applica le patch.
%prep %_sourcedir %_builddir Compila i file nella directory sotto quella di build %_builddir. Di solito si possono implementare qui alcune variazioni di "./configure && make".
%check %_builddir %_builddir Verifica che il software funziona propriamente. Fase spesso implementata per eseguire alcune variazioni di "make test". Molti pacchetti non implementano questa fase.
%install %_builddir %_buildrootdir Questa fase legge i file nella directory sotto quella di build %_builddir e scrive in una directory sotto la root build directory %_buildrootdir. I file che sono scritti si suppone che saranno installati quando il pacchetto dei binari viene installato dall'utente finale. Attenzione alla strana terminologia: La directory build root non è la stessa della build directory. Questa fase è implementata da "make install".
bin %_buildrootdir %_rpmdir Legge la directory sotto la build root directory %_buildrootdir per creare un pacchetto RPM binario sotto la directory RPM %_rpmdir. All'interno della directory RPM vi è una directory per ogni architettura ed una denominata "noarch" per pacchetti che si possono applicare a molte architetture. Questi file RPM sono i pacchetti che gli utenti andranno ad installare.
src %_sourcedir %_srcrpmdir Questa crea un pacchetto sorgente RPM (.src.rpm) all'interno della directory RPM sorgente %_srcrpmdir. Questi file sono necessari per una revisione e un aggiornamento del pacchetto.


Come si può vedere, alcune directory hanno scopi particolari per rpmbuild. Queste sono:

Nome della Macro Nome Di solito Scopo
%_specdir Specification directory ~/rpmbuild/SPECS file di specifica RPM (.spec)
%_sourcedir Source directory ~/rpmbuild/SOURCES Pacchetto dei sorgenti incontaminati (es: tarballs) e patch
%_builddir Build directory ~/rpmbuild/BUILD I file sorgente vengono spacchettati e compilati nella sua subdirectory.
%_buildrootdir Build root directory ~/rpmbuild/BUILDROOT I file vengono installati qui durante la fase %install.
%_rpmdir Binary RPM directory ~/rpmbuild/RPMS Binari RPM sono creati e immagazzinati qui sotto.
%_srcrpmdir Source RPM directory ~/rpmbuild/SRPMS Gli RPM sorgente sono creati e immagazzinati qui sotto.

Se una fase si interrompe prematuramente, è necessario guardare l'output per capire perché è fallita, cambiare il file .spec (o altri file di input) a seconda delle necessità.

Prepararsi per pacchettizzare un programma in particolare

Se ci sono programmi speciali richiesti per costruire o avviare il programma da pacchettizzare, installarli e prendere nota di cosa sono (queste informazioni serviranno).

Per pacchettizzare un programma per i repository Fedora, si devono pacchettizzare i sorgenti incontaminati (originali), insieme a patch e istruzioni di costruzione; non va bene cominciare con codice precompilato. Salvare il file con il sorgente originale (solitamente un file .tar.gz) nella cartella "~/rpmbuild/SOURCES" (dell'utente costruttore di rpm).

Leggere dal manuale le istruzioni d'installazione del programma; si deve rendere automatizzato il tutto editando uno ".spec" file, quindi capire cosa si deve fare prima. Probabilmente è meglio fare una prova di compilazione attraverso la procedura di costruzione/installazione senza usare l'RPM per prima (è consigliato specialmente se non si ha dimistichezza con gli rpm). Con qualche eccezione, tutti i programmi binari e le librerie incluse nei pacchetti Fedora devono essere costruiti dal codice sorgente contenuto nei pacchetti sorgente.

Suddividere il programma

Il codice sorgente delle applicazioni è spesso rilasciato con il codice sorgente di librerie esterne incorporate. Non incorporare insieme librerie esterne e applicazione che le usa in un singolo pacchetto. Al contrario separarle in più pacchetti.

Licenza

Usare solo software che può essere pacchettizzato legalmente.

Leggere Packaging:Guidelines#Legal, Licensing:Main and Packaging:LicensingGuidelines. In generale, serve ai soli pacchetti software rilasciati come open source software (OSS) con una licenza approvata (così come le GNU GPL, GNU LGPL, BSD-new, MIT/X o Apache 2.0). Assicurarsi che il software sia realmente licenziato in questo modo (ad esempio controlli casuali del codice sorgente degli header, README file e così via). Se ci sono pacchetti di librerie, assicurarsi che anch'esse siano OSS.

Riusare informazioni esistenti

Provare a riutilizzare quello che si può. Ovviamente, assicurarsi che non si stia pacchettizzando qualcosa che già esiste; nella Fedora Package Collection Fedora Package Database c'é una lista dei pacchetti esistenti. Inoltre controllare la In Progress Review Requests (per pacchetti in fase di revisione) e la lista Retired Packages. E' possibile usare Fedora Packages Git Repositories per vedere direttamente gli .spec file (e patch) di qualsiasi pacchetto esistente in Fedora.

E' possibile scaricare gli RPM sorgenti usando un programma del yum-utils, con:

$ yum -y install yum-utils
$ yumdownloader --source sourcepackage-name

In alternativa, un rpm sorgente può essere recuperato manualmente visitando la pagina web Fedora mirror http o ftp, selezionando la cartella releases/41/Everything/source/SRPMS. (rimpiazzare "41" con la versione di Fedora desiderata), e scaricare l'rpm sorgente voluto (il nome termina con .src.rpm).

Ottenuto l'rpm sorgente, installarlo in ~/rpmbuild:

$ rpm -ivh sourcepackage-name*.src.rpm

E' possibile inoltre depacchettizzare il .src.rpm in una directory con rpm2cpio:

$ mkdir PROGRAMNAME_src_rpm
$ cd PROGRAMNAME_src_rpm
$ rpm2cpio ../PROGRAMNAME-*.src.rpm | cpio -i

Qualche volta è più facile iniziare con un pacchetto esistente, per poi ripulirlo per Fedora; RPM Find potrebbe aiutare a trovare RPM per sistemi non-Fedora (si possono installare rpm sorgenti di altri sistemi come in Fedora). In caso, si potrebbe vedere per pacchetti sorgente (non pacchetti .deb binari) per Ubuntu o Debian (pacchetti sorgente sono degli standard tarball con una sottocartella debian/, possibilmente associata con delle patch). Se FreeBSD ports collection dovesse averlo, si potrebbe scaricare il FreeBSD ports tarball e vedere se le loro informazioni di pacchettizzazione possono aiutare come inizio. Tuttavia, questo potrebbe non essere di aiuto a tutti. Differenti distribuzioni hanno differenti regole e quello che fanno potrebbe essere inappropriato per Fedora.

Creare un file spec

E' necessario creare ora il file ".spec" nella directory "~/rpmbuild/SPECS". E' consigliato dare al file il nome del programma (es: "program.spec"). Usare il nome dell'archivio oppure il nome sostenuto dall'autore del programma dove possibile, ma assicurarsi di rispettare le Linee guida per il Naming dei pacchetti.

Creare un file di spec vuoto

Quando si crea uno .spec file per la prima volta, è possibile usare editor come vim o emacs che creeranno automaticamente uno .spec iniziale:

 $ cd ~/rpmbuild/SPECS
 $ vi program.spec

Di seguito un esempio di questo template (Notare: il modello fornito non deve necessariamente essere confirme con le linee guida del Fedora Packaging):

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


E' possibile usare $RPM_BUILD_ROOT al posto di %{buildroot}; basta che siano coerenti.

E' possibile usare il comando rpmdev-newspec per creare un file di .spec . rpmdev-newspec NOME-DEL-NUOVO-PACCHETTO crea un file spec iniziale per un nuovo pacchetto, su misura per vari tipi di pacchetti. Il programma individuerà il tipo di modello da usare dal nome del pacchetto, oppure specificare un particolare tipo di modello. Controllare /etc/rpmdevtools/spectemplate-*.spec per consultare i modelli disponibili e rpmdev-newspec --help per maggiori informazioni. Per esempio, per creare un nuovo file di spec per un modulo python:

cd ~/rpmbuild/SPECS
rpmdev-newspec python-antigravity
vi python-antigravity.spec

File .spec d'esempio

L'esempio di seguito mostra uno .spec per Fedora 16 per il programma eject:

Summary:            A program that ejects removable media using software control
Name:               eject
Version:            2.1.5
Release:            21%{?dist}
License:            GPLv2+
Group:              System Environment/Base
Source:             %{name}-%{version}.tar.gz
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
URL:                http://www.pobox.com/~tranter
ExcludeArch:        s390 s390x
BuildRequires:      gettext
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
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1

%build
%configure
make %{?_smp_mflags}

%install
make DESTDIR=%{buildroot} install

install -m 755 -d %{buildroot}/%{_sbindir}
ln -s ../bin/eject %{buildroot}/%{_sbindir}

%find_lang %{name}

%files -f %{name}.lang
%doc README TODO COPYING ChangeLog
%{_bindir}/*
%{_sbindir}/*
%{_mandir}/man1/*

%changelog
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.5-21
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild

* Fri Jul 02 2010 Kamil Dudka <kdudka@redhat.com> 2.1.5-20
- handle multi-partition devices with spaces in mount points properly (#608502)

Panoramica SPEC file

Altre utili guide:

  • La Guida RPM descrive nei dettagli come riempire uno spec file.
  • La serie IBM "Packaging software with RPM" Parte 1, Parte 2 e Parte 3 è altrettanto utile.
  • Maximum RPM ha informazioni più complete ma è datata.

Seguire la linee guida Package Naming Guidelines, Packaging Guidelines e Package review guidelines.

Si possono inserire commenti con il carattere "#", ma non inserire le potentially-multiline-macros (parole che iniziano con "%") in un commento (macros are expanded first); se si decommenta una linea, raddoppiare il segno percentuale ("%%"). Inoltre, non usare "#" sulla stessa linea dopo un comando script.

I principali tag sono listati di seguito. Notare che le macro %{name}, %{version} and %{release} possono essere usate come riferimanto a Nome, Versione e Release rispettivamente. Quando si cambia un tag, la macro automaticamente aggiorna al nuovo valore.

  • Name: Il nome del pacchetto, che dovrebbe incontrare quello dello SPEC file. Deve seguire le Linee Guida e generalmente usa caratteri minuscoli.
  • Version: Il numero di versione dall'upstream. Vedere la Sezione Version tag delle linee guida sulla pacchetizzazione. Se il numero di versione contiene tag non numerici, è necessario includere il carattere non numerico nel tag Release. Se l'upstream usa la data per intero per distinguere le versioni, considerare l'uso di numeri di versione nella forma yy.mm[dd] (ad esempio 2008-05-01 diventa 8.05).
  • Release: Il valore iniziale dovrebbe essere 1%{?dist}. Incrementare il numero ad ogni nuovo rilascio della stessa versione. Quando arriva un nuovo rilascio, cambiare il tag Version per abbinare e reimpostare in numero Release a 1. Controllare la sezione Release delle linee guida. L'opzionale Dist tag potrebbe essere utile.
  • Summary: Un breve sommario one-line del pacchetto. Usare l'inglese americano. Non finisce in un periodo.
  • Group: Necessita di un gruppo preesistente, come "Applications/Engineering"; avviare "less /usr/share/doc/rpm-*/GROUPS" per conoscere la lista completa. Usare il gruppo "Documentation" per qualsiasi sotto pacchetto (ad esempio kernel-doc) contenente documentazione.
  • License: La licenza che deve essere open source. Non usare vecchi tag Copyright. Usare abbreviazioni standard ("GPLv2+") e specifiche (usare "GPLv2+" per la GPL versione 2 o successive invece del solo "GPL" oppure "GPLv2"). Vedere Licensing e le Licensing Guidelines. E' possibile listare più licenze combinandole con "and" e "or" (ad esempio "GPLv2 e BSD").
  • URL: L'intero URL per avere maggiori informazioni sul programma (ad esempio il sito del progetto). Notare: Non è un collegamento al codice sorgente originale che invece appare al tag Source0.
  • Source0: L'intero URL all'archivio compresso contenente il codice sorgente originale, come rilasciato dall'upstream. "Source" è sinonimo di "Source0". Se si fornisce l'URL completo (come dovrebbe essere), il suo nome verrà utilizzato nella cartella SOURCES. Se possibile, incorporare %{name} e %{version}, così che le modifiche possano andare al posto giusto. Preservare il timestamps quando si scaricano i file sorgente. Se esistono più sorgenti, nominarli Source1, Source2 e così via. Se si aggiungono nuovi file, listarli come sorgenti dopo quelli originali. Una copia di ognuno di questi verrà inclusa in un SRPM, se non diversamente specificato. Vedere Source URL per maggiori informazioni su casi speciali (ad esempio sulla revisione).
  • Patch0: Il nome della prima patch da applicare al sorgente. Se serve applicare una patch dopo la decompressione, si dovrebbero editare i file e salvarne le modifiche come un "file patch" nella cartella ~/rpmbuild/SOURCES. Le Patch dovrebbero fare una modifica alla volta, quindiè ossibile avere più file patch.
  • BuildArch: Se i file da pacchettizzare sono indipendenti dall'achitettura (ad esempio shell script, file data), allora aggiungere "BuildArch: noarch". L'architettura per gli RPM binari sarà "noarch".
  • BuildRoot: La cartella "d'installazione" durante il processo %install (dopo %build). E'aggiuntivo in Fedora mentre è necessario in EPEL5. Normalmente la root build è in "%{_topdir}/BUILDROOT/".
  • BuildRequires: Lista dei pacchetti richiesti per la compilazione del programma. Questo campo può essere (e lo è comunemente) ripetuto su più linee. Queste dipendenze non sono automaticamente determinate così serve includerle tutte. Alcuni pacchetti comuni possono essere omessi, come gcc. E' possibile specificarle in minima parte se necessario (ad esempio "ocaml >= 3.08"). Se serve il file /EGGS, determinarne il pacchetto che lo possiede con "rpm -qf /EGGS". Se serve il programma EGGS, determinarne il pacchetto che lo possiede con "rpm -qf which EGGS". Mantenere le dipendenze ad un numero minimo (ad esempio usare sed invece di perl se non serve realmente perl), ma attenzione poiché alcune applicazioni disabilitano permanente le funzioni associate a dipendenze mancanti; in questi casi serve includere i pacchetti addizionali. Il comando "auto-br-rpmbuild" può essere utile.
  • Requires: Lista di pacchetti richiesti quando in programma è installato. Notare che il tag BuildRequires lista ciò che serve per la compilazione dell'RPM binario, mentre il tag Requires lista ciò che è necessario per installare e far funzionare il software; un pacchetto può essere presente in entrambe le liste. In molti casi rpmbuild recupera automaticamente le dipendenze quindi il Requires tag non è sempre utile. Tuttavia è possibile evidenziare pacchetti specifici richiesti.
  • %description: Una lunga descrizione del programma. Usare l'inglese americano. Tutte le linee devono essere al massimo di 80 caratteri. Le linee vuote indicano un nuovo paragrafo. Alcune interfaccie grafiche d'installazione software riformatteranno i paragrafi; le linee che iniziano con uno spazio vuoto verranno trattate come testo preformattato e visualizzate come sono, normalmente con caratteri fixed-width. Vedere la Guida RPM.
  • %prep: Comandi script per "preparare" il programma (ad esempio decomprimere) così che tutto sia pronto per la compilazione. Tipcamente "%setup -q"; una comune variante è "%setup -q -n NAME" se il file sorgente spacchetta in NAME. Vedere la sezione %prep.
  • %build: Comandi script per "costruire" il programma (ad esempio compilare) ed ottenerlo pronto per l'installazione. Incluse le istruzion su come farlo. Vedere la sezione %build.
  • %check: Comandi script per "testare" il programma. E' avviato tra le procedure %build e %install, quindi piazzarlo tra le due se serve. Spesso contiene semplicemente "make test" oppure "make check". E' separato da %build così da poter essere saltato a discrezione dell'utente.
  • %install: Comandi script per "installare" il programma. I comandi dovrebbero copiare file dalla cartella BUILD %{_builddir} nella buildroot %{buildroot}. Vedere la sezione %install.
  • %clean: Istruzioni su come ripulire la build root. Notare che questa sezione è ridondante in Fedora mentre è necessaria per EPEL. Tipicamente contiene solo:
rm -rf %{buildroot}
  • %files: Lista di file che saranno installati. Vedere la sezione %files.
  • %changelog: Modifiche nel pacchetto. Usare l'esempio sopra.
  • ExcludeArch: Se il pacchetto non compila, costruisce o funziona correttamente in una particolare architettura, listare le architetture coinvolte sotto questo tag.
  • E' possibile aggiungere sezioni in modo da avviare codice quando i pacchetti vengono installati o rimossi nel sistema reale (piuttosto che avviare soltanto lo script %install, che opera soltanto una pseudo-installazione nella build root). Queste sono chiamate "scriptlets" e solitamente sono usate per aggiornare il sistema avviato con informazioni dal pacchetto. Vedere la sezione "Scriptlets".

RPM inoltre supporta la creazione di diversi pacchetti (detti subpackage) da un singolo SPEC file, come name-libs e name-devel.

Non usare questi tag:

  • Packager
  • Vendor
  • Copyright

Non creare un pacchetto "relocatable"; non portano valore in Fedora e fanno cose complicate.

Approfondimento sezioni SPEC file

Sezione %prep

La sezione "%prep" descrive come spacchettare gli archivi compressi così da poter essere costruiti. Tipicamente, è un set di comandi "%setup" e/o %patch con riferimenti alle linee Source0:, Source1:, etc. Vedere la sezione su %setup e %patch in Maximum RPM per maggiori dettagli.

Le macro %{patches} e %{sources} sono disponibili da RPM 4.4.2 e sono utili se si usa una lunga lista di patch o sorgetni:

for p in %{patches}; do
    ...
done

Tuttavia tener presente che usandole si otterranno .spec file incompatibli con RPM usati in RHEL ed altre distro basate su RPM.

Sezione %prep: comando %setup

Il comando "%setup" spacchetta i sorgente.

  • -q : Sopprime output non necessari. Comunemente usato.
  • -n name : Se il tarball Source decomprime in una directory non nominata come l'RPM, questa opzione può essere usata per specificare il corretto nome. Per esempio, se la directory si chiama, usare "%setup -q -n FOO".
  • -c name : Se il tarball Source in più cartelle invece di una singola, l'opzione può essere usata per crearne una chiamata name.

Ci sono più opzioni %spec, utli principalmente se si sanno creando sottoacchetti. Quelle principali sono:

-a number Decomprime il Source dato dal numero indicato dopo aver cambiato cartella (ad esempio "–a 0" per Source0).
-b number Decomprime il Source dato dal numero indicato prima aver cambiato cartella (ad esempio "–a 0" per Source0).
-D Non cancella la cartella dopo la decompressione.
-T Disabilita la decompressione automatica dell'archivio.

Sezione %prep: comando %patch

Il comando "%patch0" applica Patch0 (e %patch1 applica Patch1 etc.). Le patch sono normali metodi di modifica necessari per "aggiustare" il codice sorgente. Si applica la solita opzione "-pNUMBER" che passa l'argomento al programma patch.

I file Patch sono nominati spesso come "telnet-0.17-env.patch", nel formato %{name} - %{version} - REASON.patch" (a volte la versione è omessa). I file Patch sono il risultato di "diff -u"; se si fa dalla subdirectory di ~/rpmbuild/BUILD allora non è necessario specificare un livello -p.

Questa è la tipica procedura per creare una patch da un singolo file:

cp foo/bar foo/bar.orig
vim foo/bar
diff -u foo/bar.orig foo/bar > ~/rpmbuild/SOURCES/PKGNAME.REASON.patch

Se si editano molti file, un metodo facile è la copia dell'intera subdirectory sotto BUILD per poi avviare il diff. Dopo aver cambiato cartella a "~rpmbuild/BUILD/NAME", allora:

cp -pr ./ ../PACKAGENAME.orig/
... modifiche ...
diff -u ../PACKAGENAME.orig . > ~/rpmbuild/SOURCES/NAME.REASON.patch

Se si modificano più file in una sola patch, è possibile anche copiare quelli originali usando alcune desinenze come ".orig" prima di modificarle. Per poi usare "gendiff" (nel pacchetto rpm-build) per creare una patch con le modifiche.

Assicurarsi che le patch corrispondano correttamente al contesto. Il valore predefinito "fuzz" è "0". Ci si può lavorare aggiungendo "%global _default_patch_fuzz 2" per ripristinare il valore trovato nelle vecchie versioni dell'RPM in Fedora, ma generalmente è raccomandato evitarlo.

Come spiegato in Packaging/PatchUpstreamStatus, tutte le patch dovrebbero avere un commento nello .spec file sul loro stato nell'upstream, includendo il bug, la data e la mail. Se è unico si dovrebbe menzionarne il motivo. Il Fedora Project non vuole allontanarsi dagli sviluppi dell'upstream; vedere PackageMaintainers/WhyUpstream.

Sezione %prep: file non modificati

A volte uno o più file del Source non necessitano d'essere decompressi. Si possono "prep" (prepararli) nella cartella build come (dove SOURCE1 si riferisce al corrispondente file Source):

cp -p %SOURCE1 .

Sezione %build

La sezione "%build" è qualche volta complicata; in essa si può configurare e compilare/costruire i file che saranno installati.

Molti programmi seguono la GNU configure (o alcune varianti). Come predefinito, installeranno in un prefix "/usr/local", ragionevolmente per dei file spacchettati. Tuttavia una volta impacchettati, cambia in "/usr". Le librerie dovrebbero essere installate o in /usr/lib oppure in /usr/lib64 in base all'architettura.

Dal momento che GNU configure è così comune, la macro "%configure" può essere usata per invocare automaticamente le corrette opzioni (ad esempio cambiare il prefix a /usr). Alcune sue varianti funzionano spesso:

 %configure
 make %{?_smp_mflags}

Per sostituire le variabili del makefile, passarle come parametro a make:

make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}

Per maggiori informazioni vedere "GNU autoconf, automake, and libtool" e "Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer.

Alcuni programmi usano cmake. Vedere Packaging/cmake.

Sezione %check

Se disponibili dei self-test, è buona idea includerli. Dovrebbero essere piazzati nella sezione %check (che segue la sezione %build) invece che all'interno della %build stessa, così da poter essere facilmente saltati se necessario.

Spesso questa sezione contiene:

make test

Sezione %install

Questa sezione coinvolge degli script per "install" (installare) il programma, copiando i file rilevanti da %{_builddir} a %{buildroot} (che solitamente significa da ~/rpmbuild/BUILD a ~/rpmbuild/BUILDROOT) e creando e cartelle all'interno di %{buildroot}.

Parte della terminologìa può essere fuorviante:

  • La "build directory", anche conosciuta come %{_builddir}, non è la stessa della "build root", conosciuta anche come %{buildroot}. La compilazione avviene nella prima, mentre i file da impacchettare sono copiati dalla prima alla seconda.
  • Durante la sezione %build, la cartella di partenza è %{buildsubdir}, sottocartella all'interno di %{_builddir}, creata precedentemente durante il %prep. Di solito è qualcosa del genere ~/rpmbuild/BUILD/%{name}-%{version}.
  • La sezione %install non parte quando l'RPM binario è installato dall'utente finale, ma è avviata solo nella creazione del pacchetto.

Alcune varianti di "make install" sono eseguite qui:

%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install

La rimozione di %{buildroot} non è più necessario, eccetto per EPEL 5.

Idealmente si dovrebbe usare DESTDIR=%{buildroot} se il programma lo supporta, dato che redirige i file d'installazione alla specifica cartella ed è esattamente ciò che ci si aspetta che faccia durante la sezione %install.

Se il programma non supporta DESTDIR (e solo se), è possibile in alternativa una delle seguenti strade:

  • Patchare il makefile così che possa supportare DESTDIR. Creare cartelle all'interno di DESTDIR dove necessario e includerne la patch dall' upstream.
  • Usare la macro "%makeinstall". Questo metodo potrebbe funzionare, ma può portare a fallimenti. Tramite la macro si arriva a qualcosa del genere "make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install", che in alcuni programmi pu non funzionare. Creare cartelle all'interno di %{buildroot} dove serve.
  • Considerare l'uso del pacchetto auto-destdir. Richiede "BuildRequires: auto-destdir" and di cambiare "make install" in "make-redir DESTDIR=%{buildroot} install". Funziona bene se l'installazione usa solo certi comandi comuni per installare i file, come cp e install.
  • Installare manualmente. Dovrbbe includere la creazione delle necessarie cartelle sotto %{buildroot} e la copia dei file da %{_builddir} a %{buildroot}. Bisogna essere cauti con gli aggiornamenti, contengono spesso nuovi filename. Un esempio di questa procedura:
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}%{_bindir}/
cp -p mycommand %{buildroot}%{_bindir}/

Come annotato in Packaging:Guidelines#Timestamps, tentare di preservare i timestamp se il makefile consente di ignorare i comandi:

make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install

Sezione %files

Questa sezione dichiara i file e le cartelle proprietà del pacchetto quindi incorporati nell'RPM binario.

Nozioni sulla sezione %files

Il %defattr imposta i permessi predefiniti del file e spesso appare all'inizio della sezione %files. Da notare che non è più necessario a meno che non bisogna i permessi. Il formato è:

%defattr(<file permissions>, <user>, <group>, <directory permissions>)

Il quarto parametro è solitamente omesso. Si usa %defattr(-,root,root,-), dove "-" usa i permessi predefiniti.

Si dovrebbero poi elencare i file e le cartelle che saranno di proprietà del pacchetto. A tal proposito usare le macro per i nomi delle cartelle, mostrate in Packaging:RPMMacros (ad esempio usare %{_bindir}/mycommand invece di /usr/bin/mycommand). Se la stringa inizia con "/" (o quando esteso da una macro) allora viene prelevato dalla cartella %{buildroot}. Oppure, si presume che il file sia nella cartella corrente (ad esempio dentro %{_builddir} come per i file di documentazione da includere). Se il pacchetto installa un solo file /usr/sbin/mycommand, la sezione %files può semplicemente essere:

%files
%{_sbindir}/mycommand

Per ottenere un rpm meno soggetto ai cambiamenti dell'upstream, dichiarare tutti i file all'interno di una cartella di proprietà del pacchetto con la stringa:

%{_bindir}/*

Per includere una singola cartella:

%{_datadir}/%{name}/

Notare che %{_bindir}/* non dice che il pacchetto in oggetto sia proprietario della cartella /usr/bin, ma solo dei file contenuti all'interno. Se si elenca una cartella, allora si richiede la proprietà di quella cartella e dei file e sottocartelle contenute. Quindi non si elenca %{_bindir} assicurardosi anche delle cartelle condivise con altri rpm.

Si verificheranno errori se:

  • una stringa non incontra alcun file o cartella
  • file o cartelle sono elencate più volte
  • file o cartelle in %{buildroot} non listate

E' inoltre possibile escludere file usando %exclude. Può aiutare per includere quasi tutti i file da differenti stringhe ma fallirà se non incontra nulla.

%files prefix

Si può aver bisogno di aggiungere uno o più prefix alle linee della sezione %files; separate da uno spazio. Vedere Max RPM section on %files directives.

Solitamente "%doc" è usato per elencare file di documentazione dentro %{_builddir} che non sono stati copiati in %{buildroot}. I file README e INSTALL sono di solito inclusi. Saranno piazzati nella cartella /usr/share/doc/%{name}-%{version}, la cui proprietà non ha bisogna d'essere dischiarata.

Notare: Se si specifica una voce %doc entry, non si possono copiare i file nella cartella della documentazione durante la sezione %install. Se, per esempio, si vuole una cartella di prova all'interno della cartella della documentazione, non usare %doc, ma creare le cartelle e copiarci i file manualmente in %{buildroot}%{_defaultdocdir}/%{name}-%{version} durante la sezione %install. Saranno correttamente marcate come documentazione. Assicurarsi di includere %{_defaultdocdir}/%{name}-%{version}/ come voce nella sezione %files.

I file di configurazione dovrebbero essere posti in /etc e sono normalmente specificati così (che preserva le modifiche durante gli aggiornamenti):

%config(noreplace) %{_sysconfdir}/foo.conf

Se l'aggiornamento usa un formato di configurazione non-retrocompatibile, specificarli così:

%config %{_sysconfdir}/foo.conf

"%attr(mode, user, group)" può essere usato per controlli più precisi sui permessi, dove "-" significa usare il predefinito:

%attr(0644, root, root) FOO.BAR

Se un file è in lingua naturale, usare %lang per annotarlo:

%lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh*

I programmi che utilizzano file di localizzazione dovrebbero seguire i metodi raccomandati per gestire i file i18n:

  • trovare i filename nel passaggio %install: %find_lang ${name}
  • aggiungere le dipendenze per la costruzione richieste: BuildRequires: gettext
  • usare i filename trovati: %files -f ${name}.lang

Questi prefix non sono validi in Fedora: %license and %readme.

%files e Filesystem Hierarchy Standard (FHS)

Riferimento a Filesystem Hierarchy Standard (FHS).

Gli eseguibili vanno in /usr/bin, i file di configurazione globali vanno in /etc, le librerie in /usr/lib (o /usr/lib64) e così via. C'é un'eccezione: eseguibili non eseguiti normalmente direttamente dall'utente o dall'amministratore dovrebbero andare nella sottocartella di /usr/libexec, denominata con %{_libexecdir}/%{name}.

Non installare file in /opt o in /usr/local.

Sfortunatamente molt programmi non rispettano la FHS. In particolare, librerie indipendenti dall'architettura vengono inserite in /usr/lib invece di /usr/share. Il primo è per librerie diendenti dall'architettura, mentre il secondo è per quelle indipendenti; significa che i sistemi con differenti architetture di CPU possono condividere la /usr/share. Ci sono molte eccezioni in Fedora (Python e Perl), ma Fedora applica queste regole più rigidamente rispetto ad alcune altre distro. rpmlint generalmente segnala se si mette qualcosa di diverso dai file ELF in /usr/lib.

Esempio di %files

Di seguito un esempio di sezione %files:

%files
%doc README LICENSE
%{_bindir}/*
%{_sbindir}/*
%{_datadir}/%{name}/
%config(noreplace) %{_sysconfdir}/*.conf

Trovare duplicati

Per listare qualsiasi duplicato di un rpm:

cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture
rpm -qlp PACKAGE1.*.rpm | sort > ,1
rpm -qlp PACKAGE2.*.rpm | sort > ,2
comm -12 ,1 ,2

Scriptlet

Quando un utente installa l'rpm, si consigliano alcuni comandi da eseguire. Questo si può ottenere con gli scriptlet. Vedere Packaging/ScriptletSnippets.

Gli scriptlet si eseguono:

  • prima (%pre) o dopo (%post) l'installazione di un pacchetto
  • prima (%preun) o dopo (%postun) la disinstallazione di un pacchetto
  • all'avvìo (%pretrans) o alla fine (%posttrans) di una transazione

Per esempio, ogni rpm binario che immagazzina file di librerie condivise in qualsiasi percorso di dynamic linker, deve richiamare ldconfig in %post e %postun. Se il pacchetto ha molti sottopacchetti con librerie, ognuno di essi dovrebbe fare la stessa cosa.

%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig

Se si esegue un solo comando, l'opzione "-p" avvìa il comando adiacente senza invocare la shell. Tuttavia, per diversi comandi, ometterla e aggiungere tutti i comandi shell.

Se si avvìa un programma negli scriptlet, qualsiasi richiesta va specificata nella forma "Requires(CONTEXT)" (ad esempio Requires(post)).

%pre, %post, %preun e %postun forniscono l'argomento $1, che è il numero di pacchetti di questo nome che saranno lasciati nel sistema. Non confrontare per uguaglianza con 2, controlla invece se sono meggiori o uguali a 2. Per %pretrans e %posttrans, $1 è sempre 0.

Per esempio se il pacchetto installa un manuale il quale indice deve essere aggiornato con install-info dal pacchetto info, innanzitutto non è garantita la presenza del pacchetto info senza una sua richiesta specifica e poi non si può fallire completamente se install-info non funziona:

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

Esiste un altro problema tecnico relativo all'installazione dei manuali. Il comando install-info aggiornerà la certella delle informazioni, quindi si dovrebbero cancellare le cartelle vuote inutilizzate da %{buildroot} durante la sezione %install:

rm -f %{buildroot}%{_infodir}/dir

Un'altra abilità simile agli scriptlet è "trigger", avviabile quando altri pacchetti sono installati o disinstallati. Vedere RPM Triggers.

Macro

La macro è un testo nel formato %{string}. Tipiche macro:

Macro Estensione tipica Significato
%{_bindir} /usr/bin Cartella dei binari: dove gli eseguibili vengono solitamente localizzati.
%{_builddir} ~/rpmbuild/BUILD Cartella per il build: i file sono compilati all'interno della sua sottocartella. Vedere %buildsubdir.
%{buildroot} ~/rpmbuild/BUILDROOT Build root: dove i file vengono "installati" durante %install, che li copia dalla sottocartella di %{_builddir} a quella di %{buildroot}. (Storicamente, %{buildroot} era in "/var/tmp/".)
%{buildsubdir} %{_builddir}/%{name} Sottocartella build: interna a %{_builddir} dove i file sono compilati durante %build. E' impostata dopo %setup.
%{_datadir} /usr/share Cartella condivisa.
%{_defaultdocdir} /usr/share/doc Cartella predefinita della documentazione.
%{dist} .fcNUMBER Versione della distro (ad esempio ".fc9")
%{fedora} NUMBER Numero di rilascio di Fedora (e.g. "9")
%{_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} /var/lib
%{_sysconfdir} /etc
%{version} Versione del pacchetto, impostata tramite il tag Version:

Se ne può sapere di più sulle macro guardando in /etc/rpm/* e /usr/lib/rpm, specialmente /usr/lib/rpm/macros. Inoltre usare rpm --showrc per saperne i valori che RPM userà per le macro (alterate da rpmrc e i file di configurazione delle macro).

E' possibile impostare le proprie macro usando %global, ma assicurarsi di definirle prima dell'uso. (Le definizioni possono riferirsi anche ad altre macro.) Per esempio:

%global date 2012-02-08

Usare l'opzione "-E"di rpmbuild per trovare il valore della macro nello .spec file:

rpmbuild -E '%{_bindir}' myfile.spec

Vedere anche Packaging/RPMMacros e RPM Guide capitolo 9.

Altri tag

In aggiunta ai tag Requires e BuildRequires, esistono questi per il controllo delle dipendenze:

  • Provides: lista i nomi dei pacchetti virtuali forniti. Ad esempio, ci potrebbe essere un pacchetto "foo" che esige una particolare funzionalità "bar" da un altro programma. Se esistono parecchi pacchetti che epossono soddisfarla, è possibile specificarli con "Provides: bar" e il pacchetto "foo" può specificare "Requires: bar". Si potrebbero anche usare metodi "alternativi", ma evitare se più utenti hanno necessità differenti, visto che queste impostazioni sono a livello di sistema. Usare "rpm -q --provides PACKAGENAME" per vedere cosa fornisce un determinato pacchetto. Alcuni esempi di pacchetti virtuali in Fedora:
    • MTA: Usato per i mail transport agents come sendmail.
    • tex(latex): Usato per latex
  • Obsoletes: rimuove un altro pacchetto(i) nominato(i) se installato(i). Usare se il nome del pacchetto cambia o se è totalmente rimpiazzato da un differente paccehtto.
  • Conflicts: specifica quali altri pacchetti non possono essere installati simultaneamente a quello in oggetto. Evitarlo se possibile. Vedere Packaging/Conflicts.
  • BuildConflicts: specifica quali pacchetti non possono essere installati se si costruisce il pacchetto in oggetto. Evitarlo se possibile.

Per gestire differenti architetture, ci sono due tag:

  • ExcludeArch: per escluderne una nella quale la costruzione del pacchetto non avviene. Ad esempio:
ExcludeArch: ppc
  • ExclusiveArch: per includere solo quella specificata. Evitarlo se non assolutamente corretto.

Architetture valide sono listate in Architectures.

Subpackage

Uno SPEC file può definire diversi binari. In altre parole, un SRPM con uno SPEC file può risultare in più RPM. Notare che c'é ancora un solo processo di creazione (%prep, %build, %install etc.). Sottopacchetti name-doc e name-devel sono comuni per la documentazionee i file di sviluppo rispettivamente.

Usare la direttiva %package per iniziare la definizione di un sottopacchetto:

%package subpackage_name

Dopo ogni direttiva %package, listarne i tag. Dovrebbe almeno includere i tag Summary e Group, oltre a %description subpackage_name e %files subpackage_name:

Tutto quanto non specificato dal sottopacchetto sarà ereditato dal suo genitore.

Come predefinito, se il nome del pacchetto è "foo" e quello del sottopacchetto è "bar", allora i nomi risultanti saranno foo-bar". E' possibile evitarlo con l'opzione "-n" (ma servirà usarlo in tutte le altre direttive una volta qui specificato):

%package -n new_subpackage_name

Leggere la sezione sui sottopacchetti della Guida RPM per maggiori informazioni.

Condizionali

E' possibile inserire stati di condizione, ad esempio per verificare se si sta creando un binario per una certa architettura:

%ifarch ARCHITECTURE_NAME

versione negata con:

%ifnarch ARCHITECTURE_NAME

o più condizioni generiche:

%if TRUE_OR_FALSE

C'é una sezione opzionale "%else"; tutte queste vengono chiuse con "%endif".

Linee guida specifiche

Ci sono molte linee guida specifiche che sono di aiuto (ad esempio per i linguaggi di programmazione specifici, per applicazioni, librerie e sistemi di build). Molte di loro sono elencate come parte delle Application Specific Guidelines of Packaging/Guidelines. Esempi di linee guida:

Altre sono:

Suggerimenti vari

Packaging/FrequentlyMadeMistakes contiene informazioni sugli errori più comuni commessi. Ci sono anche altre raccomandazioni e trucchi controversi in PackageMaintainers/Packaging Tricks.

Provare a scrivere i propri .sepc files così da funzonare quando nuove versioni dall'upstream sono pronte, senza nessuna modifica a parte il numero di versione e l'aggiornamento dei sorgenti. Per esempio, se contiene file *.txt con istruzioni d'esecuzione, invece di fare

 chmod a-x Filename1.txt Filename2.txt Filename3.txt

considerare comandi come il seguente:

 chmod a-x *.txt

Se si vogliono vedere un sacco di esempi di scriptlet, è possibile mostrarli tutti dai pacchetti installati con:

 rpm -qa --queryformat "\n\nPACKAGE: %{name}\n" --scripts | less

Non cercare di interagire con l'utente; RPM è designato per supportare tante installazioni. Se un'applicazione necessita di mostrare un EULA (End User License Agreement), quest'ultima dev'essere parte dell'esecuzione iniziale e non dell'installazione.

Non si dovrebbero avviare servizi poiché potrebbero rallentare il tutto. Se si installa uno script init e systemd, considerare l'uso di chkconfig o di systemctl per far sì che gli stessi vengano avviati o arrestati al successivo riavvìo. Prima di disinstallare, si dovrebbe normalmente tentare di fermare i suoi servizi se in esecuzione in quel momento.

La disinstallazione dovrebbe togliere tutte le modifiche fatte nell'installazione, ma non i file creati dall'utente.

Normalmente, se ci sono binari eseguibili, i simboli di debugging sono tolti dall'rpm binario normale e piazzati in un sottopacchetto name-debug. Se non dovesse succedere, si può disabilitare la creazione dell'rpm-debug aggiungendo in cima allo .spec file:

%global _enable_debug_package 0
%global debug_package %{nil}
%global __os_install_post /usr/lib/rpm/brp-compress %{nil}

mentre nella sezione %install:

export DONT_STRIP=1

Un modo per controllare la versione di Fedora in uno .spec file per i build condizionali è:

%if 0%{?fedora} <= <version>

Il ? permette il riconoscimento della versione se %fedora non è definito. Fa sì che il risultato finale sia 0, pur non interferendo sul risultato se presente un valore per %fedora. (Notare che questo metodo non funziona nelle build "scratch" in Koji, dove %fedora è impostato durante la creazione di un SRPM.)

Le GUI devono avere una voce desktop così da permetterne l'uso dal menu grafico. Per i file .desktop, vedere Fedora packaging guidelines for desktop files e desktop entry spec. Per le icone in /usr/share/icons, vedere icon theme spec.

Costruzione del pacchetto binario

Test con rpmlint

Prima di provare a costruire qualsiasi cosa, si dovrebbe eseguire rpmlint sullo spec file:

$ rpmlint program.spec

Troverà molti errori velocemente. Se l'errore riportato non ha molto senso, ridare lo stesso comando aggiungendo l'opzione "-i" (questo darà maggiori informazioni).

L'ideale sarebbe quello d'avere il minor numero di errori, ma talvolta rpmlint riporta dei falsi positivi. Le linee guida Fedora packaging spiega quali sono da ignorare.

Creazione degli RPM dallo spec file

Una volta creato uno spec file, chiamato program.spec, è possibile creare l'rpm sorgente e l'rpm binario semplicemente avviando:

 $ rpmbuild -ba program.spec

Se funziona, i file binari RPM verranno creati nella sottocartella ~/rpmbuild/RPMS/ e l'RPM sorgente in ~/rpmbuild/SRPMS.

Quando qualcosa va male, è possibile entrare ("cd") nella directory appropriata e vedere cosa contiene. Se si vogliono saltare i passaggi precedenti, usare l'opzione "--short-circuit"; è utile quando si è avuto un build con successo, ma si ha un errore nella sezione %install. Ad esempio, per reiniziare lo stage %install (saltando i passaggi precedenti):

$ rpmbuild -bi --short-circuit program.spec

Se si vuole creare l'rpm sorgente (.src.rpm), entrare nella cartella SPECS e:

$ rpmbuild -bs program.spec  

Verrà creato l'rpm sorgente nella cartella ~/rpmbuild/SRPMS. Creare solo l'rpm sorgente è abbastanza veloce, poiché non fa altro che associare lo .spec file e i file SOURCES nel .src.rpm . Creare un rpm binario tipicamente prende più tempo perché richiede l'avvìo degli script %prep, %build e %install.

Testare con rpmlint gli RPM creati

Avviato rpmlint sullo spec file, generato l'RPM binario e generato l'RPM sorgente. rpmlint lavora sugli spec, sugli rpm binari o sorgente, trovando cose differenti in ognuno. E' necessario eliminare o modificare degli "rpmlint warning" prima di rilasciare un pacchetto. Dalla cartella SPECS:

$ rpmlint NAME.spec ../RPMS/*/NAME*.rpm ../SRPMS/NAME*.rpm

Generalmente rpmbuild costruisce rpm binari con informazioni di debug, anche questi possono essere sottoposti al test.

Spostandosi nella cartella "~/rpmbuild/RPMS" poi nella sottocartella denominata dall'architettura (32 o 64 bit) si troveranno alcuni rpm binari. E' possibile vederne facilmente i file ed i permessi con rpmls (assicurarsi di trovare ciò che ci si aspetta):

$ rpmls *.rpm

Se corretti, provare ad installarli diventando root:

$ su
# rpm -ivp package1.rpm package2.rpm package3.rpm ...

Per poi testarli, utilizzandoli in differenti modi. Se si decide di usare uno strumento ad interfaccia grafica (GUI), assicurarsi che venga mostrato nel menu (se non lo è, allora qualcosa è sbagliato alla voce .desktop).

Successivamente è possibile disinstallarli:

# rpm -e package1 package2 package3

Mock and Koji

Mock è un potente tool che usa gli SRPM creati per costruire pacchetti binari all'interno di un ambiente appositamente creato. Questo può essere d'aiuto per la rilevazione delle dipendenze tra pacchetti. Se fallisce, potrebbe mancare qualcosa alla voce BuildRequires. Vedere Using Mock to test package builds per ulteriori info sull'utilizzo di mock; una volta che il proprio account rientra nel gruppo "mock", è possibile avviare comandi come il seguente per eseguire test in locale:

$ mock -r fedora-9-i386 rebuild path_to_source_RPM

Una volta che Mock ha funzionato correttamente, si può usare Koji (il quale usa Mock) per costruire in differenti sistemi. PackageMaintainers/Join e PackageMaintainers/UsingKoji hanno molte informazioni su Koji. Una volta settati, si possono eseguire test sul proprio rpm sorgente con differenti sistemi

$ koji build --scratch dist-f9 path_to_source_RPM

Si può sostituire la voce "%fc9" con qualsiasi altra release successiva di Fedora, ma non usare dist-rawhide. Ricordarsi che i valori di %fedora, %fc9, ... non saranno giusti per una scratch build, quindi non funzioneranno se il proprio .spec file fa qualcosa di diverso basato su quei valori. I build koji possono solo dipendere dai pacchetti che sono attualmente disponibili nei repository TARGET. Quindi non si può usare Koji per costruire per distribuzioni rilasciate se il proprio pacchetto dipende da altri nuovi pacchetti che Bodhi non ha ancora rilasciato. Se si vuole costruire un pacchetto che non è ancora una versione aggiornata stabile, si può aprire un ticket con rel-eng a https://fedorahosted.org/rel-eng/newticket e chiedere che il pacchetto venga aggiunto come buildroot override.

Strumenti utili

Il pacchetto rpmdevtools fornisce diversi strumenti utili; "rpm -qil rpmdevtools" mostra ciò che verrà installato.

  • rpmdev-bumpspec : dal tag release dello spec file, aggiunge un commento al changelog con la data e la versione del software:
$ rpmdev-bumpspec --comment=COMMENT --userstring=NAME+EMAIL_STRING SPECFILES

Il pacchetto yum-utils contiene molti strumenti.

  • yumdownloader: scarica il pacchetto sorgente con:
$ yumdownloader --source PACKAGENAME

Il pacchetto auto-buildrequires ha un paio di buoni strumenti d'aiuto per configurare correttamente la voce BuildRequires. Dopo averlo installato, rimpiazzare "rpmbuild" con "auto-br-rpmbuild" e si vedrà automaticamente generata la lista buildrequires.

Potrebbe essere utile RUST (GPL), anche se non crea rpm di adeguata qualità per i repository Fedora. Alien converte pacchetti di diverso formato. Non produce rpm sorgente puliti ma potrebbe essere utile per la conversione di pacchetti esistenti dai quali trarre informazioni preziose.

Linee guida e regole

Una volta creato il proprio pacchetto, bisogna seguire queste regole e linee guida:

Ci sono molte linee guida ufficiali che possono essere d'aiuto in circostanze particolari (Java programs, OCaml programs, GNOME programs, etc.). Si può inoltre imparare molto dalle sezioni SIGs e Package Maintainers. Lista delle pagine wiki sul Packaging per vedere se qualcuno si applica.

Ulteriormente, si potrebbero trovare utili quelle non ufficiali Packaging Drafts e Packaging Drafts To Do.

Mantenimento del pacchetto

Quando il pacchetto viene accettato, dev'essere mantenuto dal maintainer (o dal co-maintainer). Vedere Package update HOWTO e Package update guidelines per maggiori informazioni. Se si aggiorna a più di una release Fedora, farlo a ritroso nel tempo; ad esempio, release per Fedora N, una volta accettato, Fedora N -1 ( il sistema presuppone che versioni successive di Fedora hanno versioni uguali o più aggiornate dei programmi).

Incoraggiare gli sviluppatori upstream ad usare convenzioni stardard nel rilascio del codice sorgente; questo renderà più facile il packaging del software. Per maggiori informazioni, vedere:

Per maggiori informazioni

La pagina Package Maintainers è collegata a molte altre pagine utili e Package update HOWTO descrive come aggiornare un pacchetto esistente già mantenuto in Fedora.

Per maggiori informazioni, fuori dal wiki Fedora, vedere:

Da notare: il sito rpm5.org ha alcuni documenti ma non dipende da loro; è la casa di un fork di RPM mantenuto da Jeff Johnson. L'RPM usato da Fedora (e da Novell/SuSE) ha invece la sede in rpm.org.
lwn.net contiene un articolo a riguardo.