From Fedora Project Wiki
m (internal link cleaning)
 
(87 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{autolang}}
{{autolang}}


== Creare pacchetti HOWTO==
{{admon/warning|Questa pagina è parzialmente conforme a quella in lingua inglese; verrà aggiornata al completamento delle correzioni sull'originale.}}


Questa pagina descrive in dettaglio i meccanismi di base su come creare un pacchetto RPM specificatamente per Fedora (in particolare, come creare un file. Spec). Vengono dati anche alcuni avvisi pratici su cosa non funziona, che possono farvi risparmiare ''ore'' del vostro tempo.
== Introduzione ==


Questa pagina ''non'' mostra le linee guida ufficiali sulla creazione dei pacchetti di Fedora (per questo, vedere la [Packaging:Guidelines|  Packaging Guidelines]] e [[Packaging:NamingGuidelines|  Package Naming Guidelines]]). Questa pagina''dovrebbe'', comunque, essere compatibile con loro.
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 non va in profondità su alcune questioni, ma vi rimanda ad altri documenti che lo fanno. A differenza di molti documenti Howto su RPM, questo documento illustra le specifiche per Fedora (con un sacco di link alle linee guida specifiche di Fedora) e tende ad essere più aggiornato (perché è mantenuto attraverso il wiki di Fedora).


Per esempio, mette in guardia dall' impatto dei [http://lists.autistici.org/message/20080709.212842.3f8877db.de.html cambiamenti che sono entrati in vigore dalla versione 4.4.2.x di RPM]. Nonostante la sua attenzione a Fedora, la maggior parte di questo documento ''si applica'' anche ad altre distribuzioni basate su RPM. Se siete impazienti, potreste iniziare con [[How_to_create_a_GNU_Hello_RPM_package]], che è un breve tutorial sulla creazione di un pacchetto RPM (ma non scende molto nel dettaglio come questa pagina fa).
'''Attualmente la Documentazione Fedora ha rilasciato una bozza di guida per i packager:  [http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide Packagers Guide]'''
Da notare che questa pagina ''NON'' mostra le '''linee guida''' ufficiali sulla creazione dei pacchetti per Fedora; a questo proposito, il [[Packaging:Committee| Packaging Committee]] gestisce le regole e le linee guida stesse per il packaging in Fedora. Quelle più importanti:


Se si prevede di creare un pacchetto RPM per il repository di Fedora, seguite il processo [[Join the package collection maintainers|Come diventare manutentori dei pacchetti Fedora Collection]], insieme alle varie linee guida di Fedora.
* [[Packaging:Guidelines| Packaging Guidelines]]
* [[Packaging:LicensingGuidelines |Licensing Guidelines]]
* [[Packaging:NamingGuidelines| Package Naming Guidelines]]
* [[Packaging:DistTag| Dist Tag Guidelines]]
* [[Packaging:ReviewGuidelines| Package Review Guidelines]]
* [[Packaging:ScriptletSnippets| Recipes for RPM post scripts]]
'''[[Packaging:Guidelines|Packaging Guidelines]] e [[Packaging:NamingGuidelines|Package Naming Guidelines]] sono le principali. Detto ciò, questa pagina dovrebbe 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]].


== Impostazione sistema ed account ==
== 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 '#' !)  
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
   # dnf install @development-tools
   # yum install fedora-packager
   # dnf install fedora-packager
  # dnf install rpmdevtools
    
    
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.
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 e non invierà file o chiavi private al mondo esterno.


{{admon/caution|Non si dovrebbero ''mai'' creare pacchetti come utente root.}}  
{{admon/caution|Non si dovrebbe MAI creare un pacchetto usando l'utente <code>root</code>. Farlo è pericoloso, poiché i file binari vengono installati nel sistema prima di essere impacchettati, quindi bisogna sempre operare come utente normale in modo da non inquinare accidentalmente il proprio sistema.}}  


E' possibile creare un nuovo utente chiamato semplicemente "makerpm", impostarne la password eseguendo:
Creare un nuovo utente chiamato semplicemente "makerpm", aggiungerlo al gruppo 'mock', impostarne la password eseguendo:
   # /usr/sbin/useradd makerpm
   # /usr/sbin/useradd makerpm
  # usermod -a -G mock makerpm
   # passwd makerpm
   # passwd makerpm
Poi loggarsi come utente speciale (makerpm).
Poi loggarsi come utente speciale (makerpm).
Line 31: Line 50:
   $ rpmdev-setuptree
   $ 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.<br>
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 <code>~/.rpmmacros</code>, usato per impostare opzioni aggiuntive.  
"rpm-setuptree" inoltre creerà un file ~/.rpmmacros che verrà usato da rpm e rpmbuild quando necessario.


[[Packaging:Guidelines#Timestamps|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.
[[Packaging:Guidelines#Timestamps|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 che nel file ~/.wgetrc sia presente il comando "timestamping = on", allo stesso modo se si usa curl, nel file ~/.curlrc dev'essere presente il testo "-R".
Se si usa wget assicurarsi di aggiungere il comando "<code>timestamping = on</code>" al file <code>~/.wgetrc</code>. allo stesso modo se si usa curl, nel file <code>~/.curlrc</code> dev'essere presente il testo <code>"-R"</code>.


Una volta fatto questi passaggi per la creazione dell'account, normalmente non sarà necessario rifarli ancora.
Una volta fatto questi passaggi per la creazione dell'account, normalmente non sarà necessario rifarli ancora.
Line 41: Line 59:
== Le basi della creazione di pacchetti RPM ==
== 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.
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 vostro 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:
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 deve passare alla directory "~/rpmbuild/SPECS" ed eseguire:
  rpmbuild -ba ''NAME''.spec
  $ 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 e le directory che ogni fase normalmente legge e scrive sono elencati di seguito):
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 <code>%</code> sono macro predefinite come descritto di seguito):


{|
Alcune directory hanno determinati funzioni per <code>rpmbuild</code> che possono essere sostituiti nel file <code>.spec</code> in base alle macro predefinite (iniziano per <code>%</code>):
! Fase !! Letture !! Scritture !! Azioni
 
Come si può vedere, alcune directory hanno scopi particolari per <code>rpmbuild</code>.  Queste sono:
{|border="1" cellspacing="0"
! Nome della Macro !! Nome !! Predefinito !! Funzione
|-
|-
|%prep||%_sourcedir||%_builddir||Legge i sorgenti e le patch nella directory %_sourcedir (di solito ~/rpmbuild/SOURCES). Questa fase scompatta il sorgente in una sotto-directory inferiore alla directory di build %_builddir (di solito ~/rpmbuild/BUILD/) e applica le patch.
|<code>%_specdir</code>||Specification directory||<code>~/rpmbuild/SPECS</code>||File SPEC degli RPM (.spec)
|-
|-
|%build||%_builddir||%_builddir||Compila i file nella directory sotto quella di build %_builddir (normalmente ~/rpmbuild/BUILD/). Di solito si possono implementare qui alcune variazioni di "./configure ; make".
|<code>%_sourcedir</code>||Source directory||<code>~/rpmbuild/SOURCES</code>||Pacchetto dei sorgenti incontaminati  (es: tarballs) e patch
|-
|-
|%check||%_builddir||%_builddir||Verifica che il software funziona propriamente.  Fase implementata per eseguire alcune variazioni di "make test".  Molti pacchetti non implementano questa fase.
|<code>%_builddir</code>||Build directory||<code>~/rpmbuild/BUILD</code>||I file sorgente vengono spacchettati e compilati nella sua subdirectory.
|-
|-
|%install||%_builddir||%_buildrootdir||Questa fase legge i file nella directory sotto quella di build %_builddir (normalmente ~/rpmbuild/BUILD/) e scrive in una directory sotto la root build directory %_buildrootdir (normalmente ~/rpmbuild/BUILDROOT).  I file che sono scritti è supposto che saranno installati quando il pacchetto dei binari viene installato dall'utente finale.  Attenzione alla strana terminologia: La directory ''build root''  '''not''' è la stessa della ''build directory''.  Questa fase è implementata da "make install".
|<code>%_buildrootdir</code>||Build root directory||<code>~/rpmbuild/BUILDROOT</code>||I file vengono installati qui durante la fase <code>%install</code>.
|-
|-
|bin||%_buildrootdir||%_rpmdir||Legge la directory sotto la  build root directory %_buildrootdir (normalmente ~/rpmbuild/BUILDROOT/) per creare un pacchetto RPM binario sotto la directory RPM %_rpmdir (normalmente ~/rpmbuild/RPMS/).  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.
|<code>%_rpmdir</code>||Binary RPM directory||<code>~/rpmbuild/RPMS</code>||Binari RPM sono creati e immagazzinati qui sotto.
|-
|-
|src||%_sourcedir||%_srcrpmdir||Questa crea un pacchetto sorgente RPM (.src.rpm) all'interno della directory RPM sorgente %_srcrpmdir (normalmente ~/rpmbuild/SRPMS).  Questi file sono necessari per una revisione e un aggiornamento del pacchetto.
|<code>%_srcrpmdir</code>||Source RPM directory||<code>~/rpmbuild/SRPMS</code>||Gli RPM sorgente sono creati e immagazzinati qui sotto.
|}
|}


<!-- Note: The words "in" and "underneath" in the table above have different meanings.  Given file /a/b/c, c is "underneath" but not "in" a. -->
Per creare i pacchetti binario e sorgente, dalla directory <code>~/rpmbuild/SPECS</code> avviare:
  $ rpmbuild -ba ''NAME''.spec
 
Quando invocato in questo modo <code>rpmbuild</code> legge il file <code>.spec</code> e segue le seguenti fasi di lavoro:


Come si può vedere, alcune directory hanno scopi particolari per rpmbuild.  Queste sono:
{|border="1" cellspacing="0"
{|
! Nome dela Macro !! Nome !! Predefinito !! Funzione
! Nome della Macro !! Nome !! Di solito !! Scopo
|-
|-
|%_specdir||directory della Specifica||~/rpmbuild/SPECS||file di specifica RPM (.spec)
|<code>%prep</code>||<code>%_sourcedir</code>||<code>%_builddir</code>||Legge i sorgenti e le patch nella directory <code>%_sourcedir</code>. Questa fase scompatta il sorgente in una sotto-directory inferiore alla directory di build <code>%_builddir</code> (di solito ~/rpmbuild/BUILD/) e applica le patch.
|-
|-
|%_sourcedir||directory Source||~/rpmbuild/SOURCES||Pacchetto dei sorgenti incontaminati  (es: tarballs) e patch
|<code>%prep</code>||<code>%_sourcedir</code>||<code>%_builddir</code>||Compila i file nella directory sotto quella di build <code>%_builddir</code>. Di solito si possono realizzare qui alcune variazioni di "<code>./configure && make</code>".
|-
|-
|%_builddir||Build directory||~/rpmbuild/BUILD||Source files are unpacked and compiled in a subdirectory underneath this.
|<code>%check</code>||<code>%_builddir</code>||<code>%_builddir</code>||Verifica che il software funziona propriamente.  Fase spesso realizzata per eseguire alcune variazioni di "<code>make test</code>".  Molti pacchetti non realizzano questa fase.
|-
|-
|%_buildrootdir||directory root di Build ||~/rpmbuild/BUILDROOT||I file vengono installati qui durante la fase %install.
|<code>%install</code>||<code>%_builddir</code>||<code>%_buildrootdir</code>||Questa fase legge i file nella directory sotto quella di build <code>%_builddir</code> e scrive in una directory sotto la root build directory <code>%_buildrootdir</code>.  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 è realizzata da "<code>make install</code>".
|-
|-
|%_rpmdir||directory dei binari RPM directory||~/rpmbuild/RPMS||Binari RPM sono creati e immagazzinati qui sotto.
|<code>bin</code>||<code>%_buildrootdir</code>||<code>%_rpmdir</code>||Legge la directory sotto la  build root directory <code>%_buildrootdir</code> per creare un pacchetto RPM binario sotto la directory RPM <code>%_rpmdir</code>.  All'interno della directory RPM vi è una directory per ogni architettura ed una denominata "<code>noarch</code>" per pacchetti che si possono applicare a molte architetture.  Questi file RPM sono i pacchetti che gli utenti andranno ad installare.
|-
|-
|%_srcrpmdir||directory dei Sorgenti RPM||~/rpmbuild/SRPMS||Il sorgente RPM sono creati e immagazzinati qui sotto.
|<code>src</code>||<code>%_sourcedir</code>||<code>%_srcrpmdir</code>||Questa crea un pacchetto sorgente RPM (<code>.src.rpm</code>) all'interno della directory RPM sorgente <code>%_srcrpmdir</code>.  Questi file sono necessari per una revisione e un aggiornamento del pacchetto.
|}
|}


Se una fase si interrompe prematuramente, è necessario guarda l'output per capire ''perch+'' è fallita, cambiare il file di .spec (o altri  file di input) a seconda delle necessità.
<!-- Note: The words "in" and "underneath" in the table above have different meanings.  Given file /a/b/c, c is "underneath" but not "in" a. -->
 
Se una fase si interrompe prematuramente, è necessario guardare l'output per capire ''perché'' è fallita, cambiare il file <code>.spec</code> (o altri  file di input) a seconda delle necessità.


== Prepararsi per pacchettizzare un programma in particolare ==
== Prepararsi per pacchettizzare un programma in particolare ==
Line 90: Line 117:
e prendere nota di cosa sono (queste informazioni serviranno).
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  
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.
patch e istruzioni di costruzione; ''non'' va bene cominciare con codice precompilato.
Salvare il file con il sorgente originale (solitamente un file <code>.tar.gz</code>) nella cartella "<code>~/rpmbuild/SOURCES</code>" (dell'utente costruttore di rpm).
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,  
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.
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
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).
(è 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.
Con qualche eccezione, tutti i programmi binari e le librerie incluse nei pacchetti Fedora devono essere costruiti dal codice sorgente contenuto nei pacchetti sorgente.


Line 107: Line 132:
=== Licenza ===
=== Licenza ===


Solo software che può essere pacchettizzato legalmente.
Usare solo software che può essere pacchettizzato legalmente.


Come scritto nella [[Packaging/Guidelines#Legal|sezione legal delle linee guida]], se si intende destinare i propri rpm ai repository Fedora,
Leggere [[Packaging:Guidelines#Legal]], [[Licensing:Main]] and [[Packaging:LicensingGuidelines]].
assicurarsi di rispettare le linee guida [[Licensing:Main]] e [[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).   
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).
Assicurarsi che il software sia realmente licenziato in questo modo (ad esempio controlli casuali del codice sorgente degli header, README file e così via).
Line 122: Line 146:
Inoltre controllare la [[PackageMaintainers/InProgressReviewRequests | In Progress Review Requests]] (per pacchetti in fase di revisione)
Inoltre controllare la [[PackageMaintainers/InProgressReviewRequests | In Progress Review Requests]] (per pacchetti in fase di revisione)
e la lista [[PackageMaintainers/RetiredPackages | Retired Packages]].
e la lista [[PackageMaintainers/RetiredPackages | Retired Packages]].
In caso, vedere se qualcuno non abbia già iniziato a pacchettizzare lo stesso software per Fedora.
Google con "NomeProgramma Fedora rpm" o qualcosa del genere ... forse può aiutare.
E' possibile usare  
E' possibile usare  
http://pkgs.fedoraproject.org/gitweb/
[http://pkgs.fedoraproject.org/cgit Fedora Packages Git Repositories]
per vedere direttamente gli .spec file (e patch) di qualsiasi pacchetto esistente in Fedora.
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:<br>
E' possibile scaricare gli RPM sorgenti usando il DNF download Plugin:<br>
'''Da notare''': Bisogna aver installato yum-utils prima di poter eseguire yumdownloader
  $ dnf download --source sourcepackage-name
$ yum -y install yum-utils
Poi:
  $ yumdownloader --source sourcepackage-name
In alternativa, un rpm sorgente può essere recuperato manualmente visitando la pagina web [http://mirrors.fedoraproject.org/publiclist Fedora mirror] http o ftp,
In alternativa, un rpm sorgente può essere recuperato manualmente visitando la pagina web [http://mirrors.fedoraproject.org/publiclist Fedora mirror] http o ftp,
selezionando la cartella <code>releases/{{FedoraVersion}}/Everything/source/SRPMS</code>.  
selezionando la cartella <code>releases/{{FedoraVersion}}/Everything/source/SRPMS</code>.  
Line 138: Line 157:
e scaricare l'rpm sorgente voluto (il nome termina con .src.rpm).
e scaricare l'rpm sorgente voluto (il nome termina con .src.rpm).


Ottenuto l'rpm sorgente, con il seguente comando se ne avvìa l'installazione:
Ottenuto l'rpm sorgente, installarlo in <code>~/rpmbuild</code>:
  $ rpm -ivh sourcepackage-name*.src.rpm
  $ rpm -ivh sourcepackage-name*.src.rpm
che piazza lo .spec file nella cartella ~/rpmbuild/SPECS ed altri sorgenti e patch in ~/rpmbuild/SOURCES.


E' possibile inoltre depacchettizzare il .src.rpm in una directory con rpm2cpio:
E' possibile inoltre depacchettizzare il .src.rpm in una directory con <code>rpm2cpio</code>:
  $ mkdir PROGRAMNAME_src_rpm
  $ mkdir PROGRAMNAME_src_rpm
  $ cd PROGRAMNAME_src_rpm
  $ cd PROGRAMNAME_src_rpm
Line 148: Line 166:


''Qualche volta'' è più facile iniziare con un pacchetto esistente, per poi ripulirlo per Fedora;
''Qualche volta'' è più facile iniziare con un pacchetto esistente, per poi ripulirlo per Fedora;
[http://rpmfind.net/ RPM Find] potrebbe aiutare a trovare RPM per sistemi non-Fedora
[http://rpmfind.net/ RPM Find] e [http://pkgs.org PKGS.org] potrebbero aiutare a trovare RPM per sistemi non-Fedora
(si possono installare rpm sorgenti di altri sistemi come in 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 [http://packages.ubuntu.com/ Ubuntu]
In caso, si potrebbe vedere per pacchetti sorgente (non pacchetti <code>.deb</code> binari) per [http://packages.ubuntu.com/ Ubuntu]
o [http://www.debian.org/distrib/packages Debian] (pacchetti sorgente sono degli standard tarball con una
o [http://www.debian.org/distrib/packages Debian] (pacchetti sorgente sono degli standard tarball con una
sottocartella ''debian/'', possibilmente associata con delle patch).
sottocartella ''<code>debian/</code>'', possibilmente associata con delle patch).
Se [http://www.freebsd.org/ports/installing.html FreeBSD ports collection] dovesse averlo,  
Se [http://www.freebsd.org/ports/installing.html FreeBSD ports collection] dovesse averlo,  
si potrebbe [ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz scaricare il FreeBSD ports tarball]  
si potrebbe [ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz scaricare il FreeBSD ports tarball]  
Line 161: Line 179:
== Creare un file spec ==
== Creare un file spec ==


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


=== Creare un file di spec vuoto ===
=== Modelli ed esempi di SPEC ===
==== Modelli ====


Quando crei uno spec file per la prima volta, è possibile usare la versione iniziale emacs o vim (dalla 7.1.270-1) che creano automaticamente un template per voi,
Quando si crea uno .spec file per la prima volta, è possibile usare editor come ''vim'' o ''emacs'' che creeranno automaticamente uno .spec iniziale:
ES.:
   $ cd ~/rpmbuild/SPECS
   $ cd ~/rpmbuild/SPECS
   $ vi program.spec
   $ vi program.spec


Di seguito un esempio di questo template:
Di seguito un esempio di questo template ('''Nota:''' il modello fornito sotto non necessariamente è conforme con le linee guida del Fedora Packaging):
  Name:
  Name:
  Version:
  Version:
Line 181: Line 199:
  URL:
  URL:
  Source0:
  Source0:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   
   
  BuildRequires:
  BuildRequires:
Line 189: Line 206:
   
   
  %prep
  %prep
  %setup -q
  %autosetup
   
   
  %build
  %build
Line 196: Line 213:
   
   
  %install
  %install
  rm -rf %{buildroot}
  %make_install
make install DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
   
   
  %files
  %files
%defattr(-,root,root,-)
  %doc
  %doc
%license
   
   
  %changelog
  %changelog




Puoi avere $RPM_BUILD_ROOT al posto di %{buildroot}; basta che sia consistente.
E' possibile usare <code>$RPM_BUILD_ROOT</code> al posto di <code>%{buildroot}</code>; basta che siano coerenti.


Puoi usare il comando <code>rpmdev-newspec</code> per creare un file di spec per te.  <code>rpmdev-newspec NOME-DEL-NUOVO-PACCHETTO</code> crea un file spec iniziale per un nuovo pacchetto, su misura per vari tipi di pacchetti.  Il programma individuerà il tipo di template da usare dal nome del pacchetto, o puoi specificare un particolare tipo di modello; controlla <code>/etc/rpmdevtools/spectemplate-*.spec</code> per consultare i template disponibili.  Controlla <code>rpmdev-newspec --help</code> per maggiori informazioni. Per esempio, per creare un nuovo file di spec per un modulo python:
E' possibile usare il comando <code>rpmdev-newspec</code> per creare un file di .spec .  <code>rpmdev-newspec NOME-DEL-NUOVO-PACCHETTO</code> 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 <code>/etc/rpmdevtools/spectemplate-*.spec</code> per consultare i modelli disponibili e <code>rpmdev-newspec --help</code> per maggiori informazioni. Per esempio, per creare un nuovo file di spec per un modulo python:


  cd ~/rpmbuild/SPECS
  cd ~/rpmbuild/SPECS
Line 217: Line 230:
  vi python-antigravity.spec
  vi python-antigravity.spec


=== Un esempio: eject ===
==== Esempi ====
===== eject =====
 
L'esempio di seguito mostra uno .spec per Fedora 16 per il programma <code>eject</code>:
 
<pre>
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
%autosetup -n %{name}
 
%build
%configure
make %{?_smp_mflags}
 
%install
%make_install
 
install -m 755 -d %{buildroot}/%{_sbindir}
ln -s ../bin/eject %{buildroot}/%{_sbindir}
 
%find_lang %{name}
 
%files -f %{name}.lang
%doc README TODO ChangeLog
%license COPYING
%{_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


Di seguito un esempio, un pacchetto per Fedora 9 per il programma "eject":
* Fri Jul 02 2010 Kamil Dudka <kdudka@redhat.com> 2.1.5-20
- handle multi-partition devices with spaces in mount points properly (#608502)
</pre>


Summary: A program that ejects removable media using software control
{{Anchor|Spec_file_pieces_explained}}
Name: eject
 
Version: 2.1.5
== Panoramica del file SPEC ==
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}-root
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 &lt;zprikryl at, redhat.com&gt; 2.1.5-11
- Added check if device is hotpluggable
- Resolves #438610


=== Spec file pieces explained ===
Altre utili guide:
* La [http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html Guida RPM] descrive nei dettagli come riempire uno spec file.
The [http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html RPM Guide, section on creating RPMs],
* La serie IBM "Packaging software with RPM" [http://www.ibm.com/developerworks/library/l-rpm1/ Parte 1], [http://www.ibm.com/developerworks/library/l-rpm2/ Parte 2] e [http://www.ibm.com/developerworks/library/l-rpm3 Parte 3] è altrettanto utile.
describes the details of how to fill in a spec file.
* [http://rpm.org/max-rpm-snapshot/ Maximum RPM] ha informazioni più complete ma è datata.
The developerWorks series "Packaging software with RPM" [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] is also handy.
[http://rpm.org/max-rpm-snapshot/ Maximum RPM] has the most complete information, but is dated.


You will need to follow the Fedora guidelines, such as the
Seguire la linee guida [[Packaging/NamingGuidelines| Package Naming Guidelines]], [[Packaging/Guidelines| Packaging Guidelines]] [[Packaging/ReviewGuidelines|Package review guidelines]].
[[Packaging/NamingGuidelines| Package Naming Guidelines]],
[[Packaging/Guidelines| Packaging Guidelines]], and
[[Packaging/ReviewGuidelines|Package review guidelines]].


You can insert comments with a leading "#" character, but
Si possono inserire commenti con il carattere "#", ma
don't insert potentially-multiline-macros (words beginning with "%") in a comment
non inserire le potentially-multiline-macros (parole che iniziano con "%") in un commento
(macros are expanded first); if you're commenting out a line, double the percent signs ("%%"). Also, don't use inline comments ("#") on the same line after
(le macro vengono espanse prima); se si decommenta una linea, raddoppiare il segno percentuale ("%%"). Inoltre, non usare "#" sulla stessa linea dopo un comando script.
a script command.


Here are the major fields/areas that you will need to fill in:
I principali tag sono listati di seguito. Notare che le macro <code>%{name}</code>, <code>%{version}</code> and <code>%{release}</code> possono essere usate come riferimanto a Nome, Versione e Release rispettivamente. Quando si cambia un tag, la macro automaticamente aggiorna al nuovo valore.
* Name: The (base) name of the package. It must follow the [[Packaging/NamingGuidelines| Package Naming Guidelines]].  In many cases, this will be in all lower case.  Elsewhere in the spec file, you can refer to the name using the macro %{name} - that way, if the name changes, the new name will be used by those other locations. This name should match the spec file name.
* '''Name''': Il nome del pacchetto, che dovrebbe coincidere con quello dello SPEC file. Deve seguire le [[Packaging/NamingGuidelines|Linee Guida]] e generalmente usa caratteri minuscoli.
* Version: The upstream version number. See [http://fedoraproject.org/wiki/Packaging/NamingGuidelines#Package_Version Packaging/Naming guidelines - package version] for more information. If the version is non-numeric (contains tags that are not numbers or digits), you may need to include the additional non-numeric characters in the release field. If upstream uses full dates to distinguish versions, consider using version numbers of the form yy.mm[dd] (so a 2008-05-01 release becomes 8.05). Elsewhere in the spec file, refer to this value as %{version}.
* '''Version''': Il numero di versione dall'upstream. Vedere la [[Packaging/NamingGuidelines#Version_Tag|Sezione Version tag]] delle linee guida sulla pacchettizzazione. 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 <code>yy.mm[dd]</code> (ad esempio <code>2008-05-01</code> diventa <code>8.05</code>).
* Release: The initial value of the release should normally be "1%{?dist}". Then, increment the number every time you release a new package for the same version of software.  If a new version of the software being packaged is released, the version number should be changed to reflect the new software version, and the release number should be reset to 1. See [http://fedoraproject.org/wiki/Packaging/NamingGuidelines#Package_Release Name Guidelines - package release] for more. [[Packaging/DistTag]] describes the "dist" tag, which isn't required but can be useful. Use %{release} to reuse this value.
* '''Release''': Il valore iniziale dovrebbe essere <code>1%{?dist}</code>. 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 <code>1</code>. Controllare la [[Packaging/NamingGuidelines#Release_Tag|sezione Release]] delle linee guida. L'opzionale [[Packaging/DistTag|Dist tag]] potrebbe essere utile.
* Summary: A brief, one-line summary of the package. Use American English, and ''do not'' end in a period.
* '''Summary''': Un breve sommario one-line del pacchetto. Usare l'inglese americano. '''NON finisce con una sola frase'''.
* Group: This needs to be a pre-existing group, like "Applications/Engineering"; run "less /usr/share/doc/rpm-*/GROUPS" to see the complete list. If you create a sub-package "...-doc" with documentation, use the group "Documentation".
* '''Group''': Necessita di un gruppo preesistente, come "Applications/Engineering"; avviare "<code>less /usr/share/doc/rpm/GROUPS</code>" per conoscere la lista completa. Usare il gruppo "Documentation" per qualsiasi sotto pacchetto (ad esempio <code>kernel-doc</code>) contenente documentazione. '''''Nota: Questo tag è disapprovato a partire da Fedora 17. Vedere [[http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide/chap-Packagers_Guide-Spec_File_Reference-Preamble.html| Introduzione di riferimento Spec File]] '''''
* License: Its license; for software, this must be an open source software license. Use a standard abbreviation, e.g., "GPLv2+".  Try to be specific, e.g., use "GPLv2+" (GPL version 2 or greater) instead of just "GPL" or "GPLv2" where it's true. See [[Licensing]] and the [[Packaging/LicensingGuidelines| Licensing Guidelines]] for more information. You can list multiple licenses by combining them with "and" and "or", e.g., "GPLv2 and BSD".  Call this tag "License"; don't use the older, inaccurately named tag "Copyright".
* '''License''': La licenza che deve essere open source. ''Non'' usare vecchi tag Copyright. Usare abbreviazioni standard ("<code>GPLv2+</code>") e specifiche (usare "<code>GPLv2+</code>" per la GPL versione 2 o successive invece del solo "<code>GPL</code>" oppure "<code>GPLv2</code>"). Vedere [[Licensing]] e le [[Packaging/LicensingGuidelines|Licensing Guidelines]]. E' possibile listare più licenze combinandole con "<code>and</code>" e "<code>or</code>" (ad esempio "<code>GPLv2 and BSD</code>").
* URL: The URL for more information about the program, e.g., the project websiteNote: This is NOT where the original source code came from, see "Source" (next!).
* '''URL''': L'intero URL per avere maggiori informazioni sul programma (ad esempio il sito del progetto)'''''Nota: Non è un collegamento al codice sorgente originale che invece appare al tag Source0'''''.
* Source0: The URL for the compressed archive containing (original) pristine source code, as upstream released it. "Source" is synonymous with "Source0". If you give a full URL (and you should), its basename will be used when looking in the SOURCES directory. If possible, embed %{name} and %{version}, so that changes to either will go to the right place. '''Warning:''' ''Source0:'' and ''URL:'' are different - normally they are both URLs, but the "URL:" entry points to the project website, while the "Source0:" entry points to the actual file containing the source code (and is typically a .tar.gz file). As noted in the guidelines, "When downloading sources, patches etc, consider using a client that preserves the upstream timestamps. For example wget -N or curl -R. To make the change global for wget, add this to your ~/.wgetrc: timestamping = on, and for curl, add to your ~/.curlrc: -R."  If there is more than one source, name them Source1, Source2, and so on. If you're adding whole new files in addition to the pristine sources, you can list each of them as sources as well, but list them ''after'' the pristine sources. A copy of each of these sources will be included in any source package you create (unless you specially direct otherwise). See [[Packaging/SourceURL]] for more information on special cases (using revision control, when upstream uses prohibited code, etc.).
* '''Source0''': L'intero URL all'archivio compresso contenente il codice sorgente originale, come rilasciato dall'upstream. "<code>Source</code>" è sinonimo di "<code>Source0</code>". Se si fornisce l'URL completo (come dovrebbe essere), il suo nome verrà utilizzato nella cartella <code>SOURCES</code>. Se possibile, incorporare <code>%{name}</code> e <code>%{version}</code>, così che le modifiche possano andare al posto giusto. [[Packaging:Guidelines#Timestamps|Preservare il timestamps]] quando si scaricano i file sorgente. Se esistono più sorgenti, nominarli <code>Source1</code>, <code>Source2</code> 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 [[Packaging/SourceURL|Source URL]] per maggiori informazioni su casi speciali (ad esempio sulla revisione).
* Patch0: The name of the first patch that you will apply to the source code. If you need to patch the files after they've been uncompressed, you should edit the files, save their differences as a "patch" file in your ~/rpmbuild/SOURCES directory. Patches should make only one logical change, so it's quite possible to have multiple patch files.
* '''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 "file .patch" nella cartella <code>~/rpmbuild/SOURCES</code>. Le Patch dovrebbero fare una modifica alla volta, quindi è possibile avere più file .patch .
* BuildArch: If you're packaging files that are architecture-independent (e.g., shell scripts, data files, etc.), then add "BuildArch: noarch". The architecture for the binary RPM will then be "noarch".
* '''BuildArch''': Se i file da pacchettizzare sono indipendenti dall'architettura (ad esempio shell script, file data), allora aggiungere "<code>BuildArch: noarch</code>". L'architettura per gli RPM binari sarà "<code>noarch</code>".
* BuildRoot: This is where files will be "installed" during the "%install" process (which happens after the %build compilation process). Normally you should just leave this line alone; under the usual Fedora setup, this will be a macro that will create a new special directory under /var/tmp. Newer versions of RPM will ignore this value, and instead place the build root in "%{_topdir}/BUILDROOT/".
* '''BuildRoot''': La cartella "d'installazione" durante il processo %install (dopo %build). E'aggiuntivo in Fedora mentre è necessario in EPEL5. Normalmente la root build è in "<code>%{_topdir}/BUILDROOT/</code>".
* BuildRequires: A comma-separated list of packages required for building (compiling) the program. These are ''not'' automatically determined, so you need to include ''everything'' needed to build the program. There are a few packages that are so common in builds that you don't need to mention them, such as "gcc"; see the [[Packaging/Guidelines| Packaging Guidelines]] for the complete list of the packages you may omit. You can also specify minimum versions, if necessary, like this: "ocaml >= 3.08". You can have more than one line of BuildRequires (in which case they are all required for building). If you need file /EGGS, you can get its package by running "rpm -qf /EGGS"; if EGGS is a program, you determine its package quickly by running "rpm -qf `which EGGS`". Try to specify only the minimal set of packages necessary to properly build the package, since each one will slow down a "mock"-based build (e.g., try to use sed instead of perl if you don't really need perl's abilities).  Watch out: Some applications permanently disable functions if their package isn't detected during the build; in those cases you may need to include those additional packages. If you have trouble figuring out this list, the "auto-br-rpmbuild" command (from the auto-buildrequires package) may be helpful.
* '''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. [[HOWTOFindMissingBuildRequires#Exceptions|Alcuni pacchetti comuni possono essere omessi]], come <code>gcc</code>. E' possibile specificarle in minima parte se necessario (ad esempio "<code>ocaml >= 3.08</code>"). Se serve il file <code>/EGGS</code>, determinarne il pacchetto che lo possiede con "<code>rpm -qf /EGGS</code>". Se serve il programma <code>EGGS</code>, determinarne il pacchetto che lo possiede con "<code>rpm -qf `which EGGS`</code>". Mantenere le dipendenze ad un numero minimo (ad esempio usare <code>sed</code> invece di <code>perl</code> 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 pacchetto {{package|auto-buildrequires}} può essere utile.
* Requires: A comma-separate list of packages that are required when the program is installed.  Note that the list of packages for ''Requires'' (what's required when installing/running) and ''BuildRequires'' (what's required to build the binary RPM) are independent; a package may be in one list but not the other, or it could be in both. The dependencies of binary packages are in many cases automatically detected by rpmbuild, so it is often the case that you don't need to specify the ''Requires'' tag at all. But if you want to highlight some specific packages as being required, or require a package that rpm can't detect should be required, then add it here.
* '''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 <code>rpmbuild</code> recupera automaticamente le dipendenze quindi il Requires tag non è sempre utile. Tuttavia è possibile evidenziare pacchetti specifici richiesti.
* %description - A longer, multi-line description of the program. Use American English. All lines must be 80 characters or less. "Blank lines are assumed to separate paragraphs. Some graphical user interface installation programs will reformat paragraphs...  (lines that) start with whitespace, such as a space or tab, will be treated as preformatted text and displayed as is, normally with a fixed-width font." (per the [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch09s03.html RPM Guide]).
* '''%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 [http://docs.fedoraproject.org/drafts/rpm-guide-en/ch09s03.html Guida RPM].
* %prep - Script commands to "prepare" the program, that is, to uncompress it so that it will be ready for building (compiling). Typically this is just "%setup -q" or some variation of it; a common variation is "%setup -q -n NAME" if the source file unpacks into NAME. See the "%prep" section below for more.
* '''%prep''': Comandi script per "preparare" il programma (ad esempio decomprimere) così che tutto sia pronto per la compilazione. Tipcamente "<code>%autosetup</code>"; una comune variante è "<code>%autosetup -n NAME</code>" se il file sorgente spacchetta in <code>NAME</code>. Vedere la sezione %prep.
* %build - Script commands to "build" the program, that is, to compile it and get it ready for installing. The program should come with instructions on how to do this. See the "%build" section below for more.
* '''%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 - Script commands to self-test the program. This is run after %build and before %install, so you should place it there if you have this section. Often it simply contains "make test" or "make check". This is separated from %build so that people can skip the self-test if they desire.  This isn't documented in many places.
* '''%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 "<code>make test</code>" oppure "<code>make check</code>". E' separato da %build così da poter essere saltato a discrezione dell'utente.
* %install - Script commands to "install" the programThe commands should copy the files from the "build directory" %{_builddir} (which would be under ~/rpmbuild/BUILD) into the buildroot directory, %{buildroot} (which would normally be under /var/tmp). See the "%install" section below for more.
* '''%install''': Comandi script per "installare" il programma. I comandi dovrebbero copiare file dalla cartella <code>BUILD</code> <code>%{_builddir}</code> nella buildroot <code>%{buildroot}</code>. Vedere la sezione %install.
* %clean - instructions to clean out the build root. Typically:
* '''%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}
  rm -rf %{buildroot} # ridondante eccetto per RHEL 5
