Repository 32bit  Forum
Repository 64bit  Wiki

Creare pacchetti txz per Slackware: differenze tra le versioni

Da Slacky.eu.
(Introduzione)
Riga 1: Riga 1:
[[Category:Packages]]
[[Category:Packages]]
= Introduzione =
= Introduzione =
I pacchetti di cui fa uso Slackware sono archivi compressi in formato *.tgz: si tratta semplicemente di archivi compressi. Se ne guardiamo il contenuto, ci renderemo subito conto che contengono i file da installare in directory identiche a quelle dove andranno collocati nel disco fisso, come se riproducessero al loro interno la destinazione effettiva dei file stessi.
+
I pacchetti di cui fa uso Slackware sono archivi compressi in formato *.txz: si tratta semplicemente di archivi compressi. Se ne guardiamo il contenuto, ci renderemo subito conto che contengono i file da installare in directory identiche a quelle dove andranno collocati nel disco fisso, come se riproducessero al loro interno la destinazione effettiva dei file stessi.
Saper pacchettizzare in *.tgz, dal momento che nel mondo dell'open source sono sempre disponibili i sorgenti, significa poter ricorrere a qualsiasi programma nel formato che ci consente di tener conto della sua installazione nel database di Slackware, e dunque di aggiornare o rimuovere il pacchetto stesso in maniera pulita, con pkgtool o con i comandi correlati da shell, senza lasciare file abbandonati nel disco fisso (del tutto indipendentemente dal fatto che il pacchetto originale, come non spesso avviene, supporti la funzione "uninstall"), e infine di fruire senza difficoltà di strumenti di aggiornamento automatico come Swaret.
+
Saper pacchettizzare in *.txz, dal momento che nel mondo dell'open source sono sempre disponibili i sorgenti, significa poter ricorrere a qualsiasi programma nel formato che ci consente di tener conto della sua installazione nel database di Slackware, e dunque di aggiornare o rimuovere il pacchetto stesso in maniera pulita, con pkgtool o con i comandi correlati da shell, senza lasciare file abbandonati nel disco fisso (del tutto indipendentemente dal fatto che il pacchetto originale, come non spesso avviene, supporti la funzione "uninstall"), e infine di fruire senza difficoltà di strumenti di aggiornamento automatico come Swaret.
Sebbene esistano degli strumenti per creare i *.tgz come checkinstall, la creazione manuale offre alcuni vantaggi: la possibilità di personalizzare il pacchetto per l'architettura del nostro hardware, di abilitare funzioni e plugins che ci servono, di includervi documentazione specifica e altro.
+
Sebbene esistano degli strumenti per creare i *.txz come checkinstall, la creazione manuale offre alcuni vantaggi: la possibilità di personalizzare il pacchetto per l'architettura del nostro hardware, di abilitare funzioni e plugins che ci servono, di includervi documentazione specifica e altro.
La pacchettizzazione in *.tgz è in larga parte meccanica, nel senso che segue alcune regole generali, che funzionano nella maggior parte dei casi. Ciò non toglie che è sempre necessario studiare preliminarmente il pacchetto per capire dove esattamente va installato, con quali opzioni è opportuno configurarlo, se richiede altri pacchetti per poter funzionare (le "dipendenze").
+
La pacchettizzazione in *.txz è in larga parte meccanica, nel senso che segue alcune regole generali, che funzionano nella maggior parte dei casi. Ciò non toglie che è sempre necessario studiare preliminarmente il pacchetto per capire dove esattamente va installato, con quali opzioni è opportuno configurarlo, se richiede altri pacchetti per poter funzionare (le "dipendenze").
 
= Procedura =
= Procedura =

Versione delle 19:16, 25 feb 2010

Indice

Introduzione

I pacchetti di cui fa uso Slackware sono archivi compressi in formato *.txz: si tratta semplicemente di archivi compressi. Se ne guardiamo il contenuto, ci renderemo subito conto che contengono i file da installare in directory identiche a quelle dove andranno collocati nel disco fisso, come se riproducessero al loro interno la destinazione effettiva dei file stessi. Saper pacchettizzare in *.txz, dal momento che nel mondo dell'open source sono sempre disponibili i sorgenti, significa poter ricorrere a qualsiasi programma nel formato che ci consente di tener conto della sua installazione nel database di Slackware, e dunque di aggiornare o rimuovere il pacchetto stesso in maniera pulita, con pkgtool o con i comandi correlati da shell, senza lasciare file abbandonati nel disco fisso (del tutto indipendentemente dal fatto che il pacchetto originale, come non spesso avviene, supporti la funzione "uninstall"), e infine di fruire senza difficoltà di strumenti di aggiornamento automatico come Swaret. Sebbene esistano degli strumenti per creare i *.txz come checkinstall, la creazione manuale offre alcuni vantaggi: la possibilità di personalizzare il pacchetto per l'architettura del nostro hardware, di abilitare funzioni e plugins che ci servono, di includervi documentazione specifica e altro. La pacchettizzazione in *.txz è in larga parte meccanica, nel senso che segue alcune regole generali, che funzionano nella maggior parte dei casi. Ciò non toglie che è sempre necessario studiare preliminarmente il pacchetto per capire dove esattamente va installato, con quali opzioni è opportuno configurarlo, se richiede altri pacchetti per poter funzionare (le "dipendenze").

