Appendice A. Pacchettizzazione avanzata

# Appendice A. Pacchettizzazione avanzata

È disponibile la riscrittura di questo tutorial, con contenuti aggiornati e con esempi più pratici, denominato Guide for Debian Maintainers. Si prega di utilizzare il nuovo tutorial come documento primario.

Sono qui riportati alcuni suggerimenti e riferimenti sulle cose più comuni riguardanti la pacchettizzazione avanzata. Si consiglia vivamente di leggere tutti i riferimenti qui riportati.

Può essere necessario modificare manualmente il file del template del pacchetto generato dal comando dh_make per affrontare gli argomenti trattati in questo capitolo. Il nuovo comando debmake potrebbe trattare questi temi in modo migliore.

## A.1. Librerie condivise

Prima di pacchettizzare una libreria condivisa, si dovrebbero leggere attentamente i seguenti riferimenti principali:

- Manuale delle policy di Debian, 8 "Shared libraries"

- Manuale delle policy di Debian, 9.1.1 "File System Structure"

- Manuale delle policy di Debian, 10.2 "Libraries"

Di seguito alcuni semplici suggerimenti per iniziare:

- Le librerie condivise sono file oggetto ELF che contengono del codice compilato.

- Le librerie condivise sono distribuite come file `*.so`. (Né come file `*.a` né come file `*.la`)

- Le librerie condivise sono utilizzate principalmente per condividere codice tra più eseguibili, utilizzando il sistema ld.

- Le librerie condivise sono a volte utilizzate per fornire plugin a più di un file eseguibile con il sistema dlopen.

- Le librerie condivise esportano i symbols che rappresentano gli oggetti compilati, come le variabili, le funzioni e le classi; e consentono l'accesso ad essi dagli eseguibili collegati.

- Il SONAME di una libreria condivisa `lib`foo`.so`.`1`: `objdump -p lib`foo`.so.`1` | grep SONAME` [87]

- Il SONAME di una libreria condivisa di solito corrisponde al nome del file della libreria (ma non sempre).

- Il SONAME delle librerie condivise collegate a ``/usr/bin/foo``: `objdump -p `/usr/bin/foo` | grep NEEDED` [88]

- `lib`foo``1``: il pacchetto libreria per la libreria condivisa `lib`foo`.so.`1`` con la versione SONAME ABI `1`.[89]

- Gli script dei maintainer riguardanti i pacchetti libreria devono richiamare ldconfig in circostanze specifiche per creare i necessari collegamenti simbolici per SONAME.[90]

- `lib`foo``1`-dbg`: i pacchetti di simboli di debugging che contengono i simboli di debugging per il pacchetto della libreria condivisa `lib`foo``1``.

- `lib`foo`-dev`: il pacchetto di sviluppo che contiene i file header etc, per la libreria condivisa `lib`foo`.so.`1``.[91]

- Un pacchetto Debian, di norma, non deve contenere file di archivi Libtool `*.la`.[92]

- Un pacchetto Debian, di norma, non deve usare RPATH.[93]

- Anche se un po' datato, ed è solo un riferimento secondario, Debian Library Packaging Guide può ancora essere utile.

## A.2. Gestire `debian/`package`.symbols`

Quando si pacchettizza una libreria condivisa, si deve creare il file `debian/`package`.symbols` per gestire la versione minima associata ad ogni simbolo per le modifiche ABI compatibili con le versioni precedenti, utilizzando lo stesso SONAME della libreria per lo stesso nome del pacchetto della libreria condivisa.[94] Si dovrebbero leggere, con attenzione, i seguenti riferimenti:

- Manuale delle policy di Debian, 8.6.3 "The symbols system"[95]

- dh_makeshlibs(1)

- dpkg-gensymbols(1)

- dpkg-shlibdeps(1)

- deb-symbols(5)

Di seguito un esempio di massima, per creare il pacchetto `libfoo1` alla versione originale (upstream) `1.3` con il file `debian/libfoo1.symbols` corretto:

