Traduzioni: English - Español - Italiano - Português (Brasil) - Русский



Introduzione

Questo tutorial è basato su un Evento "Build it" di Debian Women tenuto da Margarita Manterola (in collaborazione con il progetto OpenHatch) il 07-maggio-2011

Questo tutorial tratta di come prendere un pacchetto esistente, ricompilarlo applicandovi delle modifiche e preparare tali modifiche in modo da poterle inviare come patch per un bug.

È anche utile anche se si desidera ricompilare una nuova versione di un pacchetto da unstable o testing nel proprio sistema stable per un uso personale o per caricarlo nel repository stable backports ufficiale.

Questo tutorial è ora disponibile come video dall'istanza di Peertube di Debian in inglese e malayalam

Requisiti

Per questo tutorial sono richieste molto poche conoscenze pregresse, ma non si deve aver paura della riga di comando :-)

Requisiti tecnici

Ricordarsi di eseguire:

   sudo apt-get install build-essential fakeroot devscripts

Configurare APT

Una volta che sono stati installati i pacchetti necessari, la cosa successiva da fare è assicurarsi di avere configurato sulla propria macchina alcuni repository per i sorgenti.

Aprire il file /etc/apt/sources.list e controllare che siano presenti una o più righe che iniziano con deb-src.

  • deb-src http://deb.debian.org/debian unstable main

Questa riga è necessaria per poter lavorare con i pacchetti sorgenti.

Se non c'è alcuna riga deb-src, è necessario aggiungerne almeno una. Ciò viene solitamente fatto copiando una delle righe deb esistenti e modificandola in deb-src. Lo si può fare usando un editor con i privilegi di amministratore (sudo gedit, sudo kate o sudo vim) aggiungendo questa riga:

Solitamente è una buona idea usare unstable come repository, dato che così si lavorera con la versione più recente del pacchetto, ma se si vuole modificare un pacchetto così come è presente in stable o testing si può usare allo stesso modo una di quelle distribuzioni.

Se si usa stable/testing/quello-che-è come distribuzione in uso, ottenere i sorgenti da unstable non ha effetto su di essa.

Una volta aggiunta la riga, è necessario eseguire

   sudo apt-get update

per aggiornare l'elenco dei pacchetti disponibili per l'installazione.

Creare la directory di lavoro

Una volta aggiunto l'URL per i sorgenti ai propri repository apt, si è in grado di ottenere i sorgenti di qualsiasi pacchetto Debian si desideri.

In questo specifico tutorial, verranno scaricati i sorgenti di un pacchetto a cui verrà fatta una piccola modifica in modo da farlo funzionare meglio.

È sempre una buona idea avere una directory dedicata a lavorare sul software sorgente, separata dalle altre directory usate per altri scopi. In caso non ce ne sia una già presente, è suggerita la creazione di una directory src con al suo interno un'altra chiamata debian:

   mkdir -p src/debian/; cd src/debian

All'interno di questa directory verranno messi i sorgenti del pacchetto su cui si lavorerà.

Scegliere il pacchetto

Nota: le istruzioni per node-pretty-ms sono più recenti, quindi l'esempio con fdupes in seguito può essere non considerato (viene mantenuto solamente come informazione storica).

Esempio 1: node-pretty-ms

In questo esempi si userà un pacchetto chiamato node-pretty-ms, una libreria per stampare l'orario in forma intellegibile.

Esempio 2: fdupes

In questo esempio verrà usato un pacchetto chiamato fdupes, uno strumento per rilevare file duplicati, e verrà risolto il bug Debian #585426.

Si dovrebbe installare il pacchetto (o controllare se è installato e aggiornato alla versione più recente) prima di procedere, dato che sarà necessario avere tutte le dipendenze soddisfatte quando si installerà quello modificato.

Se fdupes non è installato, lo si può installare usando:

   sudo apt-get install fdupes

Controllare che il bug sia ancora presente; lo si può fare eseguendo

   fdupes --help

e controllando che la seconda riga delle informazioni per l'opzione --debug continui a non avere alcun senso.

La pacchettizzazione

Ottenere il pacchetto sorgente

Metodo 1: apt source

Per poter ottenere i sorgenti di qualsiasi pacchetto, ciò che si deve fare è andare nella directory che si è scelta (src/debian in questo esempio) ed eseguire (come utente normale):

Esempio 1: node-pretty-ms

   apt-get source node-pretty-ms

Esempio 2: fdupes

   apt-get source fdupes

Metodo 2: dget

Si può anche trovare il collegamento al file .dsc da https://tracker.debian.org (o per versioni più vecchie da https://snapshot.debian.org) e usare il comando dget per scaricare i sorgenti.