* %files - the list of files that will be installed.   See the "%files" section below for more.
* '''%files''': Lista di file che saranno installati. Vedere la sezione %files.
* %changelog - Changes in the package. Use the format example above.
* '''%changelog''': Modifiche nel pacchetto. Usare l'esempio sopra. '''NON inserire il changelog storico del software. Questo riguarda solo quello dell'RPM stesso.'''
* ExcludeArch: If the package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in an ExcludeArch tag.
* '''ExcludeArch''': Se il pacchetto non compila, costruisce o funziona correttamente in una particolare architettura, listare le architetture coinvolte sotto questo tag.
* You can add sections so that code will run when packages are installed or removed on the real system (as opposed to just running the %install script, which only does a pseudo-install to the build root). These are called "scriptlets", and they are usually used to update the running system with information from the package. See the "Scriptlets" section below for more.
* 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".


Don't use the tags "Packager" or "Vendor".  Don't use "Copyright" - use "License" instead.
RPM inoltre supporta la creazione di diversi pacchetti (detti [[How_to_create_an_RPM_package#Subpackages|subpackage]]) da un singolo SPEC file, come <code>name-libs</code> e <code>name-devel</code>.
Don't create a "relocatable" package - they don't add value in Fedora yet they make things more complicated.


RPM supports subpackages, that is, a single spec file can generate many
{{admon/caution|'''NON''' usare questi tag:
binary packages.  For example, if the documentation is very large, you might generate
* Packager
a separate "-doc" subpackage.
* Vendor
See below for more.
* Copyright}}


=== %prep section ===
'''Non''' creare un pacchetto "ricollocabile"; non valgono in Fedora e sono complicati.
The "%prep" section describes how to unpack the compressed packages so that they can be built.
Typically, this is a set of "%setup" and/or %patch commands, which reference the Source0:, Source1:, etc. lines above.
See the [http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html Maximum RPM section on %setup and %patch] for more details.


'''Warning:''' In spec files, don't use in-line comments (a "#" comment on the same line after a command), and don't put macros (words beginning with "%") in a comment unless you quote the "%" as "%%". Macros can cause failures if they are in a comment, because they are always expanded (even when in a comment) and they can expand to multiple lines. This is true for %prep, %build, and so on.
== Approfondimento sezioni SPEC file ==
=== Sezione %prep ===
La sezione "%prep" descrive come spacchettare gli archivi compressi così da poter iniziare la compilazione.
Di solito include i comandi "%autosetup"; in alternativa di usano i comandi "%setup" e/o "%patch" con riferimenti alle linee Source0:, Source1:, etc.
Vedere la [http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html sezione su %setup e %patch in Maximum RPM] per maggiori dettagli.


The new RPM 4.4.2.x series adds two new macros, %{patches} and %{sources}, so you can do things like:
Le macro %{patches} e %{sources} sono disponibili da RPM 4.4.2; se si usa una lunga lista di patch o sorgenti ed %autosetup non è vi è utile, è possibile fare qualcosa del genere:
  for p in %{patches}; do
  for p in %{patches}; do
...
    ...
  done
  done
These new macros can be very useful if you have a large list of patches or sources.
However, keep in mind that using these will make your spec
incompatible with the rpm used in Fedora 9 and earlier, RHEL, and
many other RPM-based distros.


==== %prep section: %setup command ====
Tuttavia tener presente che usandole si otterranno .spec file incompatibli con RPM usati in RHEL ed altre distro  basate su RPM.


The "%setup" command unpacks a source package, and takes several switches.  Normally you should use "-q" (quiet) to prevent setup from babbling about every file it unpacks.  Here are a few switches besides -q:
==== Sezione %prep: comando %autosetup ====
* -n ''name'': If the name of the rpm is something other than what the Source unpacks to, use this switch to state the ''name'' it unpacks to.  E.G., if the tarball unpacks into a directory MYNAME, use %setup -q -n MYNAME
* -c ''name'': If the tarball doesn't unpack into a single directory, this creates a directory named ''name'' and then unpacks into it.  Useful if you have one of those annoying tarballs that doesn't have a single common subdirectory embedded in it.


There are
Il comando "<code>%autosetup</code>" spacchetta i sorgente.
[http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html more %spec options if you are unpacking multiple files], which is primarily useful if you
* '''<code>-n</code> ''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 il file .tar decomprime nella cartella FOO, allora usare "<code>%autosetup -n FOO</code>".
are creating subpackages (see below).  The key ones are:
* '''<code>-c</code> ''name''''' : Se il tarball Source in più cartelle invece di una singola, l'opzione può essere usata per crearne una chiamata ''name''.
 
Se si usa il comando "<code>%setup</code>" invece, allora l'opzione ''<code>-q</code>'' è comunemente usata per sopprimere gli output non necessari.
 
Ci sono [http://rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html più opzioni %setup], utili principalmente se si stanno creando sottopacchetti.
Quelle principali sono:


{|
{|
|-
|-
| -a number || Only unpack the source directive of the given number, such as –a 0 for source0:, after changing to the directory.
| <code>-a number</code> || Decomprime il Source dato dal numero indicato dopo aver cambiato cartella (ad esempio "<code>–a 0</code>" per Source0).
|-
|-
| -b number ||  Only unpack the source directive of the given number, such as –b 0 for source0:, before changing to the directory.
| <code>-b number</code> ||  Decomprime il Source dato dal numero indicato prima aver cambiato cartella (ad esempio "<code>–a 0</code>" per Source0).
|-
|-
| -D || Do not delete the directory before unpacking.
| <code>-D</code> || Non cancella la cartella dopo la decompressione.
|-
|-
| -T || Disable the automatic unpacking of the archives.
| <code>-T</code> || Disabilita la decompressione automatica dell'archivio.
|}
|}


==== %prep section: %patch commands ====
==== Sezione %prep: comando %patch ====


The "%patch0" command applies patch 0 (similar for 1, 2, etc.).  Patches are the normal way to change to the source code if necessary to package it. The normal "-pNUMBER" option applies, which simply passes that argument on to ''patch''.
Se è stato usato il comando "<code>%autosetup</code>", le nozioni sotto indicate non servono.  
Se si hanno necessità più complesse o di compatibilità con EPEL, allora possono servire.


Patch file names often look like "telnet-0.17-env.patch", that is, ''%{name}''-''%{version}''-''patch_purpose''.patch (some people omit -''%{version}''). Patch files are typically the result of a "diff -u"; if you do this from the subdirectory of ~/rpmbuild/BUILD, you won't have to specify a -p level later.  You can use all the normal ways of creating a patch file.
Il comando "<code>%patch0</code>" 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 "<code>-pNUMBER</code>" che passa l'argomento al programma <code>patch</code>.


If you're creating a patch file a single file FILENAME, a common way is to copy it to FILENAME.orig, modify it, and then save the results of "diff -u FILENAME.orig FILENAME". If you change directory to "~/rpmbuild/BUILD/''NAME''", you could create a patch file to change a single file by doing:
I file Patch sono nominati spesso come "<code>telnet-0.17-env.patch</code>", nel formato <code>%{name} - %{version} - REASON.patch</code>" (a volte la versione è omessa). I file Patch sono il risultato di "<code>diff -u</code>"; se si fa dalla subdirectory di <code>~/rpmbuild/BUILD</code> allora non è necessario specificare un livello <code>-p</code>.
cp X/Y.Z X/Y.Z.orig
vim X/Y.Z
diff -u X/Y.Z.orig X/Y.Z > ~/rpmbuild/SOURCES/PKGNAME.REASON.patch


If you're going to edit many files, one easy method is to copy the whole subdirectory underneath BUILD, and then do subdirectory diffs; once you change directory to "~rpmbuild/BUILD/''NAME''", you can:
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 <code>BUILD</code> per poi avviare il <code>diff</code>. Dopo aver cambiato cartella a "<code>~rpmbuild/BUILD/NAME</code>", allora:
  cp -pr ./ ../PACKAGENAME.orig/
  cp -pr ./ ../PACKAGENAME.orig/
  ... many edits ...
  ... modifiche ...
  diff -u ../PACKAGENAME.orig . > ~/rpmbuild/SOURCES/''NAME''.''REASON''.patch
  diff -u ../PACKAGENAME.orig . > ~/rpmbuild/SOURCES/''NAME''.''REASON''.patch


If you edit many files in one patch, you can also copy the original files using some consistent ending such as ".orig" before editing them. Then, you can use "gendiff" (in the rpm package) to create a patch with the differences.  Do "man gendiff" for more information.
Se si modificano più file in una sola patch, è possibile anche copiare quelli originali usando alcune desinenze come "<code>.orig</code>" prima di modificarle. Per poi usare "<code>gendiff</code>" (nel pacchetto <code>rpm-build</code>) per creare una patch con le modifiche.


Try to ensure that in your patch the "context" matches exactly.
Assicurarsi che le patch corrispondano correttamente al contesto. Il valore predefinito "fuzz" è "<code>0</code>". Ci si può lavorare aggiungendo "<code>%global _default_patch_fuzz 2</code>" per ripristinare il valore trovato nelle vecchie versioni dell'RPM in Fedora, ma generalmente è raccomandato evitarlo.
In old versions of Fedora, the default "fuzz" value was 2, which meant that imprecise matches were acceptable.
However, the version of [http://lwn.net/Articles/289235/ RPM used by Fedora 10 and later] have a default fuzz to 0, requiring that matches be exact.
You can work around this by adding "%global _default_patch_fuzz 2", but it's better to not
have the problem by making the patch match the context exactly.


As explained in [[Packaging/PatchUpstreamStatus]], all patches in Fedora spec files SHOULD have a comment above them about their upstream status.  This should document the upstream bug/email that includes it (including the date), or if it's Fedora-unique, why it is unique.
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]].
The Fedora Project focuses, as much as possible, on not deviating from upstream in the software it includes in the repository - see [[PackageMaintainers/WhyUpstream|Staying close to upstream projects]] for more about why it's important to do this.


==== %prep section: Unmodified files ====
==== Sezione %prep: file non modificati ====


Sometimes, you'll package just a straight file that doesn't need to be uncompressed, e.g., a "Source1:" that is just a simple PDF file.  These might not be from external sources, e.g., perhaps you've had to create a few additional files that weren't in the original sources so that the package cleanly installs in Fedora. You can "prep" those into the build directory by doing this (replace "1" with whatever number it is):
A volte uno o più file del Source non necessitano d'essere decompressi. Si possono "prep" (prepararli) nella cartella build come (dove <code>SOURCE1</code> si riferisce al corrispondente file Source):
  cp -p %SOURCE1 .
cp -p %SOURCE1 .


=== %build section ===
=== Sezione %build ===


The "%build" section is sometimes complicated; here you configure and compile/build the files to be installed.
La sezione "%build" è qualche volta complicata; in essa si può configurare e compilare/costruire i file che saranno installati.


Many programs follow the GNU configure approach (or some variation). By default, they will install to a prefix of "/usr/local" (/usr/local/bin, /usr/local/lib, etc.), which is a reasonable default for unpackaged files.  However, since you ''are'' packaging it, you will want to change the prefix to "/usr", since this is now a package maintained by the system itself. If there are any libraries, they'll need to be installed in the right directory, which is either /usr/lib or /usr/lib64 depending on the architecture (the actual value is in %{_libdir}).
Molti programmi seguono la GNU <code>configure</code> (o alcune varianti). Come predefinito, installeranno in un prefix "<code>/usr/local</code>", ragionevolmente per dei file spacchettati. Tuttavia una volta impacchettati, cambia in "<code>/usr</code>". Le librerie dovrebbero essere installate o in <code>/usr/lib</code> oppure in <code>/usr/lib64</code> in base all'architettura.


Since the GNU "configure" system is so common, rpm pre-defines a macro named "%configure", which invokes GNU configure with the right options (e.g., it changes --prefix to /usr). This means that some variation of this will often work as a build command:
Dal momento che GNU <code>configure</code> è così comune, la macro "<code>%configure</code>" può essere usata per invocare automaticamente le corrette opzioni (ad esempio cambiare il prefix a <code>/usr</code>). Alcune sue varianti funzionano spesso:
   %configure
   %configure
   make %{?_smp_mflags}
   make %{?_smp_mflags}


Sometimes you'll want to override the variables of a makefile; you can easily do that by passing them as parameters to make, like this:
Per sostituire le variabili del makefile, passarle come parametro a <code>make</code>:
  make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}
  make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}


If you need to do something complicated with GNU-generated configure, take a look at [http://sourceware.org/autobook/ "GNU autoconf, automake, and libtool"].  A good presentation on these as well as "make" is [http://www.suse.de/~sh/automake/automake.pdf "Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer].
Per maggiori informazioni vedere [http://sourceware.org/autobook/ "GNU autoconf, automake, and libtool"].


Some programs use Cmake. See [[Packaging/cmake]] for some suggestions.
Alcuni programmi usano <code>cmake</code>. Vedi [[Packaging/cmake]].


If you include some self-tests (and that's a good idea), put them in a separate "%check" section that immediately follows the "%build" area, instead of including them in %build.  That way, it will be easy for the system to skip unnecessary self-tests.
=== Sezione %check ===


=== %check section ===
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.


The "%check" section does testing, often it's "make test".
Spesso questa sezione contiene:
This is not documented in many other sources of RPM info.
make test


=== %install section ===
A volte può essere:
make check


The "%install" section is a set of script commands to "install" the program. The commands in this section should copy the files from a directory inside the "build directory" %{_builddir} (normally ~/rpmbuild/BUILD/''something'') into the build root directory, %{buildroot} (normally /var/tmp/''something''), creating the directories inside %{buildroot} as necessary.
Osservare il file Makefile per sapere il modo più appropriato.


'''Watch out''': Some of the terminology is very misleading:
=== Sezione %install ===
* The ''build directory'' (under which compilations occur during %build) and the ''build root'' (where files are copied into during the %install process) are '''different'''.  The point of the %install process is to copy files, such as those under the build directory, to the right place in the build root. Perhaps "buildroot" should be called "installroot", but it's too late now, the terminology is entrenched.
* The build directory is normally ~/rpmbuild/BUILD, while the build root (where files get installed to during %install) is normally ~/rpmbuild/BUILDROOT.  The %prep stage will normally create a subdirectory underneath the build directory as part of %setup, and populate the build directory with files (based on the source information in %_sourcedir, which is typically in ~/rpmbuild/SOURCES).  During %build, the current directory will actually start at %{buildsubdir}, that newly-created  subdirectory under the build directory.  Typically %{buildsubdir} is something like ~/rpmbuild/BUILD/%{name}-%{version}.
* The "%install" script is ''not'' used when the binary rpm package is installed by the end-user!! The term "%install" is misleading, in fact, the script must ''not'' install the programs in the REAL final locations (e.g., in /usr/bin), but under the buildroot %{buildroot}.


Normally, the install script would first erase the %{buildroot} directory, and then do some variation of "make install" (ideally using DESTDIR=%{buildroot}, if the program supports it). Here's an example of an %install section:
Questa sezione coinvolge degli script  per "install" (installare) il programma, copiando i file rilevanti da <code>%{_builddir}</code> a <code>%{buildroot}</code> (che solitamente significa da <code>~/rpmbuild/BUILD</code> a <code>~/rpmbuild/BUILDROOT</code>) e creando e cartelle all'interno di <code>%{buildroot}</code>.
 
Parte della terminologìa può essere fuorviante:
* La "build directory", anche conosciuta come <code>%{_builddir}</code>, non è la stessa della "build root", conosciuta anche come <code>%{buildroot}</code>. La compilazione avviene nella prima, mentre i file da impacchettare sono copiati dalla prima alla seconda.
* Durante la sezione %build, la cartella di partenza è <code>%{buildsubdir}</code>, sottocartella all'interno di <code>%{_builddir}</code>, creata precedentemente durante il %prep. Di solito è qualcosa del genere <code>~/rpmbuild/BUILD/%{name}-%{version}</code>.
* La sezione %install '''non''' parte quando l'RPM binario è installato dall'utente finale, ma è avviata solo nella creazione del pacchetto.
 
Alcune varianti di "<code>make install</code>":
  %install
  %install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install


Ideally, every program would have a "make install" command that supported the [http://www.gnu.org/prep/standards/html_node/DESTDIR.html ''DESTDIR'' convention].  If the program includes a "make install" that supports DESTDIR, where possible, ''use it''. The DESTDIR convention supports redirecting file installations to descend from a specific directory, which is exactly what we want during %install.
rm -rf %{buildroot} # ridondante ad eccezione di RHEL5
%make_install
 
 
Idealmente si dovrebbe usare [http://www.gnu.org/prep/standards/html_node/DESTDIR.html <code>DESTDIR=%{buildroot}</code>] 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.


Installing a program that does not support DESTDIR can be much harder, and no option is as good as native DESTDIR support.  Consider these alternatives:
Se il programma non supporta <code>DESTDIR</code> (e solo se), è possibile in alternativa una delle seguenti strade:
* Patch the makefile so that it ''does'' support DESTDIR. Create directories inside DESTDIR where necessary (feel free to use "mkdir -p", the "-p" option of mkdir is now standard and widely supported).  Be sure to submit the patch upstream.
* ''Patchare'' il makefile così che possa supportare <code>DESTDIR</code>. Creare cartelle all'interno di <code>DESTDIR</code> dove necessario e includerne la patch dall' upstream.
* Use "%makeinstall". Many older RPM documents suggest using "%makeinstall", which ''might'' work if "make install" doesn't support DESTDIR. However, as noted in the Fedora guidelines, the %makeinstall macro "must NOT be used when make install DESTDIR=%{buildroot} works. %makeinstall is (merely) a kludge that can work with Makefiles that don't make use of the DESTDIR variable...".  Unfortunately, this sometimes has subtle failures, which is why %makeinstall should not be used if DESTDIR works.  The reason is based on how %makeinstall works.  The "%makeinstall" macro expands to something like "<tt>make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install</tt>".  Many programs will quietly recompile or change parts of the program when values like prefix are changed, resulting in an incorrect installation. See the Fedora guidelines if you want the details on why this approach can fail.  You will probably need to create appropriate directories inside %buildroot before calling %makeinstall (e.g., <tt>mkdir -p %{buildroot}%{_bindir}/</tt>).
* Usare la macro "<code>%makeinstall</code>". Questo metodo potrebbe funzionare, ma può portare a fallimenti. Tramite la macro si arriva a qualcosa del genere "<code>make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install</code>", che in alcuni programmi pu non funzionare. Creare cartelle all'interno di <code>%{buildroot}</code> dove serve.
* Consider using the auto-destdir package. This requires "BuildRequires: auto-destdir", and changing "make install" to "make-redir DESTDIR=%{buildroot} install". This only works well if the installation uses only certain common commands to install files, like cp and install; see "man make-redir" for details.
* Considerare l'uso del pacchetto <code>auto-destdir</code>. Richiede "<code>BuildRequires: auto-destdir</code>" and di cambiare "<code>make install</code>" in "<code>make-redir DESTDIR=%{buildroot} install</code>". Funziona bene se l'installazione usa solo certi comandi comuni per installare i file, come <code>cp</code> e <code>install</code>.
* Do the installation "by hand", that is, instead of invoking a build system, copy the files to the correct locations. Basically, this would be a sequence that would create directories that weren't already created by the "BuildRequires" packages (typically using install -d or mkdir -p), followed by copying of files from the current directory (inside the build directory) into the buildroot directory (typically using "cp -p" and/or "install -p"). Running "make -n install" may make it easy to determine what this sequence should be.  Be sure to create directories inside %buildroot where necessary.  One serious problem with this approach is that it's easy to fail to install new or renamed files during an update&mdash;so if there's a better approach, use it instead. If you ''do'' perform the installation "by hand", be ''especially'' careful with updates when using this approach. For example:
* Installare manualmente. Dovrbbe includere la creazione delle necessarie cartelle sotto <code>%{buildroot}</code> e la copia dei file da <code>%{_builddir}</code> a <code>%{buildroot}</code>. Bisogna essere cauti con gli aggiornamenti, contengono spesso nuovi filename. Un esempio di questa procedura:
  %install
  %install
  rm -rf %{buildroot}
  rm -rf %{buildroot}
Line 471: Line 465:
  cp -p mycommand %{buildroot}%{_bindir}/
  cp -p mycommand %{buildroot}%{_bindir}/


As noted in the [[Packaging:Guidelines#Timestamps|packaging guidelines' timestamp section]],  "when adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, eg. cp -p or install -p".  So, if the makefile lets you override the install command (typically named INSTALL), you might want something like INSTALL="install -p" CP="cp -p" as make parameters, like this:
=== Sezione %files ===
make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install
Questa sezione dichiara i file e le cartelle proprietà del pacchetto quindi incorporati nell'RPM binario.


=== %files section ===
==== Nozioni sulla sezione %files ====
The %files section identifies what files and directories were added by the package - and thus, which files and directories are ''owned'' by the package.  Ownership is important - when you type "rpm -qif ''blah''",  you'll see who owns ''blah''.  This section is used when performing the ''bin'' stage, to determine which files are placed into each binary RPM file.


==== %files Basics ====
Il <code>%defattr</code> imposta i permessi predefiniti del file e spesso appare all'inizio della sezione <code>%files</code>. 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 <code>%defattr(-,root,root,-)</code>, dove "<code>-</code>" usa i permessi predefiniti.


The %files section normally begins with a %defattr line which sets the default file permissions. The format of this is %defattr(<file permissions>, <user>, <group>, <directory permissions>), that is, one can specify the permissions to apply to files and directories in the %files section. The fourth parameter is often omitted. Usually one uses %defattr(-,root,root,-), where "-" means "use the default permissions".
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 <code>%{_bindir}/mycommand</code> invece di <code>/usr/bin/mycommand</code>). Se la stringa inizia con "<code>/</code>" (o quando esteso da una macro) allora viene prelevato dalla cartella <code>%{buildroot}</code>. Oppure, si presume che il file sia nella cartella corrente (ad esempio dentro <code>%{_builddir}</code> come per i file di documentazione da includere). Se il pacchetto installa un solo file <code>/usr/sbin/mycommand</code>, la sezione <code>%files</code> può semplicemente essere:
 
This is followed by names or patterns of the directories or files to be installed and owned by this package. You should use macros for directory names, e.g., use %{_bindir}/myfile instead of /usr/bin/myfile, and %{_sbindir}/killaccount instead of /usr/sbin/killaccount. If a name or pattern begins with "/" when expanded, then it is presumed to have been copied into the %{buildroot} followed by that pattern; when installed on the final system, it will be copied into that name ''without'' the buildroot prefix. If you don't precede the pattern with "/", then it is presumed to be in the current directory (e.g., inside the build directory) - this is used for "documentation" files. So if your package just installs /usr/sbin/mycommand, then your %files section ''could'' simply say:
  %files
  %files
%defattr(-,root,root,-)
  %{_sbindir}/mycommand
  %{_sbindir}/mycommand


Any file or directory identified in the %files section is ''owned'' by the defining package. You should make sure that you declare ownership of every new file or directory the package creates.  You can use wildcards (*) which match a set of files - this makes the package less sensitive to changes. For example, you can declare that all the files that were copied into %{buildroot}/usr/bin are owned by this package by declaring:
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}/*
  %{_bindir}/*


Note that "%{_bindir}/*" does not claim that this package owns the /usr/bin directory - it claims that all the files that were installed inside the ''build root'' 's /usr/bin are owned by the package.
Per includere una singola cartella:
If you list a ''directory'' in the %files section, then you are claiming that this package owns that subdirectory and all files and directories in it, recursively (''all'' the way down) if they are present in the build root.  Do not list the "/usr/bin" or "%{_bindir}" directories directly in your %files list, because that would claim ownership of /usr/bin and everything inside it.  Claiming ownership of "%{_bindir}/*" is fine, though; that just claims ownership of the subdirectories and files you placed ''under'' %{buildroot}/%{_bindir}.  If you create a subdirectory such as %{_datadir}/%{name}, (/usr/share/NAME), you ''should'' include that directory in the %files list:
  %{_datadir}/%{name}/
  %{_datadir}/%{name}/


It's usually easier to use wildcards for filenames, and that's also better at coping with changes in upstream.  Older RPM documentation typically shows long lists under %files with individual names, such as /usr/bin/program1 followed by /usr/bin/program2. Because of the way Fedora now uses buildroots, that is no longer necessary.
Notare che <code>%{_bindir}/*</code> non dice che il pacchetto in oggetto sia proprietario della cartella <code>/usr/bin</code>, 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 <code>%{_bindir}</code> assicurardosi anche delle cartelle condivise con altri rpm.


It's an error if ''no'' file matches the wildcard of a line, so only note the directories that actually matter.  Also, you can't identify the same file or directory more than once.  Finally, it's an error to have something in the buildroot and ''not'' listed under %files; the whole point of copying something into the buildroot is because you intend to have it installed in the final system.  If you don't intend that, remove those files during the %install process.
Si verificheranno errori se:
* una stringa non incontra alcun file o cartella
* file o cartelle sono elencate più volte
* file o cartelle in <code>%{buildroot}</code> non listate


It is also possible to exclude files from a previous match by using a %exclude glob. This can be useful for including "almost all" of the files that match a different glob. However, note that, like any other file glob, even a %exclude glob will fail if it matches nothing. (This might be considered counterintuitive, as the whole point is essentially to ensure that a certain file ISN'T there, so this rule is especially important to remember.)
E' inoltre possibile escludere file usando <code>%exclude</code>. Può aiutare per includere quasi tutti i file da differenti stringhe ma fallirà se non incontra nulla.


==== %files prefixes ====
==== %files prefix ====
You may need to add one or more prefixes to a %files entry (if more than one, use a space to separate them).
Potrebbe essere necessario aggiungere uno o più prefissi alle linee della sezione <code>%files</code>; separate da uno spazio. Vedi [http://www.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html Max RPM section on %files directives].


Typically there is a "%doc" entry with a list of documentation files that didn't get copied into the buildroot; usually there is at least a README and LICENSE file. You ''must'' include the license file, if there is one. You may prefix some of these with %attr(mode, user, group) to set the file permission mode, user, or group.  You don't need to claim ownership of the /usr/share/doc/%{name} directory, that's automatic if there's a %doc entry.  Any %doc entry must not affect the runtime of the application (if it is in %doc, the program must run properly if it is not present).
Solitamente "<code>%doc</code>" è usato per elencare file di documentazione dentro <code>%{_builddir}</code> che non sono stati copiati in <code>%{buildroot}</code>. I file <code>README</code> e <code>INSTALL</code> sono di solito inclusi. Saranno piazzati nella cartella <code>/usr/share/doc</code>, la cui proprietà non ha bisogna d'essere dichiarata.


There is a potential 'gotcha' with %doc entries: if you have a %doc entry, then you can't use commands during %install to copy files into the documentation directory descending from %_defaultdocdir. That's because if there's a %doc entry, rpmbuild will automatically remove the docdir files created by %install before installing the files listed with %doc. This can hit you if, for example, you want an "examples" subdirectory in the documentation directory.  In this case, don't use "%doc" to mark documentation.  Instead, create the directories and copy the files into %{buildroot}%{_defaultdocdir}/%{name}-%{version}/ during %install, and make sure that %files includes an entry for "%{_defaultdocdir}/%{name}-%{version}/".  They will still be correctly marked as documentation.
'''Nota:''' Se si specifica una voce <code>%doc</code>, rpmbuild < 4.9.1 rimuove la cartella doc, nella quale piazza i file prima di installarli. Ciò significa che i file già all'interno, ad esempio installati nella sezione <code>%install</code>, sono rimossi e non finiranno nel pacchetto. Se si vuole installare alcuni file in nella sezione <code>%install</code>, farlo in una cartella temporanea all'interno della build dir (non in build root), ad esempio <code>_docs_staging</code>, ed includerli nella sezione <code>%files</code> come <code>%doc _docs_staging/*</code>.


If you save configuration files (under /etc - don't put them under /usr), you should normally prefix them with %config(noreplace) unless this program version uses a non-backwards-compatible configuration format (in which case, prefix them with %config).
I file di configurazione dovrebbero essere posti in <code>/etc</code> 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


Prefixing a %files entry with "%attr(mode, user, group)" lets you set the permissions for particular file(s), e.g., "%attr(0644, root, root)".  A "-" means "use the default".
"<code>%attr(mode, user, group)</code>" può essere usato per controlli più precisi sui permessi, dove "<code>-</code>" significa usare il predefinito:
%attr(0644, root, root) FOO.BAR


If a file is in particular natural language, use %lang to note that. E.G.:
"<code>%caps(capabilities)</code>" può essere usato per dare certe [http://linux.die.net/man/7/capabilities capacità] POSIX ad un file. Ad esempio:
 
%caps(cap_net_admin=pe) FOO.BAR
 
Se un file è in lingua naturale, usare <code>%lang</code> per annotarlo:
  %lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh*
  %lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh*


Programs using Locale files should follow the
I programmi che utilizzano file di localizzazione dovrebbero seguire i [[Packaging:Guidelines#Handling_Locale_Files|metodi raccomandati per gestire i file i18n]]:
[[Packaging:Guidelines#Handling_Locale_Files|recommended method of handling the i18n files]]:


* find the filenames in the <code>%install</code> step: <code> %find_lang ${name}</code>
* trovare i filename nel passaggio <code>%install</code>: <code> %find_lang ${name}</code>
* add the required build dependencies: <code>BuildRequires: gettext</code>
* aggiungere le dipendenze per la costruzione richieste: <code>BuildRequires: gettext</code>
* use the found filenames: <code>%files -f ${name}.lang</code>
* usare i filename trovati: <code>%files -f ${name}.lang</code>


Some documentation claims that %license and %readme are valid prefixes; they are ''not'' valid in Fedora.  Use %doc instead.
<code>%readme</code> '''non''' è valido in Fedora.


==== %files and Filesystem Hierarchy Standard (FHS) ====
==== %files e Filesystem Hierarchy Standard (FHS) ====


You should follow the [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard (FHS)], i.e., ordinary application executables go into /usr/bin, global configuration files go into /etc, ordinary libraries go into /usr/lib, and so on, with one exception: executables that should ''not'' normally be executed directly by users or administrators should go into a subdirectory of /usr/libexec; usually you'd refer to the necessary directory as "%{_libexecdir}/%{name}".
Riferimento a [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard (FHS)].
Gli eseguibili vanno in <code>/usr/bin</code>, i file di configurazione globali vanno in <code>/etc</code>, le librerie in <code>/usr/lib</code> (o <code>/usr/lib64</code>) e così via. C'é un'eccezione: eseguibili non eseguiti normalmente direttamente dall'utente o dall'amministratore dovrebbero andare nella sottocartella di <code>/usr/libexec</code>, denominata con <code>%{_libexecdir}/%{name}</code>.


You shouldn't be installing files under /usr/local; that is where ''unpackaged'' files go.
'''Non''' installare file in <code>/opt</code> o in <code>/usr/local</code>.
Typically there will be a "prefix" attribute that lets you set the prefix to be "/usr" instead of "/usr/local".


Unfortunately, many programs' "normal" installation routines do not follow the FHS.
Sfortunatamente molt programmi non rispettano la FHS. In particolare, librerie indipendenti dall'architettura vengono inserite in <code>/usr/lib</code> invece di <code>/usr/share</code>. 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 <code>/usr/share</code>. Ci sono molte eccezioni in Fedora (Python e Perl), ma Fedora applica queste regole più rigidamente rispetto ad alcune altre distro. <code>rpmlint</code> generalmente segnala se si mette qualcosa di diverso dai file ELF in <code>/usr/lib</code>.
In particular, many programs normally place architecture-independent libraries under /usr/lib, instead of
under /usr/share as the FHS requires.
The [http://www.pathname.com/fhs/pub/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA FHS /usr/lib section] says that
/usr/lib is for architecture-''dependent'' data (e.g., ELF files like .so files), while
[http://www.pathname.com/fhs/pub/fhs-2.3.html#USRSHAREARCHITECTUREINDEPENDENTDATA /usr/share] is for
architecture-''independent'' data.  That way, systems with different CPUs can share /usr/share.
There are many exceptions to this rule in Fedora (e.g., Python and Perl), but Fedora applies this rule more
strictly than some distributions. Note, for example, that rpmlint will complain if you
put just about anything other than ELF files into /usr/lib.


==== %files example ====
==== Esempio di %files ====


Here's a simple example of a %files section:
Di seguito un esempio di sezione %files:
  %files
  %files
  %defattr(-,root,root,-)
  %doc README
  %doc README LICENSE
  %license LICENSE COPYING
  %{_bindir}/*
  %{_bindir}/*
  %{_sbindir}/*
  %{_sbindir}/*
  %{_datadir}/%{name}/
  %{_datadir}/%{name}/
%config(noreplace) %{_sysconfdir}/*.conf


==== Finding duplicates ====
==== Trovare duplicati ====


The Fedora guidelines require that
Per listare qualsiasi duplicato di un rpm:
"A Fedora package must not list a file more than once in the spec
file's %files listings."
 
You can list any duplicates of two binary packages by doing:
  cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture
  cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture
  rpm -qlp PACKAGE1.*.rpm | sort > ,1
  rpm -qlp PACKAGE1.*.rpm | sort > ,1
Line 562: Line 552:
  comm -12 ,1 ,2
  comm -12 ,1 ,2


=== Scriptlets ===
=== Scriptlet ===
You can add sections so that code will run when packages are installed or removed on the real system (as opposed to just running the %install script, which only does a pseudo-install to the build root).  These are called "scriptlets", and they are usually used to update the running system with information from the package.


The scriptlets in %pre and %post are run before and after a package is installed (respectively). The scriptlets %preun and %postun are run before and after a package is uninstalled. The scriptlets %pretrans and %posttrans are run at start and end of a transaction.  See [[Packaging/ScriptletSnippets]] for more examples and details.  For example, every binary RPM package which stores shared library files (not just symlinks) in any of the dynamic linker's default paths, must call ldconfig in %post and %postun (post-install and post-uninstall). If the package has multiple subpackages with libraries, each subpackage should also have a %post/%postun section that calls /sbin/ldconfig. For example:
Quando un utente installa l'rpm, si consigliano alcuni comandi da eseguire. Questo si può ottenere con gli scriptlet. Vedi [[Packaging/ScriptletSnippets]].
 
Gli scriptlet si eseguono:
* prima ('''<code>%pre</code>''') o dopo ('''<code>%post</code>''') l'installazione di un pacchetto
* prima ('''<code>%preun</code>''') o dopo ('''<code>%postun</code>''') la disinstallazione di un pacchetto
* all'avvìo ('''<code>%pretrans</code>''') o alla fine ('''<code>%posttrans</code>''') di una transazione
 
Per esempio, ogni rpm binario che immagazzina file di librerie condivise in qualsiasi percorso di dynamic linker, deve richiamare <code>ldconfig</code> in <code>%post</code> e <code>%postun</code>. Se il pacchetto ha molti sottopacchetti con librerie, ognuno di essi dovrebbe fare la stessa cosa.
  %post -p /sbin/ldconfig
  %post -p /sbin/ldconfig
  %postun -p /sbin/ldconfig
  %postun -p /sbin/ldconfig


''Beware'': The "-p" option specifies what ''command processor'' to use for the commands on the following lines.
Se si esegue un solo comando, l'opzione "<code>-p</code>" avvìa il comando adiacente senza invocare la shell. Tuttavia, per diversi comandi, ometterla e aggiungere tutti i comandi shell.
If there are no following lines, then using /sbin/ldconfig as the "command processor" is a minor efficiency improvement compared to putting "/sbin/ldconfig" on the next line, and letting the shell invoke it.
That's because by using "-p",
the shell isn't invoked simply to invoke a single program.
But if you have multiple shell commands,
don't use "-p" or /sbin/ldconfig after it!  Instead, leave it blank, and include the shell commands under it.


If you are going to run programs in scriptlets, they must be installed before you run them.
Se si avvìa un programma negli scriptlet, qualsiasi richiesta va specificata nella forma "<code>Requires(CONTEXT)</code>" (ad esempio <code>Requires(post)</code>).
You have to use special variants of the "Requires:" tag, so that
the program will be installed before you try to use it.  These are of the form "Requires(CONTEXT):", e.g., "Requires(post)".


Most scriptlets (%pre, %post, %preun, and %postun) provide an argument you can use,
<code>%pre</code>, <code>%post</code>, <code>%preun</code> e <code>%postun</code> forniscono l'argomento <code>$1</code>, che è il numero di pacchetti di questo nome che saranno lasciati nel sistema. Non confrontare per uguaglianza con <code>2</code>, controlla invece se sono meggiori o uguali a <code>2</code>. Per <code>%pretrans</code> e <code>%posttrans</code>, <code>$1</code> è sempre <code>0</code>.
accessed via $1, which is the number of packages of this name which will be left on the system
when the action completes.
Don't compare for ''equality'' with 2; check if they are ''greater than or equal than'' 2, since
users can arrange to have multiple versions of a package installed simultaneously.
For %pretrans and %posttrans, $1 is always 0.
 
For example, after adding an info manual to the system the dir file
which indexes the info manuals should be updated.
Basically, after you install the info manual, you need to run the program install-info.  That's fine, except that install-info is part of package info, and there's no guarantee that info is installed unless we require it. Also, if "install-info" fails, we don't want to fail ''all'' processing. Here's one way to do that:


Per esempio se il pacchetto installa un manuale il quale indice deve essere aggiornato con <code>install-info</code> dal pacchetto <code>info</code>, innanzitutto non è garantita la presenza del pacchetto <code>info</code> senza una sua richiesta specifica e poi non si può fallire completamente se <code>install-info</code> non funziona:
  Requires(post): info
  Requires(post): info
  Requires(preun): info
  Requires(preun): info
Line 601: Line 582:
  fi
  fi


There is another glitch related to installing info files. The <code>install-info</code> command will update
Esiste un altro problema tecnico relativo all'installazione dei manuali. Il comando <code>install-info</code> aggiornerà la certella delle informazioni, quindi si dovrebbero cancellare le cartelle vuote inutilizzate da %{buildroot} durante la sezione <code>%install</code>:
the info directory, but we have to prevent the install of a useless, empty directory file from the
RPM_BUILD_ROOT environment, by deleting it in  the <code>%install</code> section:
  rm -f $RPM_BUILD_ROOT%{_infodir}/dir
  rm -f %{buildroot}%{_infodir}/dir
 
Another scriptlet-like abilility are ''triggers''.  You can define triggers for when ''other'' packages
are installed or uninstalled.  See ''Maximum RPM'' for more information about triggers.
 
=== Macros ===


Spec files may contain "macro" references (text beginning with "%"), which are replaced with other values.
Un'altra abilità simile agli scriptlet è "trigger", avviabile quando altri pacchetti sono installati o disinstallati. Vedi [http://rpm.org/api/4.4.2.2/triggers.html RPM Triggers].
You can follow % by a word, e.g., "%name", but just like shell variables you must bracket the name with {...}
if letters or digits immediately follow, e.g., "%{name}".


As noted in the
=== Macro ===
[[Packaging/Guidelines| Packaging Guidelines]],
There are two styles for referring some values such as the rpm Build Root and Optimization Flags:
* "macro style": %{buildroot}, %{optflags}
* "variable style": $RPM_BUILD_ROOT, $RPM_OPT_FLAGS
Pick a style and use it consistently throughout your packaging; this document uses "macro style".


Here are some typical macros:
La macro è un testo nel formato <code>%{string}</code>. Tipiche macro:


{|
{|
! Macro !! Typical Expansion !! Meaning
! Macro !! Estensione tipica !! Significato
|-
|-
| %{_bindir} || /usr/bin || Binary directory (where executables are usually stored)
| <code>%{_bindir}</code> || <code>/usr/bin</code> || Cartella dei binari: dove gli eseguibili vengono solitamente localizzati.
|-
|-
| %{_builddir} || ~/rpmbuild/BUILD || Build directory; files are compiled a subdirectory of the build directory. See %buildsubdir.
| <code>%{_builddir}</code> || <code>~/rpmbuild/BUILD</code> || Cartella per il build: i file sono compilati all'interno della sua sottocartella. Vedere <code>%buildsubdir</code>.
|-
|-
| %{buildroot} || ~/rpmbuild/BUILDROOT || Build root, where files are "installed" during %install. The %install stage copies files from a subdirectory of %{_builddir} to a subdirectory of %{buildroot}. Historically %{buildroot} was in "/var/tmp/".
| <code>%{buildroot}</code> || <code>~/rpmbuild/BUILDROOT</code> || Build root: dove i file vengono "installati" durante <code>%install</code>, che li copia dalla sottocartella di <code>%{_builddir}</code> a quella di <code>%{buildroot}</code>. (Storicamente, <code>%{buildroot}</code> era in "/var/tmp/".)
|-
|-
| %{buildsubdir} || %{_builddir}/%{name} || Build subdirectory, where files are compiled during %build. It's under %{_builddir}, set after %setup.
| <code>%{buildsubdir}</code> || <code>%{_builddir}/%{name}</code> || Sottocartella build: interna a <code>%{_builddir}</code> dove i file sono compilati durante <code>%build</code>. E' impostata dopo <code>%autosetup</code>.
|-
|-
| %{_datadir} || /usr/share || Share directory.
| <code>%{_datadir}</code> || <code>/usr/share</code> || Cartella condivisa.
|-
|-
| %{_defaultdocdir} || /usr/share/doc || Default documentation directory.
| <code>%{_defaultdocdir}</code> || <code>/usr/share/doc</code> || Cartella predefinita della documentazione.
|-
|-
| %{dist} || .fc''NUMBER'' || Distribution+version short name (e.g., ".fc9")
| <code>%{dist}</code> || <code>.fc''NUMBER''</code> || Versione della distro (ad esempio "<code>.fc{{FedoraVersion}}</code>")
|-
|-
| %{fedora} || ''NUMBER'' || Number of fedora release (e.g., 9)
| <code>%{fedora}</code> || <code>''NUMBER''</code> || Numero di rilascio di Fedora (e.g. "<code>{{FedoraVersion}}</code>")
|-
|-
| %{_includedir} || /usr/include
| <code>%{_includedir}</code> || <code>/usr/include</code>
|-
|-
| %{_infodir} || /usr/share/info
| <code>%{_infodir}</code> || <code>/usr/share/info</code>
|-
|-
| %{_initrddir} || /etc/rc.d/init.d
| <code>%{_initrddir}</code> || <code>/etc/rc.d/init.d</code>
|-
|-
| %{_libdir} || /usr/lib
| <code>%{_libdir}</code> || <code>/usr/lib</code>
|-
|-
| %{_libexecdir} || /usr/libexec
| <code>%{_libexecdir}</code> || <code>/usr/libexec</code>
|-
|-
| %{_localstatedir} || /var
| <code>%{_localstatedir}</code> || <code>/var</code>
|-
|-
| %{_mandir} || /usr/share/man
| <code>%{_mandir}</code> || <code>/usr/share/man</code>
|-
|-
| %{name} || || Name of package, set by Name: tag
| <code>%{name}</code> || || Name of package, set by Name: tag
|-
|-
| %{_sbindir} || /usr/sbin
| <code>%{_sbindir}</code> || <code>/usr/sbin</code>
|-
|-
| %{_sharedstatedir} || /var/lib
| <code>%{_sharedstatedir}</code> || <code>/var/lib</code>
|-
|-
| %{_sysconfdir} || /etc
| <code>%{_sysconfdir}</code> || <code>/etc</code>
|-
|-
| %{version} || || Version of package, set by Version: tag
| <code>%{version}</code> || || Versione del pacchetto, impostata tramite il tag Version:
|}
|}


To see more about macros you
Se ne può sapere di più sulle macro guardando in <code>/etc/rpm/*</code> e <code>/usr/lib/rpm</code>, specialmente <code>/usr/lib/rpm/macros</code>. Inoltre usare <code>rpm --showrc</code> per saperne i valori che RPM userà per le macro (alterate da <code>rpmrc</code> e i file di configurazione delle macro).
can look in /etc/rpm/* and the "macros" files under "/usr/lib/rpm/",
especially /usr/lib/rpm/macros.
You can also use "rpm --showrc" to show the values rpm will use for all of the options
currently set in rpmrc and macro configuration files.


You can set your own macro values using %global; be sure to define them before you use them. Macro definitions
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:
can refer to other macros. For example:
  %global date 2012-02-08
  %global myvalue 50


You can use rpmbuild to find the value of some macro, using its "-E" (--eval) option. For example, to find the current expansion of %{_bindir} in myfile.spec, you can run:
Usare l'opzione "<code>-E</code>"di <code>rpmbuild</code> per trovare il valore della macro nello .spec file:
  rpmbuild -E '%{_bindir}' myfile.spec
  rpmbuild -E '%{_bindir}' myfile.spec


[[Packaging/RPMMacros]] has more information on macros, as does
Vedere anche [[Packaging/RPMMacros]] e [https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s07.html RPM Guide capitolo 9].
[http://docs.fedoraproject.org/drafts/rpm-guide-en/ch09s07.html RPM Guide chapter 9].


=== Other tags ===
=== Altri tag ===


We noted the "Requires" and "BuildRequires" tags earlier.
In aggiunta ai tag Requires e BuildRequires, esistono questi per il controllo delle dipendenze:
There are a few other tags for controlling dependencies:
* '''Provides''': lista i nomi dei pacchetti virtuali forniti. Ad esempio, ci potrebbe essere un pacchetto "<code>foo</code>" che esige una particolare funzionalità "bar" da un altro programma. Se esistono parecchi pacchetti che epossono soddisfarla, è possibile specificarli con "<code>Provides: bar</code>" e il pacchetto "<code>foo</code>" può specificare "<code>Requires: bar</code>". Si potrebbero anche usare [http://dailypackage.fedorabook.com/index.php?/archives/6-Wednesday-Why-The-Alternatives-System.html metodi "alternativi"], ma evitare se più utenti hanno necessità differenti, visto che queste impostazioni sono a livello di sistema. Usare "<code>rpm -q --provides PACKAGENAME</code>" per vedere cosa fornisce un determinato pacchetto. Alcuni esempi di pacchetti virtuali in Fedora:
Provides, Obsoletes, Conflicts, and BuildConflicts.
** MTA: Usato per i mail transport agents come sendmail.
* "Provides:" lets you list ''virtual'' package names that this package provides.  Sometimes there are several different packages that can provide a function, and using packages won't care which one. In that case, each of the packages that provide the function should "provide" a virtual package, and then using packages can list the virtual package name under "Requires:". For example, several different packages might provide "latex"; if you depend on the virtual package "tex(latex)", then users can choose which package to get "latex" from. If you provide virtual packages, you might also want to use the [http://dailypackage.fedorabook.com/index.php?/archives/6-Wednesday-Why-The-Alternatives-System.html "alternatives" system], but be careful: "alternatives" settings are ''system-wide'', so if multiple users on the same system might want different defaults, don't use the alternatives system. You can find out what a given package provides (both virtual and non-virtual names) by querying "rpm -q --provides PACKAGENAME". Some virtual packages in Fedora are:
** tex(latex): Usato per latex
** ''MTA'' : Used for mail transport agents, such as sendmail.
* '''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.
** ''tex(latex)'' : Used for latex
* '''Conflicts''': specifica quali altri pacchetti non possono essere installati simultaneamente a quello in oggetto. Evitarlo se possibile. Vedere [[Packaging/Conflicts]].
* "Obsoletes:" lets you state that installing this package should (normally) cause the removal of the other named package(s). This is useful when a package's name changes, or when a package wholly replaces a different package.
* '''BuildConflicts''': specifica quali pacchetti non possono essere installati se si costruisce il pacchetto in oggetto. Evitarlo se possibile.
* "Conflicts:" lets you state what packages cannot be installed simultaneously this one. Obviously, try to avoid this if you can; see [[Packaging/Conflicts]] if you think you need to use it.
* "BuildConflicts:" lets you state what packages cannot be installed when building this package. Obviously, try to avoid this if you can.


You can control which architectures a package builds (or doesn't build). For example, if your package can't compile on ppc, you can do this:
Per gestire differenti architetture, ci sono due tag:
* '''ExcludeArch''': per escluderne una nella quale la costruzione del pacchetto non avviene. Ad esempio:
  ExcludeArch: ppc
  ExcludeArch: ppc
There's also an "ExclusiveArch" tag. The valid architectures one can specify in these tags are listed in the [[Architectures]] section.
* '''ExclusiveArch''': per includere solo quella specificata. Evitarlo se non assolutamente corretto.
Architetture valide sono listate in [[Architectures]].


=== Subpackages ===
=== Subpackage ===
A spec file can define more than one binary package, e.g., client and server,
or runtime and developer packages.
If there's a large amount of documentation, it may be split into a NAME-doc subpackage.
You will always have one spec file and one source RPM (SRPM), even if there are
multiple binary RPMs that they generate.
A spec file that produces multiple binary packages still has only
one creation process, so there is only one
%prep, %build, %check, and %install section that creates all the files
for all the packages.


In a spec file, use the %package directive to start defining a 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 <code>name-doc</code> e <code>name-devel</code> sono comuni per la documentazionee i file di sviluppo rispettivamente.
%package sub_package_name


By default, the subpackage name is PACKAGE_NAME, "-", SUBPACKAGE_NAME; you can
Usare la direttiva <code>%package</code> per iniziare la definizione di un sottopacchetto:
use "-n" to override this and make a new name:
  %package subpackage_name
  %package -n new_sub_package_name


After the %package directive, list the tags for the subpackage.
Dopo ogni direttiva <code>%package</code>, listarne i tag. Dovrebbe almeno includere i tag Summary e Group, oltre a <code>%description subpackage_name</code> e <code>%files subpackage_name</code>:
This should include at least the "Summary:" and "Group:" tags and directives
"%description SUBPACKAGE_NAME" and "%files SUBPACKAGE_NAME".
Anything not specified by the subpackage will be inherited from its parent.
For the directives, if you used "-n" with %package,
you'll need it again for these directives.
You need to specify the name for the other directives, e.g., %pre and %post,
if you use them in the subpackage.


[http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch10s04.html See the RPM Guide section on subpackages] for more information.
Tutto quanto non specificato dal sottopacchetto sarà ereditato dal suo genitore.


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


You can insert conditional statements.
[http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch10s04.html Leggere la sezione sui sottopacchetti della Guida RPM] per maggiori informazioni.
E.G., you can test if you are creating a binary for a certain architecture
 
with:
=== Condizionali ===
 
E' possibile inserire stati di condizione, ad esempio per verificare se si sta creando un binario per una certa architettura:
  %ifarch ARCHITECTURE_NAME
  %ifarch ARCHITECTURE_NAME
the negated version with:
versione negata con:
  %ifnarch ARCHITECTURE_NAME
  %ifnarch ARCHITECTURE_NAME
or the more general conditional:
o più condizioni generiche:
  %if TRUE_OR_FALSE
  %if TRUE_OR_FALSE


There is an optional "%else" section; all of these are closed with "%endif".
C'é una sezione opzionale "<code>%else</code>"; tutte queste vengono chiuse con "<code>%endif</code>".


=== Application Specific Guidelines ===
=== Linee guida specifiche ===


There are many application-specific guidelines that can help you (e.g., for specific programming languages, applications, libraries, and build systems).  Many of them are listed as part of the
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 [[Packaging/Guidelines#Application_Specific_Guidelines|Application Specific Guidelines of Packaging/Guidelines]].  Esempi di linee guida:
[[Packaging/Guidelines#Application_Specific_Guidelines|Application Specific Guidelines of Packaging/Guidelines]].  Examples of application-specific guidelines are those for:
* [[Packaging:Cmake|Cmake]]
* [[Packaging:Cmake|Cmake]]
* [[Packaging:Emacs|Emacs]]
* [[Packaging:Emacs|Emacs]]


Failing that, some other ways of finding application-specific help are:
Altre sono:
* The 'SEARCH' command on Fedoraproject.org.
* Il comando 'SEARCH' di Fedoraproject.org.
* [[PackagingDrafts]]
* [[PackagingDrafts]]
* A [[SIGs|Special Interest Group (SIG)]]
* [[SIGs|Special Interest Group (SIG)]]
* [http://fedoraproject.org/wiki/Special:PrefixIndex/Packaging Wiki pages prefixed with 'Packaging']
* [[Special:PrefixIndex/Packaging|Pagine Wiki con prefisso 'Packaging']]


=== Miscellaneous hints ===
=== Suggerimenti vari ===


Try to write your scripts so that when upstream makes changes, the packaging is likely to work when you change the version number and reload the source file(s). For example, if it contains *.txt files with execute bits, instead of doing:
[[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
   chmod a-x Filename1.txt Filename2.txt Filename3.txt
consider doing this, which will handle new filenames that use the same file naming convention:
considerare comandi come il seguente:
   chmod a-x *.txt
   chmod a-x *.txt


If you want to see lots of examples of scriptlets, you can show all the scriptlets on installed programs using:
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
   rpm -qa --queryformat "\n\nPACKAGE: %{name}\n" --scripts | less


[[Packaging/FrequentlyMadeMistakes]] has information on frequently-made mistakes.
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.
 
Don't try to interact with the user; RPM is designed to support batch installs. If an application needs to show a EULA, that needs to be part of its initial execution, not its installation.


You might not want to start services, because in a big install that could slow things down. If you install an init script, consider using chkconfig to arrange for the service to be started and stopped on the next reboot. Before ''uninstalling'' you should normally try to stop its services if it's running.
Non si dovrebbero avviare servizi poiché potrebbero rallentare il tutto. Se si installa uno script init e systemd, considerare l'uso di <code>chkconfig</code> o di <code>systemctl</code> 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.


Uninstall should reverse most changes made during installation, but don't remove any user-created files.
La disinstallazione dovrebbe togliere tutte le modifiche fatte nell'installazione, ma non i file creati dall'utente.


Normally, if there are binary executables, a separate "debug" package is created with the symbols, and the symbols are stripped from the normal binary packages.  If this shouldn't happen, you can disable the package-creation and stripping with:
Normalmente, se ci sono binari eseguibili, i simboli di debugging sono tolti dall'rpm binario normale e piazzati in un sottopacchetto <code>name-debug</code>. Se non dovesse succedere, si può disabilitare la creazione dell'rpm-debug aggiungendo in cima allo .spec file:
  %global _enable_debug_package 0
  %global _enable_debug_package 0
  %global debug_package %{nil}
  %global debug_package %{nil}
  %global __os_install_post /usr/lib/rpm/brp-compress %{nil}
  %global __os_install_post /usr/lib/rpm/brp-compress %{nil}


To prevent stripping you may also need to do this in the %install section:
mentre nella sezione <code>%install</code>:
  export DONT_STRIP=1
  export DONT_STRIP=1


A way to check for the version of Fedora in a spec file for conditional builds is:
Un modo per controllare la versione di Fedora in uno .spec file per i build condizionali è:
  %if 0%{?fedora} <= <version>
  %if 0%{?fedora} <= <version>
(The ? causes the macro to evaluate to blank if %fedora is not defined, and this causes the end result to be "0", which is a number and thus ok, while not interfering with the result if there is actually a value for %fedora.)
Il <code>?</code> permette il riconoscimento della versione se <code>%fedora</code> non è definito. Fa sì che il risultato finale sia <code>0</code>, pur non interferendo sul risultato se presente un valore per <code>%fedora</code>. (Notare che questo metodo non funziona nelle build "scratch" in Koji, dove <code>%fedora</code> è impostato durante la creazione di un SRPM.)
 
Note that the previous trick DOES NOT work in Koji "scratch" builds - %fedora is set during the creation of a source RPM. (Thus, this trick does work in actual Koji builds as the system extracts sources from the source RPM and rebuilds the source RPM with the appropriate %fedora value.)


There are also some recommendations and controversial tricks on
Le GUI devono avere una voce desktop così da permetterne l'uso dal menu grafico. Per i file <code>.desktop</code>, vedere [[Packaging/Guidelines#Desktop_files|Fedora packaging guidelines for desktop files]] e [http://standards.freedesktop.org/desktop-entry-spec/latest/ desktop entry spec]. Per le icone in <code>/usr/share/icons</code>, vedere [http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html icon theme spec].
[[PackageMaintainers/Packaging Tricks]].
 
GUI programs ''must'' have a desktop entry (so that people can invoke it from a graphical menu). The
[http://fedoraproject.org/wiki/Packaging/Guidelines#Desktop_files Fedora packaging guidelines discuss desktop files].  See also the [http://standards.freedesktop.org/desktop-entry-spec/latest/ desktop entry spec] (for .desktop files) and
[http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html icon theme spec] (for icon-related materials such as those in /usr/share/icon).
 
=== Older RPM documents ===
Some older documents about RPM have the most information, but some older documents make claims that are no longer true:
* rpm files are no longer placed in a shared /usr/src/redhat directory.  This is an obsolete way of using rpm and ''not'' recommended; modern systems set a %{_topdir} instead like ~/rpmbuild.
* the %install process does not install files in their final location.  Instead, it "installs" files to the buildroot.
* The "rpm" command no longer creates packages (e.g., "rpm -ba" was once legal). Use the separate "rpmbuild" program instead.
* Many historical specs use the "%define" command to define macros.  However, "%define" creates a locally defined submacro within other macro definitions; this is very rarely needed, and using %define incorrectly can cause subtle bugs.  For nearly all uses, use "%global" instead.  (See [[PackagingDrafts/global_preferred_over_define]].)
* The "BuildRoot:" value is now ignored.


== Costruzione del pacchetto binario ==
== Costruzione del pacchetto binario ==
=== Test con rpmlint ===
=== Test con rpmlint ===


Prima di provare a costruire qualsiasi cosa da esso, si dovrebbe eseguire ''rpmlint'' sullo spec file:
Prima di provare a costruire qualsiasi cosa, si dovrebbe eseguire <code>rpmlint</code> sullo spec file:
  $ rpmlint program.spec
  $ rpmlint program.spec
Troverà molti errori velocemente. Se l'errore riportato non ha molto senso,
Troverà molti errori velocemente. Se l'errore riportato non ha molto senso,
Line 813: Line 742:


L'ideale sarebbe quello d'avere il minor numero di errori, ma talvolta rpmlint riporta dei falsi positivi.
L'ideale sarebbe quello d'avere il minor numero di errori, ma talvolta rpmlint riporta dei falsi positivi.
Le [http://fedoraproject.org/wiki/Packaging/Guidelines#Use_rpmlint linee guida Fedora packaging] spiega quali sono da ignorare.
Le [[Packaging/Guidelines#Use_rpmlint|linee guida Fedora packaging]] spiega quali sono da ignorare.


=== Creazione degli RPM dallo spec file ===
=== Creazione degli RPM dallo spec file ===
Line 824: Line 753:
Quando qualcosa va male, è possibile entrare ("cd") nella directory appropriata e vedere cosa contiene.
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):
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
$ rpmbuild -bi --short-circuit program.spec
Se si vuole creare l'rpm sorgente (.src.rpm), entrare nella cartella SPECS e:
Se si vuole creare l'rpm sorgente (.src.rpm), entrare nella cartella SPECS e:
  $ rpmbuild -bs program.spec   
  $ rpmbuild -bs program.spec   
Line 831: Line 760:
=== Testare con rpmlint gli RPM creati ===
=== 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:
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. [[Common_Rpmlint_issues|Questa pagina]] offre spiegazioni per alcuni dei problemi comuni che potrebbero saltare fuori. <br/>
Dalla cartella SPECS:
  $ rpmlint ''NAME''.spec ../RPMS/*/''NAME''*.rpm ../SRPMS/''NAME''*.rpm
  $ 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.
Generalmente rpmbuild costruisce rpm binari con informazioni di debug, anche questi possono essere sottoposti al test.
Line 849: Line 779:
== Mock and Koji ==
== Mock and Koji ==


[[Projects/Mock|Mock]] è un potente tool che usa gli SRPM creati per costruire pacchetti binari all'interno di un ambiente quasi vuoto 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:
[[Projects/Mock|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 <code>mock</code>; una volta che il proprio account rientra nel gruppo "<code>mock</code>", è possibile avviare comandi come il seguente per eseguire test in locale:
  $ mock -r fedora-9-i386 rebuild path_to_source_RPM
  $ 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
Una volta che Mock ha funzionato correttamente, si può usare Koji (il quale usa Mock) per costruire in
differenti sistemi alcuni dei quali non si può avere. [[PackageMaintainers/Join]] e [[PackageMaintainers/UsingKoji]] hanno molte informazioni su Koji.
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
Una volta settati, si possono eseguire test sul proprio rpm sorgente con differenti sistemi
  $ koji build --scratch dist-f9 path_to_source_RPM
  $ koji build --scratch dist-f9 path_to_source_RPM
Si può sostituire la voce "dist-f9" 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.
Si può sostituire la voce "<code>%fc9</code>" con qualsiasi altra release successiva di Fedora, ma non usare <code>dist-rawhide</code>. Ricordarsi che i valori di <code>%fedora</code>, %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.
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.
Se si vuole costruire un pacchetto che non è ancora una versione aggiornata stabile, presentare una richiesta "buildroot override" via Bodhi. Se il pacchetto non è a proprio carico, contattare il/i maintainer. [Prima dell'attuale metodo che prevede una richiesta "buildroot override", si poteva aprire un ticket con rel-eng a https://fedorahosted.org/rel-eng/newticket e chiedere che il pacchetto venisse aggiunto come buildroot override]


== Strumenti utili ==
== Strumenti utili ==


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


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


Il pacchetto yum-utils contiene molti strumenti.
DNF download plugin (dal core DNF plugins) contiene molti strumenti utili:


* <code>yumdownloader: scarica il pacchetto sorgente con:</code>
* <code>dnf download</code>: scarica il pacchetto sorgente


  $ yumdownloader --source PACKAGENAME
  $ dnf download --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.
Il pacchetto <code>auto-buildrequires</code> ha un paio di buoni strumenti d'aiuto per configurare correttamente la voce BuildRequires. Dopo averlo installato, rimpiazzare "<code>rpmbuild</code>" con "<code>auto-br-rpmbuild</code>" e si vedrà automaticamente generata la lista buildrequires.


Potrebbe essere utile [http://rust.sourceforge.net/ RUST] (GPL), anche se non crea rpm di adeguata qualità per i repository Fedora. [http://kitenet.net/~joey/code/alien/ 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.
Potrebbe essere utile [http://rust.sourceforge.net/ RUST] (GPL), anche se non crea rpm di adeguata qualità per i repository Fedora. [http://kitenet.net/~joey/code/alien/ 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.
Se si ha intenzione di creare un pacchetto RPM per Fedora, assicurarsi di sottoporre il proprio file ad una [https://fedorahosted.org/FedoraReview/ Fedora Review], che aiuta a garantire che ci si attenga alle [[Packaging:Guidelines?rd=Packaging/Guidelines|Linee-guida sul Packaging]].
Finalmente, [https://github.com/alanfranz/docker-rpm-builder docker-rpm-builder] (APL 2.0) usa [http://www.docker.com Docker] per costruire i pacchetti RPM; mentre l'uso di 'rpmbuild' richiede di lavorare nella stessa distro del target, e 'mock' funziona bene su distribuzioni Fedora/Centos/RHEL per qualsiasi target, '''quest'ultimo strumento lavora con Docker'''.
Se si preferisce costruire RPM per altre distribuzioni o architetture avendo accesso pubblico ai repository, è possibile usare [https://copr.fedoraproject.org Copr].
Per firmare il pacchetto, usare <code>rpmsign</code>.


== Linee guida e regole ==
== Linee guida e regole ==
Line 890: Line 828:
Si può inoltre imparare molto dalle sezioni [[SIGs]] e  
Si può inoltre imparare molto dalle sezioni [[SIGs]] e  
[[:Category:Package Maintainers|Package Maintainers]].
[[:Category:Package Maintainers|Package Maintainers]].
[https://fedoraproject.org/wiki/Special:Prefixindex/Packaging Lista delle pagine wiki sul Packaging] per vedere se qualcuno si applica.
[[Special:Prefixindex/Packaging|Lista delle pagine wiki sul Packaging]].
 
Inoltre, si potrebbero trovare utili quelle non ufficiali
[[Special:Search?ns0=1&search=PackagingDrafts%2F&searchx=Search|Packaging Drafts]] e [[PackagingDrafts|Packaging Drafts To Do]].
 
Si potrebbero trovare spunti da [http://en.opensuse.org/Packaging SuSE],
[http://www.debian.org/doc/debian-policy/ Debian], ma
[http://www.mail-archive.com/distributions@lists.freedesktop.org/msg00156.html ci sono differenze tra le distribuzioni], quindi si presume che non possono essere usate direttamente.


Se non servono, si potrebbero trovare utili quelle non ufficiali
'''I file .spec creati devono riguardare software opensource come previsto dal [[Legal:Fedora_Project_Contributor_Agreement|FPCA]].'''
[https://fedoraproject.org/wiki/Special:Search?ns0=1&search=PackagingDrafts%2F&searchx=Search Packaging Drafts] e [https://fedoraproject.org/wiki/PackagingDrafts Packaging Drafts To Do].


== Mantenimento del pacchetto ==
== Mantenimento del pacchetto ==
Line 932: Line 876:
* [http://wiki.mandriva.com/en/Development/Howto/RPM Mandriva Rpm HowTo (en)] ([http://www.mandrivaclub.com/xwiki/bin/view/KB/MandrivaRpmHowTo alt]) è un tutorial RPM anche se per Mandriva. Da notare che in Fedora ''non'' si ricomprimono i tarball originali, come Mandriva suggerisce, perché questo avrebbe cambiato le loro hash crittografate.
* [http://wiki.mandriva.com/en/Development/Howto/RPM Mandriva Rpm HowTo (en)] ([http://www.mandrivaclub.com/xwiki/bin/view/KB/MandrivaRpmHowTo alt]) è un tutorial RPM anche se per Mandriva. Da notare che in Fedora ''non'' si ricomprimono i tarball originali, come Mandriva suggerisce, perché questo avrebbe cambiato le loro hash crittografate.
* [http://linuxshellaccount.blogspot.com/2008/03/creating-your-own-linux-rpms-initial.html Creazione del proprio Linux RPM - Software Building Iniziale] è un'altra introduzione ma fa il punto su "Il processo per costruire RPM è più facile della creazione dei pacchetti per Solaris... Meno passaggi, e l'abilità di aggiungere tutte le informazioni sul software in uno specifico file,  fatti per una maggiore essenzialità (più facile da modificare e riprodurre) del sistema di packaging".
* [http://linuxshellaccount.blogspot.com/2008/03/creating-your-own-linux-rpms-initial.html Creazione del proprio Linux RPM - Software Building Iniziale] è un'altra introduzione ma fa il punto su "Il processo per costruire RPM è più facile della creazione dei pacchetti per Solaris... Meno passaggi, e l'abilità di aggiungere tutte le informazioni sul software in uno specifico file,  fatti per una maggiore essenzialità (più facile da modificare e riprodurre) del sistema di packaging".
* [http://fedoranews.org/alex/tutorial/rpm/ Tutto ciò da sapere sul RPM] (più sull'installazione che sulla creazione)
* [http://fedoranews.org/alex/tutorial/rpm/ Tutto ciò che bisogna sapere su RPM] (più sull'installazione che sulla creazione)
* The [http://wiki.rpm.org/ rpm.org Wiki] ha alcune informazioni utili, come la [http://wiki.rpm.org/Problems lista dei problemi conosciuti]
* The [http://wiki.rpm.org/ rpm.org Wiki] ha alcune informazioni utili, come la [http://wiki.rpm.org/Problems lista dei problemi conosciuti]



Latest revision as of 20:59, 19 September 2016

Questa pagina è parzialmente conforme a quella in lingua inglese; verrà aggiornata al completamento delle correzioni sull'originale.

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.

Attualmente la Documentazione Fedora ha rilasciato una bozza di guida per i packager: Packagers Guide

Da notare che questa pagina NON mostra le linee guida ufficiali sulla creazione dei pacchetti per Fedora; a questo proposito, il Packaging Committee gestisce le regole e le linee guida stesse per il packaging in Fedora. Quelle più importanti:


Packaging Guidelines e Package Naming Guidelines sono le principali. Detto ciò, questa pagina dovrebbe 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 '#' !)

 # dnf install @development-tools
 # dnf install fedora-packager
 # dnf install rpmdevtools
 

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 e non invierà file o chiavi private al mondo esterno.

Non si dovrebbe MAI creare un pacchetto usando l'utente root. Farlo è pericoloso, poiché i file binari vengono installati nel sistema prima di essere impacchettati, quindi bisogna sempre operare come utente normale in modo da non inquinare accidentalmente il proprio sistema.

Creare un nuovo utente chiamato semplicemente "makerpm", aggiungerlo al gruppo 'mock', impostarne la password eseguendo:

 # /usr/sbin/useradd makerpm
 # usermod -a -G mock 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 deve 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):

Alcune directory hanno determinati funzioni per rpmbuild che possono essere sostituiti nel file .spec in base alle macro predefinite (iniziano per %):

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

Nome della Macro Nome Predefinito Funzione
%_specdir Specification directory ~/rpmbuild/SPECS File SPEC degli 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.

Per creare i pacchetti binario e sorgente, dalla directory ~/rpmbuild/SPECS avviare:

 $ rpmbuild -ba NAME.spec

Quando invocato in questo modo rpmbuild legge il file .spec e segue le seguenti fasi di lavoro:

Nome dela Macro Nome Predefinito Funzione
%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 realizzare qui alcune variazioni di "./configure && make".
%check %_builddir %_builddir Verifica che il software funziona propriamente. Fase spesso realizzata per eseguire alcune variazioni di "make test". Molti pacchetti non realizzano 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 è realizzata 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.


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 il DNF download Plugin:

$ dnf download --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 e PKGS.org potrebbero 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.

Modelli ed esempi di SPEC

Modelli

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 (Nota: il modello fornito sotto non necessariamente è conforme con le linee guida del Fedora Packaging):

Name:		
Version:	
Release:	1%{?dist}
Summary:	
Group:		
License:	
URL:		
Source0:	

BuildRequires:	
Requires:	

%description

%prep
%autosetup

%build
%configure
make %{?_smp_mflags}

%install
%make_install

%files
%doc
%license

%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

Esempi

eject

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
%autosetup -n %{name}

%build
%configure
make %{?_smp_mflags}

%install
%make_install

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

%find_lang %{name}

%files -f %{name}.lang
%doc README TODO ChangeLog
%license COPYING
%{_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 del file SPEC

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 (le macro vengono espanse prima); 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 coincidere con 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 pacchettizzazione. 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 con una sola frase.
  • 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. Nota: Questo tag è disapprovato a partire da Fedora 17. Vedere [Introduzione di riferimento Spec File]
  • 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 and BSD").
  • URL: L'intero URL per avere maggiori informazioni sul programma (ad esempio il sito del progetto). Nota: 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 "file .patch" nella cartella ~/rpmbuild/SOURCES. Le Patch dovrebbero fare una modifica alla volta, quindi è possibile avere più file .patch .
  • BuildArch: Se i file da pacchettizzare sono indipendenti dall'architettura (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 pacchetto auto-buildrequires 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 "%autosetup"; una comune variante è "%autosetup -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} # ridondante eccetto per RHEL 5
  • %files: Lista di file che saranno installati. Vedere la sezione %files.
  • %changelog: Modifiche nel pacchetto. Usare l'esempio sopra. NON inserire il changelog storico del software. Questo riguarda solo quello dell'RPM stesso.
  • 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 "ricollocabile"; non valgono in Fedora e sono complicati.

Approfondimento sezioni SPEC file

Sezione %prep

La sezione "%prep" descrive come spacchettare gli archivi compressi così da poter iniziare la compilazione. Di solito include i comandi "%autosetup"; in alternativa di usano i 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; se si usa una lunga lista di patch o sorgenti ed %autosetup non è vi è utile, è possibile fare qualcosa del genere:

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 %autosetup

Il comando "%autosetup" spacchetta i sorgente.

  • -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 il file .tar decomprime nella cartella FOO, allora usare "%autosetup -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.

Se si usa il comando "%setup" invece, allora l'opzione -q è comunemente usata per sopprimere gli output non necessari.

Ci sono più opzioni %setup, utili principalmente se si stanno creando sottopacchetti. 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

Se è stato usato il comando "%autosetup", le nozioni sotto indicate non servono. Se si hanno necessità più complesse o di compatibilità con EPEL, allora possono servire.

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".

Alcuni programmi usano cmake. Vedi 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

A volte può essere:

make check

Osservare il file Makefile per sapere il modo più appropriato.

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":

%install
rm -rf %{buildroot} # ridondante ad eccezione di RHEL5
%make_install


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}/

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

Potrebbe essere necessario aggiungere uno o più prefissi alle linee della sezione %files; separate da uno spazio. Vedi 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, la cui proprietà non ha bisogna d'essere dichiarata.

Nota: Se si specifica una voce %doc, rpmbuild < 4.9.1 rimuove la cartella doc, nella quale piazza i file prima di installarli. Ciò significa che i file già all'interno, ad esempio installati nella sezione %install, sono rimossi e non finiranno nel pacchetto. Se si vuole installare alcuni file in nella sezione %install, farlo in una cartella temporanea all'interno della build dir (non in build root), ad esempio _docs_staging, ed includerli nella sezione %files come %doc _docs_staging/*.

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

"%caps(capabilities)" può essere usato per dare certe capacità POSIX ad un file. Ad esempio:

%caps(cap_net_admin=pe) 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

%readme non è valido in Fedora.

%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 LICENSE COPYING
%{_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. Vedi 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. Vedi 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 %autosetup.
%{_datadir} /usr/share Cartella condivisa.
%{_defaultdocdir} /usr/share/doc Cartella predefinita della documentazione.
%{dist} .fcNUMBER Versione della distro (ad esempio ".fc41")
%{fedora} NUMBER Numero di rilascio di Fedora (e.g. "41")
%{_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. Questa pagina offre spiegazioni per alcuni dei problemi comuni che potrebbero saltare fuori.
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, presentare una richiesta "buildroot override" via Bodhi. Se il pacchetto non è a proprio carico, contattare il/i maintainer. [Prima dell'attuale metodo che prevede una richiesta "buildroot override", si poteva aprire un ticket con rel-eng a https://fedorahosted.org/rel-eng/newticket e chiedere che il pacchetto venisse 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

DNF download plugin (dal core DNF plugins) contiene molti strumenti utili:

  • dnf download: scarica il pacchetto sorgente
$ dnf download --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.

Se si ha intenzione di creare un pacchetto RPM per Fedora, assicurarsi di sottoporre il proprio file ad una Fedora Review, che aiuta a garantire che ci si attenga alle Linee-guida sul Packaging.

Finalmente, docker-rpm-builder (APL 2.0) usa Docker per costruire i pacchetti RPM; mentre l'uso di 'rpmbuild' richiede di lavorare nella stessa distro del target, e 'mock' funziona bene su distribuzioni Fedora/Centos/RHEL per qualsiasi target, quest'ultimo strumento lavora con Docker.

Se si preferisce costruire RPM per altre distribuzioni o architetture avendo accesso pubblico ai repository, è possibile usare Copr.

Per firmare il pacchetto, usare rpmsign.

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.

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

Si potrebbero trovare spunti da SuSE, Debian, ma ci sono differenze tra le distribuzioni, quindi si presume che non possono essere usate direttamente.

I file .spec creati devono riguardare software opensource come previsto dal FPCA.

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.