Procedura

In linea di massima, la procedura da seguire è la seguente:

  1. scompattare il sorgente con tar
  2. sistemare i permessi dei file con chmod
  3. esaminare le opzioni da passare al configure col comando ./configure --help
  4. configurare il pacchetto col comando configure e con le opzioni del caso
  5. costruire il pacchetto col comando make
  6. installare il pacchetto col comando make install
  7. aggiungere la documentazione
  8. strippare i binari con strip
  9. strippare le librerie con strip
  10. comprimere i file man con gzip
  11. comprimere i file info con gzip
  12. ripristinare i permessi corretti della directory /bin con chmod
  13. inserire la descrizione del pacchetto e altri eventuali file informativi
  14. creare il pacchetto con makepkg
  15. cancellare le directory temporanee di lavoro con rm -r.


Creazione Pacchetti

Vediamo ora in dettaglio i vari passaggi.

Scompattare il sorgente con tar

Il sorgente si scompatta da console a seconda del formato, che in genere è tar.gz o tar.bz2, oppure con utilità grafiche come Ark (per KDE) o File Roller (per Gnome) in una directory qualunque. È sempre più opportuno evitare di svolgere questa operazione in directory di programma per non causare eventuali errori di cancellazione e usare una directory creata ad hoc: alcuni la creano in /home o all'interno della directory dei sorgenti (soluzioni entrambe scomode), o ancora in una subdirectory di /tmp. Qui ipotizzeremo, a titolo di esempio, di lavorare nella directory provvisoria /tmp/pkg.

Sistemare i permessi dei file con chmod