Esempio 1: node-pretty-ms

   dget https://deb.debian.org/debian/pool/main/n/node-pretty-ms/node-pretty-ms_7.0.1-1.dsc

Esempio 2: fdupes

 dget http://snapshot.debian.org/archive/debian/20100529T162939Z/pool/main/f/fdupes/fdupes_1.50-PR2-3.dsc

Sono in questo modo stati scaricati 3 file (1. .dsc, 2. .orig.tar.*, 3. .diff.gz o .debian.tar.*), che compongono il pacchetto sorgente Debian.

Una volta scaricato il pacchetto, si può controllare la directory in cui si è (digitando ls), e si scoprirà che oltre ai 3 file scaricati si avrà anche una directory chiamata node-pretty-ms-7.0.1 o fdupes-1.50-PR2. È la directory dei sorgenti/i sorgenti spacchettati del pacchetto Debian.

Notare: nel caso che l'estrazione del file .dsc fallisca con un errore simile a

dscverify: node-pretty-ms_7.0.1-1.dsc failed signature check:
gpg: no valid OpenPGP data found.
gpg: the signature could not be verified.
Please remember that the signature file (.sig or .asc)
should be the first file given on the command line.
Validation FAILED!!

allora si può estrarre manualmente il file .dsc con

  dpkg-source -x node-pretty-ms_7.0.1-1.dsc

e questo creerà la directory descritta sopra.

Per entrare in tale directory digitare:

Esempio 1: node-pretty-ms

   cd node-pretty-ms-7.0.1

Esempio 2: fdupes

   cd fdupes-1.50-PR2/

Metodo 3: debcheckout/origtargz

Si può anche ottenere il repository dei sorgenti dal sistema di controllo di versioni (per esempio git).

Esempio 1: node-pretty-ms

   debcheckout node-pretty-ms
   cd node-pretty-ms
   origtargz

Esempio 2: fdupes

   debcheckout fdupes
   cd fdupes
   origtargz

Notare: nel caso in cui origtargz falisca con un errore usare gbp export-orig --pristine-tar o gli altri metodi spiegati in precedenza (apt source o dget).

Controllando il contenuto di questa directory (digitando nuovamente ls), si vedono parecchi file di vario tipo ed una directory debian.

Ogni pacchetto Debian (o derivato da Debian) include una directory debian in cui vengono archiviate tutte le informazioni relative al pacchetto Debian. Tutto ciò che è al di fuori di quella directory, è codice originale a monte, cioè il codice originale rilasciato di chiunque abbia programmato il software.

Spostarsi nella directory debian digitando

   cd debian

Questa è la directory che il manutentore del pacchetto ha aggiunto al codice sorgente per creare il pacchetto.

In essa di solito si trovano molti file relativi alla versione Debian del programma, patch specifiche per Debian, pagine man, documentazione e così via. In questa occasione non ci soffermiamo oltre su questi file; guardare il suo contenuto usando ls.

Ricordarsi che

Spostarsi indietro di una directory, usando

   cd ..

Si dovrebbe essere di nuovo in node-pretty-ms-7.0.1 o fdupes-1.50-PR2, la directory principale del codice sorgente.

Ottenere le dipendenze di compilazione

Per quasi ogni programma, per poterlo compilare è necessaria l'installazione di alcune dipendenze. Le dipendenze sono i programmi o le librerie necessari per compilare il programma in questione. Solitamente si tratta di svariati pacchetti che finiscono in -dev, ma possono essere comprese anche altre cose, come automake o gcc, a seconda di quanti strumenti di sviluppo sono già stati installati sulla macchina.

apt fornisce un metodo per installare facilmente tutte le dipendenze necessarie:

Esempio 1: node-pretty-ms

   sudo apt build-dep node-pretty-ms

Esempio 2: fdupes

   sudo apt-get build-dep fdupes

Una volta scaricati questi strumenti, si è pronti per compilare il pacchetto.

Ricompilare senza modifiche

Prima di fare una qualunque modifica al codice, compilare il pacchetto come è adesso, solo per assicurarsi che si compila e si installa in modo corretto. Eseguire:

   debuild -b -uc -us

I parametri aggiuntivi servono per far compilare solamente un pacchetto binario (.deb) e per evitare che venga firmato, dato che al momento non è necessario firmarlo.

Ci vorrà probabilmente un po' di tempo perché l'esecuzione di questo comando venga completata, dato che solitamente prima deve essere eseguito ./configure, poi deve essere compilato il codice sorgente e quindi creato il pacchetto. Di fatto, esegue i comandi che sono elencati nel file debian/rules e si spera termini con un messaggio simile a:

Esempio 1: node-pretty-ms

dpkg-deb: building package 'node-pretty-ms' in '../node-pretty-ms_7.0.1-1_all.deb'.

