Esiste della nuova e interessante documentazione sulla pacchettizzazione:
Se si ha la necessità di creare rapidamente un pacchetto, usare equivs.
Se si preferisce ampliare realmente le proprie conoscenze sulla pacchettizzazione in Debian:
prima leggere l'eccellente introduzione alla pacchettizzazione per Debian
poi leggere l'interessante file PDF incluso nel pacchetto packaging-tutorial
Translation(s): English - Italiano - Brasileiro - 简体中文
Contents
Questo è un approccio pratico all'apprendimento di come creare pacchetti Debian.
La pacchettizzazione per Debian non è così difficile; leggere prima l'introduzione alla pacchettizzazione per Debian.
Se non si trovano le risposte alla proprie domande nelle informazioni di questa pagina, guardare i manuali New Maintainer's Guide e la Debian Policy.
Il capitolo sulla gestione dei pacchetti Debian del manuale Developers Reference contiene molte informazioni utili sulla gestione di tutti i tipi di problemi che si possono incrontrare con apt e dpkg.
Se si desidera creare un pacchetto Debian ufficiale, assicurarsi prima che non sia già stato pacchettizzato.
Se qualcuno sta già lavorando al pacchetto, lo si dovrebbe contattare se si vuole collaborare a creare un pacchetto ufficiale.
Per un modo leggermente più moderno di gestire tutti questi aspetti, guardare git-buildpackage. DA_FARE: riscrivere questa pagina tenendo in considerazione git-buildpackage, invece di quilt, per un'esperienza meno arzigogolata e più familiare.
Compilazione iniziale
Prima di iniziare si dovrebbe essere al corrente di alcuni rischi:
ATTENZIONE
Tutte le operazioni descritte dovrebbero essere preferibilmente fatte in un ambiente chroot per motivi di sicurezza. pbuilder e sbuild sono due ambienti di questo tipo; consultare la loro documentazione.
L'esecuzione di make su un sistema può essere un rischio per la sicurezza! È raccomandato controllare in anticipo che il Makefile non contenga cose strane. Applicazioni oscure o fatte ad hoc potrebbero ricadere in questo caso.
NON eseguire make install, a meno di non essere assolutamente certi che sia sicuro farlo (controllare la sezione «install» del Makefile). Questo è un pericolo per la sicurezza e si può correre il rischio di danneggiare o compromettere il sistema.
Passi da compiere:
- Cercare di compilare il pacchetto, ma non installarlo
- la maggior parte degli insuccessi nella compilazione sono il risultato di dipendenze mancanti (solitamente sono per lo più pacchetti *-dev mancanti)
- annotare ogni nuovo pacchetto che è stato necessario installare per la compilazione
- * potrebbero essere necessari anche alcuni dei pacchetti che erano già installati sul sistema (nota
- objdump -p | grep NEEDED mostrerà proprio le librerie necessarie)
- questi pacchetti verranno inseriti nell'elenco delle dipendenze di compilazione del pacchetto
- annotare i trucchi e le operazioni particolari che sono state necessari per la compilazione (file mancanti, modifiche a file, ecc.) e che dovranno successivamente essere riprodotti nelle regole di compilazione del pacchetto
- il software necessario non sia presente in un altro pacchetto
non ci sia un pacchetto in fase di lavorazione con un (ITP (Intent To Package) pendente)
la propria sicurezza che non sia pacchettizzato sia una sicurezza sicura
Si potrebbero controllare anche altre distribuzioni basate su Debian.
È preferibile creare una gabbia chroot in cui compilare l'applicazione. Ciò riduce i problemi per la sicurezza e gli eventuali danni al sistema; inoltre assicura che qualsiasi cambiamento locale alla macchina non interferisca con la compilazione.
Se la compilazione del pacchetto ha successo, allora significa che si potrebbe aver identificato tutte le dipendenze. Non preoccuparsi, ciò verrà controllato in seguito in un ambiente chroot. Provare l'applicazione in un ambiente chroot (potrebbe essere necessaria la presenza di alcune cose nell'ambiente chroot, per esempio può essere necessario montarvi proc o sys, ecc.). Gli script di installazione difettosi sono purtroppo molto comuni e probabilmente non si vuole a questo punto ancora fare un'installazione di prova. Può essere invece preferibile fare i test su una macchina virtuale qemu in modalità snapshot in cui le modifiche non sono permanenti e si può tenere la propria macchina di sviluppo al sicuro da makefile difettosi o malevoli.
''Debianizzazione''
Dopo la prima compilazione, è arrivato il momento di creare le parti del pacchetto specifiche per Debian.
Debianizzare il pacchetto usando dh_make o uno degli altri strumenti per la pacchettizzazione automatica.
Il file debian/control: aggiungere a the Build-Depends (a volte anche a Build-Depends-Indep) l'elenco dei pacchetti che è necessario siano installati per poter compilare l'applicazione (ricordarsi gli elenchi annotati prima). Si dovrebbero omettere i pacchetti che sono elencati in /usr/share/build-essential/essential-packages-list o /usr/share/build-essential/list e anche qualsiasi pacchetto che è elencato da essi come dipendenza.
Il file debian/rules: se sono stati necessarie delle operazioni particolari, allora:
- automatizzare queste operazioni particolari e le modifiche che è necessario fare mettendole nel file debian/rules in una sezione patch
- assicurarsi che esista una sezione unpatch che inverta tutte la modifiche fatte con l'azione patch
- fare sì che l'azione clean dipenda da quella unpatch
- fare in modo che l'azione build dipenda da quella patch
Revisionare ogni file modello (debian/*.ex). Se il pacchetto ha bisogno di quella funzionalità, allora personalizzare il file secondo le proprie necessità e rinominarlo rimuovendo la parte ".ex".
Cancellare tutti i modelli non necessari. Non preoccuparsi, possono essere ripristinati in qualsiasi momento con "dh_make -a".
Assicurarsi che tutte le directory in cui verranno messi dei file siano elencate nel file debian/dirs senza essere precedute da un carattere «/».
Assicurarsi che i file siano installati nella posizione corretta (in una directory, non nel file system radice). Controllare con attenzione l'azione install del Makefile dell'applicazione. Se l'applicazione usa autoconf e automake, potrebbe essere sufficiente impostare la variabile d'ambiente DESTDIR, ad esempio usando "make DESTDIR=$(CURDIR)/debian/nomepacchetto". (dh_make lo imposterà automaticamente.)
Nota: molto spesso il pacchetto originale installa file in /usr/local. NON INSTALLARE ALCUN FILE IN TALE DIRECTORY.
Compilazione iniziale del pacchetto
DA_FARE: aggiungere annotazioni
Compilare pacchetti Debian
Per essere sicuri che un pacchetto Debian soddisfi tutte le dipendenze di compilazione e non sia influenzato da alcun aspetto specifico dell'ambiente dell'utente, i pacchetti dovrebbero essere compilati in un ambiente chroot. A questo scopo possono essere usati strumenti come pbuilder.
Quando si sta lavorando su un pacchetto, una ricompilazione veloce può essere fatta con 'debuild'. Ma allora tutte le dipendenze di compilazione devono essere soddisfate nell'installazione in cui è compilato il pacchetto. Si possono installare automaticamente tutti i pacchetti necessari usando apt-get build-dep. Un esempio completo di compilazione del pacchetto pippo sarebbe:
$ apt-get source pippo $ cd pippo-0.0.1 $ sudo apt-get build-dep pippo $ debuild -i -us -uc -b
Questo è di solito sufficiente per fare il backport di pacchetti.
Controllare e verificare il pacchetto
Tutti i test in chroot
Perché è una buona idea usare una chroot?
- Sicurezza
- Test
- Nessun rischio di danneggiare il sistema dello sviluppatore
- Si possono identificare facilmente i pacchetti installati in modo sbagliato (ls -lR nella directory radice della chroot prima e dopo la compilazione; diff -u prima.list dopo.list)
Le dipendenze di compilazione mancanti vengono facilmente identificate, evitando perciò seri bug del tipo FTBFS (Fails To Build From Source, compilazione fallita dai sorgenti)
- Il sistema chroot è un sistema Debian puro che appartiene ad un'unica distribuzione (es. Sarge, Etch o Sid se la chroot è stata creata in modo corretto con debootstrap o cdebootstrap)
Controllare il pacchetto
licensecheck -r *
DA_FARE: aggiungere informazioni
Lintian
Verificare tutti i pacchetti con lintian.
lintian pacchetto-versione.changes
Piuparts
Controllare tutti i pacchetti .deb con piuparts.
piuparts pacchettobin-versione.deb
Punti da verificare per ogni pacchetto
- Esiste una pagina man per ogni file eseguibile nel pacchetto? In alcuni casi rari è sensato avere una pagina man per più binari nello stesso pacchetto.
- Ha un file .desktop? (I demoni di solito non ne hanno bisogno)
Se nel pacchetto vi è una quantità considerevole di cose indipendenti dall'architettura, sono pacchettizzate in un pacchetto separato con arch all?
Il pacchetto si compila in modo pulito? Ciò non significa reindirizzare gli errori su /dev/null
- lintian si lamenta a gran voce quando controlla il file .changes?
- Cosa dice piuparts sui file .deb?
- Alcuni controlli automatici:
Questo elenco di controlli è deprecato dato che check-all-the-things lo sostituisce, tranne che per alcuni controlli documentati nel file TODO.
sudo apt-get install lintian lintian4python libcrypt-ssleay-perl libwww-perl cppcheck devscripts pyflakes libperl-critic-perl desktop-file-utils mp3check checkmp3 mp3val fontforge-nox freetype2-demos gettext-lint jlint pngcheck jpeginfo vorbis-tools oggz-tools lacheck fdupes python-magic libxml2-utils similarity-tester moreutils pep8 blhc libconfig-model-perl libconfig-model-dpkg-perl bfbtester elfutils hlint adequate i18nspector epubcheck iwyu python-jpylyzer libb-lint-perl codespell duck export BUILDPATH=/home/foo/path/to/foo-1.2.3 cd $BUILDPATH lintian ../*.changes lintian4py ../*.changes cme check dpkg cme check dpkg-control cme check dpkg-copyright debuild && debuild && debuild uscan --verbose licensecheck --check=. --recursive --copyright . grep -i warn ../*.build blhc --all ../*.build cppcheck -j8 --quiet -f . jlint.sh 2>&1 | fgrep -v 'Verification completed: ' pyflakes . pep8 --ignore W191 . perlcritic -1 . suspicious-source bfbtester -x 10 -a debian/*/bin debian/*/usr/bin debian/*/sbin debian/*/usr/sbin debian/*/usr/games hlint . codespell --quiet-level=3 find -iname \*.sh -print0 | xargs --no-run-if-empty --null -n1 sh -n find -iname \*.sh -print0 | xargs --no-run-if-empty --null -n1 checkbashisms find \( -iname \*.pm -o -iname \*.pl \) -print0 | xargs --no-run-if-empty --null -n1 perl -wc find \( -iname \*.pm -o -iname \*.pl \) -print0 | xargs --no-run-if-empty --null -n1 perl -MO=Lint 2>&1 | grep -v ' syntax OK$' find -iname \*.php\* -print0 | xargs --no-run-if-empty --null -n1 php -l -f find \( -iname \*.c -o -iname \*.cxx -o -iname \*.cpp -o -iname \*.cc -o -iname \*.h -o -iname \*.hpp -o -iname \*.hh -o -iname \*.hxx \) -print0 | xargs --no-run-if-empty --null -n1 include-what-you-use find -iname \*.desktop -print0 | xargs --no-run-if-empty --null -n1 desktop-file-validate find -iname \*.mp3 -print0 | xargs --no-run-if-empty --null mp3check --error-check --anomaly-check find -iname \*.mp3 -print0 | xargs --no-run-if-empty --null checkmp3 find -iname \*.mp3 -print0 | xargs --no-run-if-empty --null mp3val find \( -iname \*.ttf -o -iname \*.otf -o -iname \*.sfd -o -iname \*.pfa -o -iname \*.pfb -o -iname \*.bdf -o -iname \*.pk -o -iname \*.ttc -o -iname \*.pcf \) -print0 | xargs --null --no-run-if-empty --max-args=1 fontlint find \( -iname \*.ttf -o -iname \*.otf \) -print0 | xargs --no-run-if-empty --null -n1 ftvalid find \( -name \*.po -o -name \*.pot \) -print0 | xargs --max-args=1 --no-run-if-empty --null msgfmt --check --check-compatibility --check-accelerators find \( -name \*.po -o -name \*.pot \) -print0 | xargs --no-run-if-empty --null POFileChecker find \( -name \*.po -o -name \*.pot \) -print0 | xargs --no-run-if-empty --null POFileSpell find \( -name \*.mo -o -name \*.po -o -name \*.pot \) -print0 | xargs --no-run-if-empty --null i18nspector find -iname *.png -print0 | xargs --no-run-if-empty --null pngcheck -q find \( -iname \*.jpg -o -iname \*.jpeg \) -print0 | xargs --no-run-if-empty --null jpeginfo --check --quiet | fgrep -v "[OK]" find \( -iname \*.jp2 -o -iname \*.j2k -o -iname \*.jpf -o -iname \*.jpx -o -iname \*.jpm -o -iname \*.mj2 \) | xargs jpylyzer --wrapper | xmllint --format - | egrep 'fileName|isValid' | tr -d \\n | sed 's_</isValidJP2>_&\n_g;s_ *<fileName>__g;s_</fileName> *__g;s_</\?isValidJP2>_ _g;s_False_is an invalid JPEG2000 file_g' | sed '/True *$/d' find \( -iname \*.ogg -o -iname \*.oga -o -iname \*.ogv \) -print0 | xargs --no-run-if-empty --null ogginfo -q | grep -v 'Processing file ' | cat -s find \( -iname \*.ogg -o -iname \*.oga -o -iname \*.ogv \) -print0 | xargs --no-run-if-empty --null oggz-validate find -iname \*.xml -print0 | xargs --no-run-if-empty --null xmllint --noout find -iname \*.tex -print0 | xargs --no-run-if-empty --null lacheck find -iname \*.epub -print0 | xargs --no-run-if-empty --null -n1 epubcheck -quiet | egrep -v '^(Check finished with warnings or errors| *)$' find -iname *.py -print0 | xargs --no-run-if-empty --null grep 'environ *\[.HOME.\]' find -iname \*paypal\*.png -o -iname \*paypal\*.gif -o -iname \*flattr\*.png -iname \*flattr\*.gif find \( -iname \*.png -o -iname \*.gif -o -iname \*.jpg -o -iname \*.jpeg \) -print0 | xargs --no-run-if-empty --null grep -iE 'inkscape|gimp' find ! \( -iname \*.icns -o -iname \*.bmp -o -iname \*.ico -o -iname \*.png -o -iname \*.gif -o -iname \*.jpg -o -iname \*.jpeg -o -iname \*.mo -o -iname \*.gz -o -iname \*.zip -o -iname \*.pdf -o -iname \*.bz2 -o -iname \*.tar -o -iname \*.odt -o -iname \*.docx -o -iname \*.torrent -o -iname \*.pyc -o -iname \*.pyo -o -iname \*.o -o -iname \*.wav -o -iname \*.ttf -o -iname \*.ogg -o -iname \*.oga -o -iname \*.ogv -o -iname \*.xcf -o -iname \*.so -o -iname \*.so.\* -o -iname \*.gmo -o -iname \*.debug -o -iname \*.tga \) -print0 | xargs --no-run-if-empty --null isutf8 find ! -type d | xargs file | grep ': *ELF ' | sed 's/: +*.*//' | xargs --no-run-if-empty eu-elflint --quiet --gnu-ld --strict find -type f -iname \*.gz -print0 | xargs --no-run-if-empty --null gzip --test find -type f -iname \*.bz2 -print0 | xargs --no-run-if-empty --null bzip2 --test find -type f -iname \*.xz -print0 | xargs --no-run-if-empty --null xz --test find \( -type f -iname \*.zip -o -iname \*.jar -o -iname \*.pk3 -o -iname \*.wz \) -print0 | xargs --no-run-if-empty --null unzip -t find -type f -iname \*.lzma -print0 | xargs --no-run-if-empty --null lzma --test find -type f -iname \*.lzo -print0 | xargs --no-run-if-empty --null lzop --test find -type f -iname \*.lz -print0 | xargs --no-run-if-empty --null lzip --test find -type f -iname \*.uu -print0 | xargs --no-run-if-empty --null uudecode -o /dev/null grep -r '/tmp/' . grep -r '/home' . grep -r '/srv' . grep -r '/opt' . grep -r 'PATH' . grep -r 'PERLLIB' . grep -r 'x86_64-linux-gnu' . grep -r 'site-packages' . grep -rC4 'system *(' . grep -rC4 'popen *(' . grep -ri 'fixme' . grep -ri 'todo' . grep -ri 'hack' . fdupes -r . find -type f | sim_text -ipTt 75 | tac | column -t apt-get install $(sed -n 's/^Package: //p' debian/control | tr '\n' ' ') ; debi ; apt-get -f install ; adequate $(sed -n 's/^Package: //p' debian/control | tr '\n' ' ') duck echo TODO: jslint puppet-lint acheck linkchecker ssl-cert-check
Si possono prendere altre idee dallo script check-build nel pacchetto pkg-perl-tools.
Questa pagina è ancora incompleta; l'aggiunta di informazioni è benvenuta; non dimenticare però di usare una forma concisa.
Esempi
- Il pacchetto Oolite è stato creato seguendo questa tecnica (a dire il vero, questa pagina è stata scritta durante le prime fasi di pacchettizzazione di Oolite).
Ci sono esempi interessanti nel file PDF incluso nel pacchetto packaging-tutorial.
CategoryDeveloper | CategoryPackaging | CategoryRedundant: merge with Packaging/Intro