- Preparare lo scheletro dell'albero del sorgente debianizzato utilizzando il file originale `libfoo-1.3.tar.gz`.

  - Se è il primo pacchetto per `libfoo1`, bisogna creare il file vuoto `debian/libfoo1.symbols`.

  - Se la versione originale (upstream) precedente `1.2` è stata pacchettizzata come `libfoo1` con il file `debian/libfoo1.symbols` nei propri sorgenti del pacchetto, lo si utilizzi.

  - Se la versione originale (upstream) precedente `1.2` non è stata pacchettizzata con il file `debian/libfoo1.symbols`, è necessario creare il file `symbols` per tutti i pacchetti binari disponibili con lo stesso nome del pacchetto della libreria condivisa che contiene lo stesso SONAME della libreria, ad esempio, le versioni `1.1-1` e `1.2-1`. [96]

        $ dpkg-deb -x libfoo1_1.1-1.deb libfoo1_1.1-1
        $ dpkg-deb -x libfoo1_1.2-1.deb libfoo1_1.2-1
        $ : > symbols
        $ dpkg-gensymbols -v1.1 -plibfoo1 -Plibfoo1_1.1-1 -Osymbols
        $ dpkg-gensymbols -v1.2 -plibfoo1 -Plibfoo1_1.2-1 -Osymbols

- È possibile provare a costruire l'albero dei sorgenti utilizzando dei programmi come debuild e pdebuild. (Se questo non riesce a causa della mancanza di simboli, ecc, ci sono stati dei cambiamenti ABI incompatibili con le versioni precedenti, che richiedono di cambiare il nome del pacchetto della libreria condivisa a qualcosa di simile `libfoo1a` e si dovrebbe ricominciare di nuovo da capo.)

      $ cd libfoo-1.3
      $ debuild
      ...
      dpkg-gensymbols: warning: some new symbols appeared in the symbols file: ...
       see diff output below
      --- debian/libfoo1.symbols (libfoo1_1.3-1_amd64)
      +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
      @@ -127,6 +127,7 @@
        foo_get_name@Base 1.1
        foo_get_longname@Base 1.2
        foo_get_type@Base 1.1
      + foo_get_longtype@Base 1.3-1
        foo_get_symbol@Base 1.1
        foo_get_rank@Base 1.1
        foo_new@Base 1.1
      ...

- Se si vede il diff stampato da dpkg-gensymbols qui sopra, bisogna estrarre i file `symbols` aggiornati correttamente dal pacchetto binario generato dalla libreria condivisa. [97]

      $ cd ..
      $ dpkg-deb -R  libfoo1_1.3_amd64.deb libfoo1-tmp
      $ sed -e 's/1\.3-1/1\.3/' libfoo1-tmp/DEBIAN/symbols \
              >libfoo-1.3/debian/libfoo1.symbols

- Costruire la release dei pacchetti con programmi come debuild e pdebuild.

      $ cd libfoo-1.3
      $ debuild -- clean
      $ debuild
      ...

In aggiunta agli esempi sopra riportati, è necessario controllare ulteriormente la compatibilità ABI e cambiare le versioni di qualche simbolo manualmente come richiesto. [98]

Anche se è solo un riferimento secondario,, Debian wiki UsingSymbolsFiles e i suoi collegamenti possono essere utili.

## A.3. Multiarch

La funzionalità multiarch introdotta in Debian wheezy integra il supporto per l'installazione dei pacchetti binari cross-architettura (in particolare `i386`<->`amd64`, ma anche altre combinazioni) in `dpkg` e `apt`. Si consiglia di leggere attentamente i seguenti riferimenti:

- Ubuntu wiki MultiarchSpec (upstream)

- Debian wiki Multiarch/Implementation (Debian situation)

Esso utilizza la tripletta come `i386-linux-gnu` e `x86_64-linux-gnu` per il percorso d'installazione delle librerie condivise. La tripletta del percorso reale è impostata con il valore dinamico `$(DEB_HOST_MULTIARCH)` da dpkg-architecture(1) per ogni costruzione. Ad esempio, il percorso per installare le librerie multiarch viene modificato come segue.[99]

Vecchio percorso | percorso i386 multiarch | percorso amd64 multiarch
--- | --- | ---
`/lib/` | `/lib/i386-linux-gnu/` | `/lib/x86_64-linux-gnu/`
`/usr/lib/` | `/usr/lib/i386-linux-gnu/` | `/usr/lib/x86_64-linux-gnu/`