Esempio 2: fdupes

   dpkg-deb: building package `fdupes' in `../fdupes_1.50-PR2-3_<mia arch>.deb'

localizzato nella lingua di sistema. <mia arch> può essere i386, amd64, a seconda della architettura sulla quale gira la macchina. I pacchetti indipendenti dall'architettura possono essere all.

Una volta che il pacchetto è stato compilato correttamente, il passo successivo è installare questo file con:

Esempio 1: node-pretty-ms

   apt install ../node-pretty-ms_7.0.1-1_all.deb

Le sezioni che seguono si riferiscono solo all'esempio 2.

Esempio 2: fdupes

   sudo dpkg -i ../fdupes_1.50-PR2-3_<mia arch>.deb

Dopo, controllare che il bug sia ancora presente eseguendo

   fdupes --help

Modificare il codice sorgente

Ora, si deve davvero risolvere questo bug.

Qui inizia il divertimento. Quando si cerca di risolvere un bug di un pacchetto, a volte questo è nei sorgenti originali e a volte è correlato al modo in cui il programma è stato pacchettizzato per Debian. Perciò a seconda di dove è il problema si devono modificare file diversi.

In questo caso particolare, il pacchetto usa lo strumento dpatch, uno strumento per gestire patch per il pacchetto, perciò verrà usato tale strumento. Altri pacchetti usano uno strumento diverso, chiamato quilt, per gestire le patch ma non verrà trattato in questo tutorial.

Per creare una nuova patch, è necessario fare quanto segue. Digitare:

   dpatch-edit-patch 80_bts585426_fix_help 70_bts537138_disambiguate_recurse.dpatch

Questo avvierà una nuova shell all'interno di un ambiente speciale, in cui si possono modificare i file e dpatch in seguito si occuperà di ottenere le differenze con l'originale.

Il nome della patch è stato scelto in modo da essere conforme al modello già stabilito dal manutentore.

Ora deve essere modificato il file fdupes.c. Andare alla riga 1066 e cancellarla. La riga dice:

  • printf(" \teach set of duplicates without prompting the user\n");

Ciò può essere fatto con il proprio editor preferito (vi fdupes.c, gedit fdupes.c, kate fdupes.c, ecc.).

Una volta fatto, si deve digitare

   exit

nella console; questo termina l'ambiente speciale che dpatch aveva creato e si ottiene una nuova patch nella directory debian/patches/. Controllare con:

   cat debian/patches/80_bts585426_fix_help.dpatch

Per poter applicare questa patch, è necessario modificare il file debian/patches/00list e aggiungere come ultima riga:

  • 80_bts585426_fix_help

Il file 00list è il file dpatch che elenca tutte le patch che verranno applicate; queste vengono applicate in ordine, da quella nella prima riga a quella nell'ultima.

Prima di ricostruire il pacchetto con questa patch, si deve rendere il proprio pacchetto diverso da quello originale, in modo che in seguito possano essere estratte le differenze così da poterle inviare come patch per il bug. Per fare questo, digitare:

   dch -n

Questo

Ora si sta quindi modificando il file changelog; quello che è necessario inserire in questo file è una qualche descrizione del cambiamento che è stato fatto. Per esempio:

  • Added a patch to fix the --help issue with the --debug option. Closes: #585426".

Farlo nella riga con il carattere * vuoto.

Compilare il pacchetto modificato

Una volta che ciò è stato fatto, è sufficiente ricompilare il pacchetto con lo stesso comando usato prima:

   debuild -b -uc -us

Aggiungere l'opzione -tc se si desiderano ripulire gli elementi generati dalla compilazione.

Nel caso che sia necessario fare il debug del pacchetto compilato, specialmente se si sta cercando di risolvere un problema di Segmentation Fault, può essere utile compilarlo nel modo seguente, in modo che il codice non venga ottimizzato e non siano rimossi i simboli di debug così da rendere più facile il debug.:

   DEB_BUILD_OPTIONS='nostrip noopt debug' dpkg-buildpackage -b -uc -us

Si vede a schermo dell'output della compilazione; di solito non è molto interessante, a meno che non si stia cercando un bug che è correlato alla compilazione stessa del pacchetto. Normalmente l'autrice lascia che proceda mentre va a fare qualcos'altro (ad esempio prendere qualche biscotto per il caffe).

Questa volta il pacchetto creato dovrebbe essere: ../fdupes_1.50-PR2-3.1_<mia arch>.deb, la versione è cambiata perché dch l'ha cambiata per conto dell'utente nel changelog (-3.1 invece di -3).

Installare e testare il pacchetto modificato

Installarlo con:

   sudo dpkg -i ../fdupes_1.50-PR2-3.1_<mia arch>.deb

e testarlo per vedere se l'aiuto adesso è corretto. :)