Per poter lavorare (alcuni rari pacchetti presentano permessi originali non ortodossi, altri pochi ne presentano di strani, come il nome dell'autore), conferiamo a tutti i file il permessi di root (utente e gruppo, cioè root.root) col comando chown -R root.root /tmp/pkg. Quindi sistemiamo i permessi in modo che risultino secondo la tabella seguente:

Permessi originali | Permessi modificati


       777            |         
       775            |           755   
       555            |   

       664            | 
       666            |           644
       444            |   

Prima di chmodare, verifichiamo naturalmente se ne vale la pena, cioè se effettivamente sono presenti file con quei permessi da modificare. I comandi sono del tipo: find . -perm 775 -exec chmod 755 {} \; find . -perm 664 -exec chmod 644 {} \; (che sono i casi più diffusi) e via dicendo.

Esaminare le opzioni da passare al configure col comando ./configure -help

Il comando ./configure --help è la fonte primaria di informazioni. Esso precisa di solito in quale directory si installa di default il programma, quali sono le opzioni da passare al compilatore e infine quali sono le opzioni specifiche del pacchetto.

Analizziamo a titolo esemplificativo l'output del comando passato al sorgente di Rekall 2.1.

 bash-2.05b$ ./configure --help
`configure' configures this package to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Queste sono le opzioni di base della configurazione, pressoché identicheper tutti i pacchetti. Forniscono alcune informazioni sul pacchetto, e solitamente nella compilazione si può prescindere da esse.

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Queste sono le indicazioni sull'installazione standard del pacchetto. Ci suggeriscono che esso andrà a installarsi in /usr/local e nelle relative subdirectory.

Fine tuning of the installation directories:
  --bindir=DIR           user executables [EPREFIX/bin]
  --sbindir=DIR          system admin executables [EPREFIX/sbin]
  --libexecdir=DIR       program executables [EPREFIX/libexec]
  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
  --libdir=DIR           object code libraries [EPREFIX/lib]
  --includedir=DIR       C header files [PREFIX/include]
  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
  --infodir=DIR          info documentation [PREFIX/info]
  --mandir=DIR           man documentation [PREFIX/man]

Queste indicazioni suggeriscono come modificare le directory di destinazione di file specifici. Ad esempio, in Slackware i file di sistema vanno installati in /etc, e per evitare che finiscano sotto /usr/etc è necessario passare al configure l'opzione --sysconfdir=/etc (sempre che il pacchetto contenga file di questo tipo). Allo stesso modo, file di log ecc vanno collocato in /var/log e non in /usr/var/log. A questo fine, si passa al configure l'opzione --localstatedir=/var. Infine, i vari Window manager vanno collocati in /usr/X11R6. Tutte queste attenzioni non servono solo a produrre la standardizzazione dei pacchetti e di conseguenza l'ordine all'interno del disco fisso. Esse fanno anche sì che gran parte del sistema giri in sola lettura, per garantirne la sicurezza.

Program names:
  --program-prefix=PREFIX            prepend PREFIX to installed program names
  --program-suffix=SUFFIX            append SUFFIX to installed program names
  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  --target=TARGET   configure for building compilers for TARGET [HOST]

Queste indicazioni sono relative all'assegnazione di un prefisso o di un suffisso al nome del programma al momento dell'installazione. Se si passa al configure $ARCH-slackware-linux per specificare il sistema operativo, questo potrebbe generare degli eseguibili con estensione scorretta, come slackware-linux-cups invece, semplicemente, di cups. Le opzioni --program-prefix=PREFIX e --program-suffix=SUFFIX evitano questo errore.

Optional Features:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-debug     Enables Debug-Code
  --disable-dependency-tracking Speeds up one-time builds
  --enable-dependency-tracking  Do not reject slow dependency extractors
  --enable-debug=ARG    enables debug symbols (yes|no|full) default=no
  --disable-debug         disables debug output and debug symbols default=no
  --enable-strict         compiles with strict compiler options (may not work!)
  --enable-warnings       compiles with -Wall and similiar
  --enable-profile        creates profiling infos default=no
  --enable-pch            enables precompiled header support (currently only KCC) default=no
  --enable-final          build size optimized apps (experimental - needs lots of memory)
  --disable-closure       don't delay template instantiation
  --enable-shared=PKGS  build shared libraries default=yes
  --enable-static=PKGS  build static libraries default=no
  --enable-fast-install=PKGS  optimize for fast installation default=yes
  --disable-libtool-lock  avoid locking (might break parallel builds)
  --enable-objprelink     prelink apps using objprelink (experimental only tested on linux/386)
  --enable-embedded       link to Qt-embedded, don't use X
  --enable-qtopia         link to Qt-embedded, link to the Qtopia Environment
  --disable-mt            link to non-threaded Qt (deprecated)
  --enable-kernel-threads Enable the use of the LinuxThreads port on FreeBSD/i386 only.
  --disable-threading     disables threading even if libpthread found

Sono qui elencate le caratteristiche opzionali del pacchetto. Tra quelle più utili e comuni, --disable-debug fa sì che si evitino di ricevere tutti i messaggi di debug, mentre --disable-static impedisce la costruzione di librerie statiche, il che è una soluzione adottabile per la maggior parte dei pacchetti, che in tal modo risulteranno anche più snelli.

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-gnu-ld           assume the C compiler uses GNU ld default=no
  --with-pic              try to use only PIC/non-PIC objects default=use both
  --with-pythondir=pythondir   use python installed in pythondir
  --without-python     Do not compile the Scripter Plugin
  --with-xinerama         enable support for Xinerama
  --with-extra-includes=DIR
                          adds non standard include paths
  --with-extra-libs=DIR   adds non standard library paths
  --with-qt-dir=DIR       where the root of Qt is installed
  --with-qt-includes=DIR  where the Qt includes are.
  --with-qt-libraries=DIR where the Qt library is installed.

Qui si dettaglia che il pacchetto può essere installato abilitando determinate funzioni legate ad altri pacchetti presenti nel sistema. Ad es., l'opzione --with-xinerama fa sì che sia abilitato il supporto per Xinerama. Molti pacchetti consentono di abilitare o meno specifiche utili opzioni, per adattare il pacchetto alle proprie esigenze. Ad esempio, alcune GUI per database consentono di usare vari database (da MySQL a PostgreSQL) a seconda delle opzioni attivate; per certi programmi di posta elettronica, può essere opportuno abilitare ssl con l'opzione --enable-ssl, per altri determinati plugins col comando --enable-plugins e via dicendo. Altre opzioni suggeriscono al programma la presenza di librerie in posizioni non canoniche, che potrebbero sfuggire al controllo automatico.

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
              headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  CXX         C++ compiler command
  CXXFLAGS    C++ compiler flags
  CXXCPP      C++ preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Sono qui elencate le variabili di sistema. L'ottimizzazione del pacchetto prevede di adottare sempre CFLAGS, cioè di indicare per quale tipo di ambiente deve lavorare i compilatore. I parametri di ottimizzazione da passare al compilatore che prendono per l'appunto il nome di FLAGS, dipendono anche dall'architettura per cui vogliamo configurare il pacchetto (come Pentium o Athlon). Se non viene precisato alcun parametro, gcc cerca di minimizzare il tempo di compilazione e lo spazio richiesto in memoria (chiamato "costo di compilazione", a scapito dell'efficienza del pacchetto. La situazione cambia se al compilatore vengono passati dei parametri definiti. Quelli classici (attualmente ne esistono di nuovi e più spinti, ma tutti ancora a livello sperimentale) sono -O (equivalente di -O1. Attenzione: si tratta della lettera O, non del numero zero) riduce le dimensioni del pacchetto; -O2 cerca invece di migliorare la dimensione del compilato; infine -O3 migliora ulteriormente la velocità del compilato a scapito delle dimensioni (per cui ne produce un lieve incremento). Per compatibilità, nei pacchetti standard si adotta -O2. Quindi si precisa l'ottimizzazione per il processore e la CPU. Attualmente i pacchatti ufficiale di Slackware sono costruiti per i486, per cui avremo i seguenti due valori: -march=i486 e -mcpu=i686. Pacchetti costruiti per uso personale possono anche avere ottimizzazioni più spinte, ad esempio i FLAGS -O3 e -march=i686 (che non funzioneranno dunque su un i486). Le versioni più recenti di gcc adottano -mtune in luogo di -mcpu, dichiarato ormai deprecato. In ogni caso, si può trovare l'elenco esaustivo delle opzioni al seguente indirizzo: http://gcc.gnu.org/onlinedocs.

Configurare il pacchetto col comando configure e con le opzioni del caso

Individuate tutte le opzioni che ci interessano, passiamo effettivamente al configure. In primo luogo le variabili di ambiente, quindi il prefix, infine le caratteristiche opzionali. In secondo luogo dobbiamo passare al configure la directory dove installare il pacchetto. Come già abbiamo bisto, a differenza di altre distribuzioni Linux, in Slackware i pacchetti aggiuntivi in genere non sono collocati in /usr/local, ma in /usr. Fanno eccezione i pacchetti che girano sotto KDE, che andranno invece collocati in /opt/kde. Per suggerire la directory al configure si usa il comando --prefix=/usr, oppure, nel secondo caso, --prefix=/opt/kde. Il comando risulterà pertanto qualcosa di simile a:

CFLAGS="-O2 -march=i486 -mcpu=i686" ./configure --prefix=/usr --disable-debug

oppure

CFLAGS="-O2 -march=i486 -mcpu=i686" ./configure --prefix=/opt/kde --disable-debug --with-jack --with-ladspa --with-xinerama --with-alsa.

Costruire il pacchetto col comando make

Il pacchetto si costruisce semplicemente col classico make, a cui in certi casi non frequentissimi va fatto seguire il make depend (ma in genere è la procedura stessa che avverte di ciò).

Installare il pacchetto col comando make install

Dobbiamo ora installare il pacchetto. Tuttavia noi non lo vogliamo installare effettivamente nel sistema per renderlo operativo, ma effettuarne solo un'installazione provvisoria per costruirlo in modo indipendente. A questo fine dobbiamo suggerire al make install di installarlo all'interno di una directory temporanea di lavoro, che abbiamo convenzionalmente chiamato /pkg e già creato col comando mkdir -p /tmp/pkg. Come sappiamo, la struttura di questo pacchetto deve riprodurre la struttura che poi avrà il pacchetto. In altre parole, se determinati file andranno a collocarsi in /usr/lib, adesso dobbiamo fare in modo che vadano a finire in /pkg/usr/lib ecc. Il comando da impartire per redirigerli è allora:

make install DESTDIR=/dir/dir (ad es.,  DESTDIR=/tmp/pkg)

oppure

make install prefix=/dir/dir (ad es.,  prefix=/tmp/pkg/usr).

Nei programmi più recenti (i Makefile generati con automake e autoconf) l'opzione DESTDIR ha soppiantato l'ormai deprecata prefix (che, se adottata, produce errori di installazione). Ciò non toglie che un elevato numero di pacchetti la supporti ancora. È da notare che se si adotta DESTDIR va indicata solo la directory principale di lavoro (/pkg), mentre se si adotta prefix va indicata anche la subdirectory (/pkg/usr). In ogni caso, per verificare quale delle due opzioni adottare è sufficiente, dopo aver eseguito il make, dare il comando grep -R destdir Makefile oppure cercare la stringa "destdir" o "dc_destdir" nel Makefile con un editor quasiasi di testo.

Aggiungere la documentazione

Nella directory principale del sorgente è presente un certo numero di file di documentazione (file come AUTHORS, COPYING, INSTALL, README, THANX, TODO ecc.). Questa documentazione va copiata nella directory di default della documentazione, e cioè in /usr/doc/nome_pacchetto-versione. Al momento, naturalmente, la copieremo nella nostra directory di lavoro, e cioè /pkg/usr/doc/nome_pacchetto-versione, che avremo creato apposta col comando mkdir -p /tmp/pkg/usr/doc/nome_pacchetto-versione.

Strippare i binari con strip

Per ridurre le dimensioni del pacchetto vanno strippati i file eseguibili. Essi possono essere cercati manualmente e quindi (posto che siano un /usr/bin) strippati con un comando del tipo:

strip --strip-unneeded /usr/lib/nome_file

o, in alternativa:

strip -g /usr/bin/nome_file

oppure l'operazione può essere affidata al comando

find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null

Lo strip non solo riduce le dimensioni dei binari (e successivamente delle librerie) rendendo il programma più veloce e riducendo l'uso della memoria, ma contribuisce anche a rendere più sicuri i binari: eliminando i simboli di debug dai file, essi risultano diversi da quello normalmente usati in altre distribuzioni e meno soggetti a un possibile exploit. C'è una sola controindicazione, che però riguarda più che altro i programmatori: in caso di crash, il programma non darà indicazioni utili alla soluzione del problema.

Strippare le librerie con strip

Per lo stesso motivo vanno strippare le librerie (sebbene alcuni sostengano che questa operazione può creare dei problemi a certi pacchetti), o manualmente col comando (posto che siano in /usr/lib)

strip --strip-unneeded /usr/lib/nome_libreria

o, in alternativa:

strip -g /usr/lib/nome_libreria

oppure col comando

find . | xargs file | grep "shared object" | grep ELF | cut -f1 -d : | xargs strip --strip-unneeded 2> /dev/null

Nota La stessa procedura può essere adottata anche per strippare evantuali file di tipo current o archive. In questo caso il comando sarà:

find . | xargs file | grep "current ar archive" | cut -f 1 -d > : | xargs strip -g 2> /dev/null

I file di tipo "current ar archive" sono generalmente quelli con estensione *.a, laddove i file di tipo shared object (librerie) sono generalmente quelli con estensione *.so.

Comprimere i file man con gzip

Sempre per motivi di spazio, i file man, qualora presenti, vanno compressi con gzip, a cui si può passare anche l'opzione -9 per raggiungere le dimensioni più ridotte possibili. Il programma man le scompatta al volo durante la lettura. Il comando allora sarà: gzip -9 /work/usr/man/* o gzip -9 /work/usr/man/*/* (nel non infrequente caso che i file di man siano contenuti in sub-subdirectory).

Comprimere i file info con gzip

Ancora una volta per ridurre al massimo le dimensioni del pacchetto, si comprimono sempre con gzip i file info, qualora presenti. Il comando allora sarà:

gzip -9 /work/usr/info/*

Infine si rimuove il file "dir", spesso presente, che, in quanto contiene semplicemente l'elenco dei file del pacchetto, è considerato inutile.

Ripristinare i permessi corretti della dir /bin con chmod

Il "pacchetto perfetto alla Slack" vuole che i binari (contenuti in /usr/bin o /sbin) siano di proprietà di root.bin. Questi permessi vanno ripristinati (dal momento che, come dal n. 1, sappiamo che attualmente sono invee di root.root) col comando:

chown -R root.bin /pkg/usr/bin.

Inserire la descrizione del pacchetto e altri eventuali file informativi

I pacchetti per Slackware contengono un file di solo testo chiamato di default "slack-desc", contenente una breve descrizione del pacchetto stesso. Esso presenta una formattazione standard. Si tratta obbligatoriamente di 11 righe che iniziano tutte col nome del pacchetto (senza alcuna modifica, o il file non risulterà leggibile), precedute da un delimitatore del testo che deve andare dal doppio punto che segue il nome del pacchetto all'ultimo carattere della riga più lunga del testo descrittivo. È conveniente che ogni riga della descrizione resti entro gli ottanta caratteri, per evitare problemi con editor impostati.

Esempio di slack.desc:

# HOW TO EDIT THIS FILE:
# The "handy ruler" below makes it easier to edit a package description.  Line
# up the first '|' above the ':' following the base package name, and the '|'
# on the right side marks the last column you can put a character in.  You must
# make exactly 11 lines for the formatting to be correct.  It's also
# customary to leave one space after the ':'.

     |-----handy-ruler------------------------------------------------------|
emacs: emacs (GNU Emacs)
emacs:
emacs: Base binaries and support files for the GNU Emacs editor/environment.
emacs: This version supports X.  If you do not have X installed, you will
emacs: also have to install the replacement Emacs binary that does not
emacs: require the X11, Xaw3d, and Xt libraries.
emacs:
emacs: The emacs binary in this package was configured with these options:
emacs:   i486-slackware-linux --prefix=/usr --with-x11 --with-x-toolkit
emacs:   --with-pop
emacs:
--------------------------------------------------------------------------------

La parte superiore, intitolata HOW TO EDIT THIS FILE, è tutta commentata e consiste soltanto in istruzioni per compilare correttamente la descrizione (ciò nondimeno, è buona norma mantenere sempre questa sezione invece di rimuoverla). Il file va collocato in una directory creata appositamente e chiamata /install.

Creare il pacchetto col comando makepkg

Ormai tutto è pronto. Non resta che creare il pacchetto col comando makepkg opzioni nome_pacchetto-versione-pacchetto-architettura-release.tgz. Questa sequenza di dati ha una particolare importanza, soprattutto nel caso si debba aggiornare il pacchetto (col comando upgradepkg). Prendiamo ad esempio il pacchetto emacs-21.3-i486-1ms.tgz. Il primo campo è il nome del programma (emacs); il secondo la versione (21.3); il terzo l'architettura per cui è stato compilato (i486); il quarto la release (che può essere la prima o le successive, se per qualche motivo il pacchetto viene ricompilato con delle modifiche e dunque sarà 1, 2 ecc.) ed eventualmente una sigla che indica il nome di chi ha costruito il pacchetto (nel mio caso, le mie iniziali e dunque ms); infine l'estensione del pacchetto stesso (ovviamente, tgz). Il comando sarà dunque:

makepkg -l y -c n emacs-21.3-i486-1ms.tgz

L'opzione -c n (dove c significa chown e n abbrevia ovviamente "no") impedisce che vengano modificati i permessi che abbiamo assegnato. In caso contrario, makepkg concederà a tutte le directory i permessi 755 e la proprietà a root.root, che è quanto non vogliamo, avendo in precedenza disposto altrimenti. Creato il pacchetto, si possono rimuovere le due directory temporanee di lavoro (quella in cui abbiamo scompattato il sorgente e quella in cui abbiamo costruito il *.tgz). Ora siamo pronti per installare il nostro *.tgz, ma prima è opportuno verificare che il processo di compilazione sia andato a buon fine. La verifica di eventuali errori si può compiere (è il metodo più veloce) rileggendo i messaggi che sono apparsi sulla shell, a questo fine si può impostare la cronologia della shell perché visualizzi un numero illimitato di righe (Impostazioni => Cronologia => Numero di linee > Illimitato), oppure si può redirigere il processo a un file. Infine, si possono vedere soltanto gli errori ridirigendoli a un file col comando

./nome_pacchetto.SlackBuil --cleanup 2>/home/errori.txt 


Tips & Trick

a) Se il pacchetto creato necessita di un particolare file di configurazione, è possibile scriverne uno generico, da collocare in una dir opportuna creata appositamente (potrebbe essere /usr/share/nome_pacchetto, oppure /etc).

b) Se il pacchetto creato è tale che il programma dev'essere avviato mediante uno script rc.* (di quelli collocati usualmente in /etc/rc.d), allo stesso modo è opportuno inserirlo nel pacchetto.

c) Alcuni programmi non accettano le opzioni per il compilatore, dunque non possono essere costruiti per una particolare architettura. In questo caso, in luogo dell'indicazione dell'architettura (come i486) andrà inserita l'indicazione "noarc".

d) In certi casi, il programma di installazione tenta di installare i file man in /usr/share. Poiché la collocazione canonica è /usr/man (anche se Slackware crea in questi casi dei link), per redirigere la creazione dei file stessi si può passare al configure l'opzione --mandir=/usr. Se questa non dovesse funzionare, si procede spostando manualmente i file man nella posizione corretta con mv /tmp/pkg/usr/share/man /tmp/pkg/usr/man e quindi rimuovendo la directory originale con rm -r /tmp/pkg/usr/share/man.

e) Se il pacchetto necessita di librerie particolari, cioè ha delle dipendenze che richiedono altri pacchetti inusuali, o non presenti in Slackeare, ciò può essere segnalato in un file (di solo testo) chiamato "slack-required", che andrà posizionato in /install. Di default, si segnala una sola dipendenza per linea, precisando inoltre la versione richiesta, secondo la sintassi: nome_applicazione condizione versione, dove "condizione" può essere =, <, >, => e =<. Ad es., la stringa openh323 >= 1.13.4 significa che che è richiesta la libreria openh323 in versione uguale o maggiore di 1.13.4.

f) Abbiamo visto che lo script doinst.sh ha il compito di gestire i link presenti nel pacchetto. Esso può svolgere tuttavia anche delle altre funzioni aggiuntive, fondamentali per pacchetti che presentano caratteristiche particolari. Se, ad esempio, abbiamo a che fare con un programma che gira in un ambiente particolare, dobbiamo creare degli utenti e un gruppo ad hoc. È questo, fra gli altri, il caso di Qmail, che gira in ambiente chroot per motivi di sicurezza. In questo caso in doinst.sh, usando il linguaggio del bash scripting, si dovrà fare in modo che il programma crei per l'appunto i gruppi e gli utenti necessari. Il programma di installazione trova lo script e lo esegue.


Compilazione del Kernel

Alcuni pacchetti richiedono, per funzionare, librerie aggiuntive che vanno pertanto installate. A volte, molte di più sono invece le librerie necessarie per compilare il pacchetto stesso. In genere, i software applicativi normali non risentono del kernel sotto il quale sono stati costruiti. Ci sono naturalmente delle eccezioni, fra cui possiamo ricordare gli applicativi in perl, che vengono compilati in riferimento alla versione di perl installata: un aggiornamento della versione di perl impedisce il funzionamento di tutto il software perl compilato con la versione precedente e dev'essere conseguentemente ricompilato. Un comportamento diverso hanno invece i moduli (o drivers) che dipendono dal kernel per i quale sono stati costruiti (ad esempio, l'ultima versione attualmente disponibile degli alsa driver è stata compilata per il kernel 2.6.x e pertanto non funziona col kernel 2.4.x).

Casi Particolari: Il "FAKE INSTALL"

La procedura descritta funziona per la maggior parte dei pacchetti. Tuttavia a volte si incontrano degli inconvenienti, soprattutto se il pacchetto non contiene un configure: alcuni Makefile non contemplano la presenza di DESTDIR per redirigere a piacimento l'installazione. Per questi esistono vie alternative; è possibile cambiare --prefix col comando make --prefix=/destinazione), ma spesso questo comando non viene accettato, oppure in altri casi produce dei guai. È allora possibile editare direttamente il makefile apportandovi le modifiche del caso, e cioè sostituendo i path di installazione, ad es. cambiando con un editor qualsiasi /usr/local in /usr (in questo caso può essere anche possibile inserire o modificare i flags per il compilatore). In altri casi ci si deve rassegnare a produrre un "fake install", cioè una falsa installazione. Ci sono due alternative. Primo caso: dopo il make che genera i vari file del pacchetto, non si lancia il makeinstall, ma si creano le directory a mano con mkdir e si spostano i file al loro interno con mv (se si prevede di installare il pacchetto, è sufficiente copiare i file, perché poi essi verranno sovrascritti dall'installazione finale). Ovviamente, è necessario individuare i file creati o modificati dal make (in qualche caso ci aiutano le note presenti nei sorgenti; altrimenti è necessario leggere il Makefile). Secondo caso: dopo il make install, è possibile individuare i file prodotti e installati col comando find, dandogli come parametri le varie dir e cercando i file modificati o creati nel minor lasso di tempo possibile, ad es.:

find /usr -mmin 1.

Quindi il pacchetto dev'essere ricreato a mano, andando a prendere uno per uno i vari file e spostandoli nella directory di lavoro. Altri programmi ancora non presentano il configure, oppure (è il caso di quelli redatti in linguaggio di scripting come Perl e Python) non hanno il Makefile. In questi casi è necessario individuare se esiste un altro file adibito all'installazione, altrimenti non resta che effettuare ancora una volta tutto a mano.

Creare una patch

In certi casi, per adattare il pacchetto alla nostra architettura o allo stesso sistema operativo, o ancora per risolvere dei problemi di compilazione, è necessario modificare dei file di configurazione originali (in genere il Makefile). Se si vuole tener traccia delle modifiche (essenziale nel caso poi si intenda produrre uno SlackBuild), si devono modificare i file nella directory di partenza, a cui si aggiunge il suffisso *.orig e quindi produrre un file che registri le modifiche apportate col comando diff -u -r [file-originale] [file-modificato] >file.diff. La patch può essere inserita anche nello SlackBuild, che ricorre a una versione del file.diff compressa con gzip.

Lo slackbuild

Lo SlackBuild non è che uno script di shell che contiene una serie di comandi atti a costruire un pacchetto *.tgz partendo dai sorgenti. È sufficiente collocare nella stessa directory lo SlackBuild, lo slack-desc e il file sorgente e lanciare lo Slackbuild stesso. Questo può essere avviato (sempre e solo da root) settando i permessi in modo opportuno (di norma 755) e quindi impartendo il comando ./nome_pacchetto.SlackBuild oppure col comando sh nome_pacchetto.SlackBuild. L'aggiunta dell'opzione --cleanup effettua la cancellazione delle directory temporanee di lavoro. Ilprocesso può essere seguito da shell, e alla fine nella directory /tmp troveremo il pacchetto pronto. La scrittura di uno SlackBuild è utile perché in tal modo i vari passaggi eseguiti nella creazione del pacchetto non vanno persi: sarà sempre possibile compilare una versione aggiornata (controllando i cambiamenti) senza dover rifare daccapo tutto il procedimento. Inoltre, modificando alcuni parametri, si può compilare in modo veloce un pacchetto personalizzato (ad esempio, è possibile utilizzare uno SlackBuild ufficiale e modificare i FLAGS per adattarlo maggiormente alla nostra architettura). Naturalmente, la stesura dello SlackBuild richiede una qualche conoscenza di bash scripting. Ci limitiamo in questa sede a offrire un esempio commentato di SlackBuild.

#!/bin/sh
#
# Heavily based on the Slackware 10.0 SlackBuild
#
# http://www.nano-editor.org/

Qui si imposta la shell con cui far funzionare lo SlackBuild, nella fattispecie bash. Infatti altre shell usano comandi leggermente diversi. Si fornisce anche l'indicazione del sito da cui è tratto il sorgente. Tutta questa breve sessione è commentata in quanto non fa parte dello script vero e proprio, cioè di quanto verrà in effetti eseguito.

CWD=`pwd`
if ["$TMP" = ""]; then
TMP=/tmp
fi
PKG=$TMP/package-nano
NAME=nano
VERSION=1.2.4
ARCH=i486
BUILD=1ms

Dapprima (prima riga) si imposta la directory corrente in cui stanno il sorgente, lo slack-desc e lo SlackBuild. CWD è la Current Work Directory e il comando pwd effettua il print out directory, che per noi è la directory di esecuzione dello script. Quindi si impostano la variabile per la directory di lavoro, qui /tmp (seconda e terza riga). In secondo luogo vengono create altre variabili atte a velocizzare il lavoro: il nome della directory di lavoro in /tmp (quinta riga), il nome del pacchetto (sesta riga), la versione (settima riga), l'architettura (ottava riga) e infine la release del *.tgz (nona riga). L'uso delle variabili è sempre preferibile, perché, se si deve aggiornare lo SlackBuild per costruire una versione successiva, basta cambiare una sola occorrenza.

 if [ ! -d $TMP ]; then
mkdir -p $TMP 
fi

Qui si definisce la posizione in cui scompattare il sorgente.

 if [ ! -d $PKG ]; then
mkdir -p $PKG 
fi

Qui si definisce la posizione in cui creare il pacchetto.

echo "| Start SlackBuild $NAME-$VERSION |"

Una semplice stampa a schermo, che ci avverte dell'avvio dello SlackBuild per un determinato pacchetto, fornendone nome e versione.

cd $TMP
tar xzvf $CWD/$NAME-$VERSION.tar.gz

In questo modo ci si porta nella directory di lavoro e si scompatta il sorgente.

cd $NAME-$VERSION
chown -R root.root .
find . -perm 775 -exec chmod 755 {} \;
find . -perm 664 -exec chmod 644 {} \;

In questo modo ci si porta nella directory del sorgente ormai scompattato (prima riga), si cambiano i permessi (seconda riga), si rendono ortodossi eventuali per messi anomali (terza e quarta riga)

CFLAGS="-O2 -march=i486 -mcpu=i686" ./configure --prefix=/usr \
						--disable-debug \
						--enable-color \
						--enable-multibuffer \
						--enable-nanorc

In questo modo si passano al configure i parametri di configurazione per il compilatore, si suggerisce la directory di installazione e si impostano i parametri opzionali.

make

Si passa alla compilazione vera e propria del pacchetto.

make install DESTDIR=$PKG

Si fa in modo che i file del pacchetto vengano installati all'interno della directory temporanea di lavoro

mkdir -p $PKG/usr/doc/$NAME-$VERSION
cp -a \
  ABOUT-NLS AUTHORS BUGS COPYING ChangeLog INSTALL NEWS README THANKS TODO UPGRADE \
  $PKG/usr/doc/$NAME-$VERSION

In questo modo si crea la directory canonica per inserire la documentazione e vi si copiano i file dal sorgente scompattato, in genere presenti nella sua directory principale.


( cd $PKG 
  find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 
  find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 
)

Si strippano i binari e le librerie.

gzip -9 $PKG/usr/man/*/*
gzip -9 $PKG/usr/info/*

Si comprimono i file man e info

chown -R root.bin $PKG/usr/bin

Si conferiscono i corretti permessi alla directory /bin, dove stanno gli eseguibili.

mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc

Si crea la directory install e vi si copia lo slack-desc. In questa directory il programma inserirà poi anche l'eventuale doinst.sh.

cd $PKG
makepkg -l y -c n $TMP/$NAME-$VERSION-$ARCH-$BUILD.tgz

Si passa nella directory del pacchetto appena creato e si impartisce il comando atto a creare il pacchetto

if [ "$1" = "--cleanup" ]; then
rm -rf $TMP/$NAME-$VERSION
rm -rf $PKG
fi

Nel caso lo SlackBuild sia stato lanciato con l'opzione -cleanup, questa sezione si occupa di cancellare le due directory temporanee: quella dove è stato scompattato il sorgente e quella in cui è stato creato il pacchetto.

Sitologia

Purtroppo, la letteratura sul tema della compilazione dei *.tgz è scarsa e a volte scadente. Alcuni testi forniscono solo indicazioni generiche o sommarie. Qui riportiamo delle indicazioni sul materiale reperibile in rete:

http://www.slacky.it/modules.php?name=Content&pa=showpage&pid=33

http://www.hackerjournal.it/hj/modules.php?op=modload&name=News&file=article&sid=94

http://www.google.it/search?q=cache:noeUgu4xXlcJ:belluno.linux.it/20040424-distribuzioni/2004-04-24-slack.pdf+creare+pacchetti+slackware&hl=it&lr=lang_it

http://www.slack.z00.it/slack/docs/slackbuild.html

http://www.justlinux.com/nhf/Distribution_Specific/Slackware_Linux/Slackware__The_Quick_and_Dirty_Quide_to_Packages.html

http://www.osnews.com/story.php?news_id=3974

http://old.slackfiles.net/documentation/en/articles/pkgtools.html

http://www.linuxpackages.net/howto.php?page=package&title=Package+Howto

http://www.linuxpackages.net/howto.php?page=perfect-package&title=Perfect+Package

http://www.slacky.it/modules.php?name=Content&pa=showpage&pid=32


Nota

Questa versione anticipa in linea di massima la sezione sulla pacchettizzazione per la prossima versione di "Slackware for dummies". Per essa, sono previsti alcuni ulteriori approfondimenti e una nuova sezione su "Creare uno script doinst.sh".


Ringraziamenti

Devo un duplice ringraziamento a Lorys, di Slacky.it. In primo luogo per aver letto una prima versione di questo HOW-TO suggerendo alcune correzioni e aggiunte. In secondo luogo perché è soprattutto grazie alla sua disponibilità che ho acquisito alcune nozioni su come pacchettizare in tgz. Resta inteso che eventuali errori, sviste e omissioni sono di mia esclusiva responsabilità.

Autore: Samiel

Strumenti personali
Namespace

Varianti