Qui di seguito alcuni esempi tipici di pacchetti multiarch divisi per scenario:

- sorgente di libreria `lib`foo`-1.tar.gz`

- sorgente di programma ``bar`-1.tar.gz` scritto con un linguaggio compilato

- sorgente di programma ``baz`-1.tar.gz` scritto con un linguaggio interpretato

Pacchetto | Architettura: | Multi-Arch: | Contenuto del pacchetto
--- | --- | --- | ---
`lib`foo``1`` | qualsiasi | uguale | la libreria condivisa, co-installabile
`lib`foo``1`-dbg` | qualsiasi | uguale | i simboli di debug della libreira condivisa, co-installabile
`lib`foo`-dev` | qualsiasi | uguale | i file di header, ecc, della libreira condivisa, co-installabile
`lib`foo`-tools` | qualsiasi | straniero | il programma di supporto run-time, non co-installabile
`lib`foo`-doc` | tutti | straniero | i file di documentazione della libreria condivisa
``bar`` | qualsiasi | straniero | i file del programma compilato, non co-installabile
``bar`-doc` | tutti | straniero | i file di documentazione del programma
``baz`` | tutti | straniero | i file del programma interpretato

Si prega di notare che il pacchetto di sviluppo dovrebbe contenere un link simbolico per la libreria condivisa associata senza un numero di versione. Ad es.: `/usr/lib/x86_64-linux-gnu/libfoo.so` -> `libfoo.so.1`

## A.4. Costruzione del pacchetto della libreria condivisa

Si può costruire il pacchetto Debian delle libreria, abilitando il supporto multiarch utilizzando dh(1) come di seguito:

- Aggiornare `debian/control`.

  - Aggiungere `Build-Depends: debhelper (>=10)` per la sezione del sorgente del pacchetto.

  - Aggiungere `Pre-Depends: ${misc:Pre-Depends}` per ogni pacchetto binario di una libreria condivisa.

  - Aggiungere `Multi-Arch:` per ogni sezione del pacchetto binario.

- Impostare `debian/compat` a "10".

- Regolare il percorso dal normale `/usr/lib/` a quello multiarch `/usr/lib/$(DEB_HOST_MULTIARCH)/` per tutti gli script di pacchettizzazione.

  - Invocare `DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)` nel file `debian/rules` per impostare la variabile `DEB_HOST_MULTIARCH`.

  - Sostituire `/usr/lib/` con `/usr/lib/$(DEB_HOST_MULTIARCH)/` nel file `debian/rules`.

  - Se `./configure` viene utilizzato nella parte target di `override_dh_auto_configure` in `debian/rules`, ci si assicuri di sostituirlo con `dh_auto_configure --` . [100]

  - Sostituire tutte le occorrenze di `/usr/lib/` con `/usr/lib/*/` nei file `debian/`foo`.install`.

  - Genera dinamicamente dei file come `debian/`foo`.links` da `debian/`foo`.links.in` aggiungendo un script al target di `override_dh_auto_configure` in `debian/rules`.

        override_dh_auto_configure:
                dh_auto_configure
                sed 's/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/g' \
                        debian/foo.links.in > debian/foo.links

Ci si assicuri di verificare che il pacchetto di libreria condivisa contenga solo i file attesi, e che il pacchetto -dev continui a funzionare.

Tutti i file installati contemporaneamente come pacchetto multiarch con lo stesso percorso del file devono avere esattamente lo stesso contenuto. È necessario prestare attenzione alle differenze generate dall'ordine dei byte nei dati e dall'algoritmo di compressione.

## A.5. Pacchetto nativo Debian

Se il pacchetto è mantenuto solo per Debian o per uso locale, il suo sorgente potrebbe contenere tutti i file in `debian/*`. In questo caso, ci sono 2 modi per pacchettizzarlo.

È possibile creare l'archivio originale escludendo i file in `debian/*` e pacchettizandolo come pacchetto Debian non nativo, come descritto in Sezione 2.1, «Flusso di lavoro per la costruzione dei pacchetti Debian». Questo è il metodo normale che alcune persone incoraggiano ad utilizzare.