In ogni caso, se ciò che si è fatto ha peggiorato le cose si può sempre tornare alla versione Debian con:

  apt-get install --reinstall fdupes=<versione_precedente>

Creare il pacchetto sorgente

Una volta che un bug è stato risolto, si può volere anche creare il pacchetto sorgente. Ciò significa non solo il file .deb, ma anche gli altri file che sono stati scaricati all'inizio. Ciò viene fatto con:

   debuild -us -uc

I parametri aggiuntivi servono ad evitare che il pacchetto venga firmato, dato che al momento non è necessario.

Se si è creato il pacchetto sorgente, si può andare nella directory precedente con cd .. e controllare che ci siano i file con ls. Si può vedere che ora ci sono più file, inclusi 2 file dsc, uno per il pacchetto originale e uno per quello appena creato.

Inviare i cambiamenti al BTS

Una volta che si è creato il pacchetto sorgente, si possono trovare le differenze tra il proprio pacchetto e quello originale usando debdiff:

   debdiff fdupes_1.50-PR2-3.dsc fdupes_1.50-PR2-3.1.dsc > mio_primo_debdiff.diff

In questo caso particolare, dato che è stato usato lo strumento dpatch, ciò che dovrebbe essere inviato al BTS come patch è il file dpatch che è stato creato, poiché i cambiamenti fatti sono contenuti lì.

Ma se non fosse stato usato dpatch, si potrebbe usare l'output di quel comando debdiff e inviarlo al BTS.

Conclusioni

Questo è tutto, prepararsi per il prossimo pacchetto

Ora che le modifiche a questo pacchetto sono terminate, si può continuare a risolvere bug in altri pacchetti Debian! Questi sono i comandi che è importante ricordare:

   apt-get source il-pacchetto
   apt-get build-dep il-pacchetto
   (...)
   fakeroot debian/rules binary
   dpkg -i il-pacchetto-blabla.deb
   dpkg-buildpackage -us -uc
   debdiff pacchetto-blabla.dsc pacchetto-blabla.1.dsc > un_altro_debdiff.diff

Feedback

L'autrice spera che questo tutorial sia stato gradito, inviarle un feedback se se ne ha voglia, o modificare questo Wiki se si desiderano aggiungere informazioni utili che possono essere state dimenticate.

Domande e risposte

DOMANDA: Il numero 80_ nel nome della patch è un fatto estetico?

RISPOSTA: È fatto in modo da poterle avere in ordine quando le si elenca con ls. L'ordine di applicazione è quello in cui appaiono nel file 00list. Alcuni manutentori scelgono di usare numeri per esse, altri no. Ma quando si crea una patch per un pacchetto si dovrebbe cercare di seguire qualsiasi schema sia stato scelto dal manutentore.

DOMANDA: A proposito dei parametri di dpatch-edit-patch, dove si prendono quei parametri? Sto parlando della roba bts****

RISPOSTA: Il primo è il nome della patch. È stato scelto un nome simile a quelle già esistenti. "bts" sta per "bug tracking system", il numero è quello del bug che si vuole chiudere.

DOMANDA: Come sceglie dch il numero "3.1"?

RISPOSTA: È stato usato dch -n, perché non era eseguito dal manutentore del pacchetto (n sta per non-manutentore). Poi c'è 3.1. Se si fosse stati manutentore, si sarebbe usato dch -i e il programma avrebbe scelto -4.

DOMANDA: Quando si invia una patch al BTS, si deve inviare qualcosa riguardo al changelog?

RISPOSTA: Non necessariamente, ma si può inviare anche quello; dipende dal bug che si sta risolvendo. È anche accettabile l'invio dell'output di debdiff.

Se si sta inviando solamente una patch piccola e semplice, è normale lasciare che sia il manutentore a scrivere il changelog; se invece si tratta di un grande aggiornamento NMU allora, sì, si dovrebbe inviare al BTS il changelog come parte della grande patch.

DOMANDA: Inviare un changelog con un NMU è considerato non educato?

RISPOSTA: Quello che ad alcuni (non a tutti) manutentori non piace è il fatto che qualcuno faccia veramente un NMU. L'invio di una patch al BTS è sempre/always/immer/siempre benvenuto!

DOMANDA: Qual è il modo più veloce/facile per scoprire quale strumento (se c'è) è usato per gestire le patch?

RISPOSTA: Se tra le dipendenze di compilazione è presente quilt o dpatch in debian/control. Oppure se c'è un file debian/README.source.

DOMANDA: Questo flusso di lavoro funziona per tutti i pacchetti?

RISPOSTA: È piuttosto generico. L'unica cosa che potrebbe cambiare è il sistema di gestione delle patch (dpatch/quilt/nessuno). Il resto è fondamentalmente sempre uguale.

Vedere anche