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.
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):
Fase | Letture | Scritture | Azioni |
---|---|---|---|
%prep |
%_sourcedir |
%_builddir |
Legge i sorgenti e le patch nella directory %_sourcedir . Questa fase scompatta il sorgente in una sotto-directory inferiore alla directory di build %_builddir (di solito ~/rpmbuild/BUILD/) e applica le patch.
|
%prep |
%_sourcedir |
%_builddir |
Compila i file nella directory sotto quella di build %_builddir . Di solito si possono implementare qui alcune variazioni di "./configure && make ".
|
%check |
%_builddir |
%_builddir |
Verifica che il software funziona propriamente. Fase spesso implementata per eseguire alcune variazioni di "make test ". Molti pacchetti non implementano questa fase.
|
%install |
%_builddir |
%_buildrootdir |
Questa fase legge i file nella directory sotto quella di build %_builddir e scrive in una directory sotto la root build directory %_buildrootdir . I file che sono scritti si suppone che saranno installati quando il pacchetto dei binari viene installato dall'utente finale. Attenzione alla strana terminologia: La directory build root non è la stessa della build directory. Questa fase è implementata da "make install ".
|
bin |
%_buildrootdir |
%_rpmdir |
Legge la directory sotto la build root directory %_buildrootdir per creare un pacchetto RPM binario sotto la directory RPM %_rpmdir . All'interno della directory RPM vi è una directory per ogni architettura ed una denominata "noarch " per pacchetti che si possono applicare a molte architetture. Questi file RPM sono i pacchetti che gli utenti andranno ad installare.
|
src |
%_sourcedir |
%_srcrpmdir |
Questa crea un pacchetto sorgente RPM (.src.rpm ) all'interno della directory RPM sorgente %_srcrpmdir . Questi file sono necessari per una revisione e un aggiornamento del pacchetto.
|
Come si può vedere, alcune directory hanno scopi particolari per rpmbuild
. Queste sono:
Nome della Macro | Nome | Di solito | Scopo |
---|---|---|---|
%_specdir |
Specification directory | ~/rpmbuild/SPECS |
File 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. |
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/40/Everything/source/SRPMS
.
(rimpiazzare "40
" 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 %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 COPYING ChangeLog %{_bindir}/* %{_sbindir}/* %{_mandir}/man1/* %changelog * Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.5-21 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild * Fri Jul 02 2010 Kamil Dudka <kdudka@redhat.com> 2.1.5-20 - handle multi-partition devices with spaces in mount points properly (#608502)
Panoramica 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 esempio2008-05-01
diventa8.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 a1
. 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 esempiokernel-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 cartellaSOURCES
. 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, nominarliSource1
,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 programmaEGGS
, determinarne il pacchetto che lo possiede con "rpm -qf
". Mantenere le dipendenze ad un numero minimo (ad esempio usarewhich EGGS
sed
invece diperl
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
può essere utile.auto-buildrequires
- 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 inNAME
. Vedere la sezione %prep. - %build: Comandi script per "costruire" il programma (ad esempio compilare) ed ottenerlo pronto per l'installazione. Incluse le istruzion su come farlo. Vedere la sezione %build.
- %check: Comandi script per "testare" il programma. E' avviato tra le procedure %build e %install, quindi piazzarlo tra le due se serve. Spesso contiene semplicemente "
make test
" oppure "make check
". E' separato da %build così da poter essere saltato a discrezione dell'utente. - %install: Comandi script per "installare" il programma. I comandi dovrebbero copiare file dalla cartella
BUILD
%{_builddir}
nella buildroot%{buildroot}
. Vedere la sezione %install. - %clean: Istruzioni su come ripulire la build root. Notare che questa sezione è ridondante in Fedora mentre è necessaria per EPEL. Tipicamente contiene solo:
rm -rf %{buildroot}
- %files: Lista di file che saranno installati. Vedere la sezione %files.
- %changelog: Modifiche nel pacchetto. Usare l'esempio sopra. 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 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 %spec, utli principalmente se si sanno creando sottoacchetti. Quelle principali sono:
-a number |
Decomprime il Source dato dal numero indicato dopo aver cambiato cartella (ad esempio "–a 0 " per Source0).
|
-b number |
Decomprime il Source dato dal numero indicato prima aver cambiato cartella (ad esempio "–a 0 " per Source0).
|
-D |
Non cancella la cartella dopo la decompressione. |
-T |
Disabilita la decompressione automatica dell'archivio. |
Sezione %prep: comando %patch
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" e "Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer.
Alcuni programmi usano cmake
. Vedere Packaging/cmake.
Sezione %check
Se disponibili dei self-test, è buona idea includerli. Dovrebbero essere piazzati nella sezione %check (che segue la sezione %build) invece che all'interno della %build stessa, così da poter essere facilmente saltati se necessario.
Spesso questa sezione contiene:
make test
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 eccetto che per 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 diDESTDIR
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, comecp
einstall
. - Installare manualmente. Dovrbbe includere la creazione delle necessarie cartelle sotto
%{buildroot}
e la copia dei file da%{_builddir}
a%{buildroot}
. Bisogna essere cauti con gli aggiornamenti, contengono spesso nuovi filename. Un esempio di questa procedura:
%install rm -rf %{buildroot} mkdir -p %{buildroot}%{_bindir}/ cp -p mycommand %{buildroot}%{_bindir}/
Come annotato in Packaging:Guidelines#Timestamps, tentare di preservare i timestamp se il makefile consente di ignorare i comandi:
make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install
Sezione %files
Questa sezione dichiara i file e le cartelle proprietà del pacchetto quindi incorporati nell'RPM binario.
Nozioni sulla sezione %files
Il %defattr
imposta i permessi predefiniti del file e spesso appare all'inizio della sezione %files
. Da notare che non è più necessario a meno che non bisogna i permessi. Il formato è:
%defattr(<file permissions>, <user>, <group>, <directory permissions>)
Il quarto parametro è solitamente omesso. Si usa %defattr(-,root,root,-)
, dove "-
" usa i permessi predefiniti.
Si dovrebbero poi elencare i file e le cartelle che saranno di proprietà del pacchetto. A tal proposito usare le macro per i nomi delle cartelle, mostrate in Packaging:RPMMacros (ad esempio usare %{_bindir}/mycommand
invece di /usr/bin/mycommand
). Se la stringa inizia con "/
" (o quando esteso da una macro) allora viene prelevato dalla cartella %{buildroot}
. Oppure, si presume che il file sia nella cartella corrente (ad esempio dentro %{_builddir}
come per i file di documentazione da includere). Se il pacchetto installa un solo file /usr/sbin/mycommand
, la sezione %files
può semplicemente essere:
%files %{_sbindir}/mycommand
Per ottenere un rpm meno soggetto ai cambiamenti dell'upstream, dichiarare tutti i file all'interno di una cartella di proprietà del pacchetto con la stringa:
%{_bindir}/*
Per includere una singola cartella:
%{_datadir}/%{name}/
Notare che %{_bindir}/*
non dice che il pacchetto in oggetto sia proprietario della cartella /usr/bin
, ma solo dei file contenuti all'interno. Se si elenca una cartella, allora si richiede la proprietà di quella cartella e dei file e sottocartelle contenute. Quindi non si elenca %{_bindir}
assicurardosi anche delle cartelle condivise con altri rpm.
Si verificheranno errori se:
- una stringa non incontra alcun file o cartella
- file o cartelle sono elencate più volte
- file o cartelle in
%{buildroot}
non listate
E' inoltre possibile escludere file usando %exclude
. Può aiutare per includere quasi tutti i file da differenti stringhe ma fallirà se non incontra nulla.
%files prefix
Potrebbe essere necessario aggiungere uno o più prefissi alle linee della sezione %files
; separate da uno spazio. Vedere Max RPM section on %files directives.
Solitamente "%doc
" è usato per elencare file di documentazione dentro %{_builddir}
che non sono stati copiati in %{buildroot}
. I file README
e INSTALL
sono di solito inclusi. Saranno piazzati nella cartella /usr/share/doc
, 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
Questi prefix non sono validi in Fedora: %license
and %readme
.
%files e Filesystem Hierarchy Standard (FHS)
Riferimento a Filesystem Hierarchy Standard (FHS).
Gli eseguibili vanno in /usr/bin
, i file di configurazione globali vanno in /etc
, le librerie in /usr/lib
(o /usr/lib64
) e così via. C'é un'eccezione: eseguibili non eseguiti normalmente direttamente dall'utente o dall'amministratore dovrebbero andare nella sottocartella di /usr/libexec
, denominata con %{_libexecdir}/%{name}
.
Non installare file in /opt
o in /usr/local
.
Sfortunatamente molt programmi non rispettano la FHS. In particolare, librerie indipendenti dall'architettura vengono inserite in /usr/lib
invece di /usr/share
. Il primo è per librerie diendenti dall'architettura, mentre il secondo è per quelle indipendenti; significa che i sistemi con differenti architetture di CPU possono condividere la /usr/share
. Ci sono molte eccezioni in Fedora (Python e Perl), ma Fedora applica queste regole più rigidamente rispetto ad alcune altre distro. rpmlint
generalmente segnala se si mette qualcosa di diverso dai file ELF in /usr/lib
.
Esempio di %files
Di seguito un esempio di sezione %files:
%files %doc README LICENSE %{_bindir}/* %{_sbindir}/* %{_datadir}/%{name}/ %config(noreplace) %{_sysconfdir}/*.conf
Trovare duplicati
Per listare qualsiasi duplicato di un rpm:
cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture rpm -qlp PACKAGE1.*.rpm | sort > ,1 rpm -qlp PACKAGE2.*.rpm | sort > ,2 comm -12 ,1 ,2
Scriptlet
Quando un utente installa l'rpm, si consigliano alcuni comandi da eseguire. Questo si può ottenere con gli scriptlet. Vedere Packaging/ScriptletSnippets.
Gli scriptlet si eseguono:
- prima (
%pre
) o dopo (%post
) l'installazione di un pacchetto - prima (
%preun
) o dopo (%postun
) la disinstallazione di un pacchetto - all'avvìo (
%pretrans
) o alla fine (%posttrans
) di una transazione
Per esempio, ogni rpm binario che immagazzina file di librerie condivise in qualsiasi percorso di dynamic linker, deve richiamare ldconfig
in %post
e %postun
. Se il pacchetto ha molti sottopacchetti con librerie, ognuno di essi dovrebbe fare la stessa cosa.
%post -p /sbin/ldconfig %postun -p /sbin/ldconfig
Se si esegue un solo comando, l'opzione "-p
" avvìa il comando adiacente senza invocare la shell. Tuttavia, per diversi comandi, ometterla e aggiungere tutti i comandi shell.
Se si avvìa un programma negli scriptlet, qualsiasi richiesta va specificata nella forma "Requires(CONTEXT)
" (ad esempio Requires(post)
).
%pre
, %post
, %preun
e %postun
forniscono l'argomento $1
, che è il numero di pacchetti di questo nome che saranno lasciati nel sistema. Non confrontare per uguaglianza con 2
, controlla invece se sono meggiori o uguali a 2
. Per %pretrans
e %posttrans
, $1
è sempre 0
.
Per esempio se il pacchetto installa un manuale il quale indice deve essere aggiornato con install-info
dal pacchetto info
, innanzitutto non è garantita la presenza del pacchetto info
senza una sua richiesta specifica e poi non si può fallire completamente se install-info
non funziona:
Requires(post): info Requires(preun): info ... %post /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || : %preun if [ $1 = 0 ] ; then /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || : fi
Esiste un altro problema tecnico relativo all'installazione dei manuali. Il comando install-info
aggiornerà la certella delle informazioni, quindi si dovrebbero cancellare le cartelle vuote inutilizzate da %{buildroot} durante la sezione %install
:
rm -f %{buildroot}%{_infodir}/dir
Un'altra abilità simile agli scriptlet è "trigger", avviabile quando altri pacchetti sono installati o disinstallati. Vedere RPM Triggers.
Macro
La macro è un testo nel formato %{string}
. Tipiche macro:
Macro | Estensione tipica | Significato |
---|---|---|
%{_bindir} |
/usr/bin |
Cartella dei binari: dove gli eseguibili vengono solitamente localizzati. |
%{_builddir} |
~/rpmbuild/BUILD |
Cartella per il build: i file sono compilati all'interno della sua sottocartella. Vedere %buildsubdir .
|
%{buildroot} |
~/rpmbuild/BUILDROOT |
Build root: dove i file vengono "installati" durante %install , che li copia dalla sottocartella di %{_builddir} a quella di %{buildroot} . (Storicamente, %{buildroot} era in "/var/tmp/".)
|
%{buildsubdir} |
%{_builddir}/%{name} |
Sottocartella build: interna a %{_builddir} dove i file sono compilati durante %build . E' impostata dopo %autosetup .
|
%{_datadir} |
/usr/share |
Cartella condivisa. |
%{_defaultdocdir} |
/usr/share/doc |
Cartella predefinita della documentazione. |
%{dist} |
.fcNUMBER |
Versione della distro (ad esempio ".fc40 ")
|
%{fedora} |
NUMBER |
Numero di rilascio di Fedora (e.g. "40 ")
|
%{_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:
- Il comando 'SEARCH' di Fedoraproject.org.
- PackagingDrafts
- Special Interest Group (SIG)
- Pagine Wiki con prefisso 'Packaging'
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
Il pacchetto yum-utils contiene molti strumenti.
yumdownloader: scarica il pacchetto sorgente con:
$ yumdownloader --source PACKAGENAME
Il pacchetto auto-buildrequires
ha un paio di buoni strumenti d'aiuto per configurare correttamente la voce BuildRequires. Dopo averlo installato, rimpiazzare "rpmbuild
" con "auto-br-rpmbuild
" e si vedrà automaticamente generata la lista buildrequires.
Potrebbe essere utile RUST (GPL), anche se non crea rpm di adeguata qualità per i repository Fedora. Alien converte pacchetti di diverso formato. Non produce rpm sorgente puliti ma potrebbe essere utile per la conversione di pacchetti esistenti dai quali trarre informazioni preziose.
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.
Linee guida e regole
Una volta creato il proprio pacchetto, bisogna seguire queste regole e linee guida:
- How to join the Fedora Package Collection Maintainers - Descrive il processo per diventare Fedora package maintainer
- Packaging Guidelines
- Package Naming Guidelines
- Dist Tag Guidelines
- Package Review Guidelines
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:
- Releasing Free/Libre/Open Source Software (FLOSS) for Source Installation (sommario veloce)
- GNU Coding Standards release process
- Software Release Practice HOWTO
- Filesystem Hierarchy Standard (FHS)
- Packaging Unix software
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:
- How to build RPM packages on Fedora - ripasso veloce
- Packaging software con RPM (developerWorks) Part 1, Part 2 e Part 3
- Fedora Classroom ha avuto una sessione IRC sul packaging e si può far riferimento al log su https://fedoraproject.org/wiki/Building_RPM_packages_%2820090405%29
- Manuale Fedora Packager
- When Sally met Eddie - Un semplice testo con pochi dettagli
- Maximum RPM Book - Molte informazioni complete, ma in alcuni casi obsolete
- RPM Guide, section on creating RPMs - Ha parecchie buone informazioni leggermente più aggiornate, ma è una bozza
- Guida per sviluppatori, sezione building RPM
- Creating RPMS slides da Guru Labs
- La lotta, il mio primo tentativo di fare un'introduzione leggibile sull'rpm building.
- RPM Tutorial (Fullhart)
- Cambridge RPM tutorial è una presentazione sulla creazione basilare degli RPM
- [1] RPM HOWTO: RPM al Minimo di Donnie Barnes
- [2] RPM HowTo di Dawson
- SuSE build tutorial - ma su SuSE, non per Fedora. Cross-distribution package HOWTO contiene suggerimenti se si fanno rpm per diverse distribuzioni.
- Mandriva Rpm HowTo (en) (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.
- 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".
- Tutto ciò che bisogna sapere su RPM (più sull'installazione che sulla creazione)
- The rpm.org Wiki ha alcune informazioni utili, come la lista dei problemi conosciuti
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.