L'alternativa è utilizzare lo stesso metodo usato dai pacchetti Debian nativi.

- Creare un pacchetto sorgente nativo di Debian nel formato `3.0 (native)` usando un singolo file tar compresso che include tutti i file.

  - ``pacchetto`_`versione`.tar.gz`
  - ``pacchetto`_`versione`.dsc`

- Costruire pacchetti binari Debian dal pacchetto sorgente nativo di Debian.

  - ``pacchetto`_`versione`_`arch`.deb`

Per esempio, se si hanno i file sorgenti in `~/mypackage-1.0` senza i file `debian/*`, si può creare un pacchetto nativo Debian, utilizzando il comando dh_make come segue:

    $ cd ~/mypackage-1.0
    $ dh_make --native

La directory `debian` e il suo contenuto, sono creati proprio come Sezione 2.8, «Il primo pacchetto non nativo per Debian». Questo non crea un archivio poiché si tratta di un pacchetto Debian nativo. Questa è l'unica differenza. Il resto delle attività di pacchettizzazione sono praticamente le stesse.

Dopo l'esecuzione del comando dpkg-buildpackage, si possono vedere i seguenti file nella directory principale:

- `mypackage_1.0.tar.gz`

  Questo è l'archivio del codice sorgente creato dalla directory `mypackage-1.0` dal comando dpkg-source. (Il suffisso non è `orig.tar.gz`.)

- `mypackage_1.0.dsc`

  Questo è un sommario del contenuto del codice sorgente, come per i pacchetti non-nativi Debian. (non c'è revisione Debian.)

- `mypackage_1.0_i386.deb`

  Questo è il pacchetto binario completo, come per i pacchetti non-nativi Debian. (non c'è revisione Debian.)

- `mypackage_1.0_i386.changes`

  Questo file descrive tutte le modifiche apportate nella versione attuale del pacchetto, come per i pacchetti Debian non-nativi. (non c'è revisione Debian.)

[87] In alternativa: `readelf -d lib`foo`.so.`1` | grep SONAME`

[88] In alternativa: `readelf -d lib`foo`.so.`1` | grep NEEDED`

[89] See Manuale delle policy di Debian, 8.1 "Run-time shared libraries".

[90] See Manuale delle policy di Debian, 8.1.1 "ldconfig".

[91] See Manuale delle policy di Debian, 8.3 "Static libraries" e Manuale delle policy di Debian, 8.4 "Development files".

[92] Si veda Debian wiki ReleaseGoals/LAFileRemoval.

[93] Si veda Debian wiki RpathIssue.

[94] Le modifiche ABI incompatibili con le versioni precedenti, normalmente rendono necessario aggiornare il SONAME della libreria e il nome del pacchetto della libreria condivisa a quelli nuovi.

[95] Per le librerie C++ e per gli altri casi in cui il tracciamento dei singoli simboli è troppo difficile, si consulti invece Manuale delle policy di Debian, 8.6.4 "The shlibs system", instead.

[96] Tutte la versioni precedenti del pacchetto Debian packages sono disponibili su http://snapshot.debian.org/. La revisione Debian viene eliminata dalla versione per rendere più facile il backport del pacchetto: `1.1` << `1.1-1~bpo70+1` << `1.1-1` and `1.2` << `1.2-1~bpo70+1` << `1.2-1`

[97] La revisione Debian viene eliminata dalla versione per rendere più facile il backport del pacchetto: `1.3` << `1.3-1~bpo70+1` << `1.3-1`

[98] Si veda Manuale delle policy di Debian, 8.6.2 "Shared library ABI changes".

[99] Vecchi percorsi di libreria, per scopi speciali, come `/lib32/` and `/lib64/` non sono più utilizzati.

[100] In alternativa, si possono aggiungere gli argomenti `--libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)` e `--libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)` a `./configure`. Si noti che `--libexecdir` indica il percorso predefinito d'installazione dei programmi eseguibili gestiti da altri programmi e non dagli utenti. Il percorso predefinito di Autotools è `/usr/libexec/` mentre quello di Debian è `/usr/lib/`.

Capitolo 9. Caricamento del pacchetto |  |