Gentoo Logo

Disclaimer : La versione originale di questo articolo è stata pubblicata da IBM developerWorks ed è di proprietà di Westtech Information Services. Questo documento è una versione aggiornata dell'articolo originale, e contiene numerosi miglioramenti apportati dal Gentoo Linux Documentation team.
Questo documento non è mantenuto attivamente.


Bash per esempi, Parte 3

Indice:

1.  Esplorare il sistema ebuild

Entrare nel sistema ebuild

Non vedevo l'ora di arrivare a questa terza e ultima parte di Bash by examplee, perché ora che abbiamo già trattato i fondamenti della programmazione bash nella Parte 1 e nella Parte 2, possiamo concentrarci su argomenti più avanzati, come lo sviluppo di applicazioni bash e la strutturazione dei programmi. In questo articolo, vi darò una buona dose di esperienza pratica nello sviluppo bash, presentando un progetto sulla cui scrittura e revisionne ho speso molte ore: il sistema ebuild di Gentoo Linux.

Sono il capo progettista di Gentoo Linux, un SO Linux di ultima generazione, attualmente in fase beta. Una delle mie responsabilità principali è assicurarmi che tutti i pacchetti binari (simili ai pacchetti RPM) siano creati in modo corretto e lavorino insieme. Come probabilmente sapete, un sistema standard Linux non è composto da un albero di sorgenti singolo e unito (come BSD), ma in realtà è fatto di oltre 25 pacchetti fondamentali che lavorano insieme. Alcuni di questi pacchetti contengono:

Pacchetto Descrizione
linux Il kernel vero e proprio
util-linux Una raccolta di vari programmi collegati a Linux
e2fsprogs Una raccolta di varie utility riguardanti il filesystem ext2
glibc La libreria GNU C

Ogni pacchetto sta nel suo tarball ed è mantenuto da sviluppatori, o team di sviluppatori, indipendenti. Per creare una distribuzione, ogni pacchetto deve essere scaricato separatamente, compilato e pacchettizzato. Ogni volta che un pacchetto deve essere corretto, aggiornato o migliorato, la compilazione e la pacchettizzazione devono essere ripetute (e i pacchetti diventano obsoleti molto in fretta). Per aiutare ad eliminare le fasi ripetitive del processo di creazione ed aggiornamento dei pacchetti, ho creato il sistema ebuild, scritto quasi interamente in bash. Per aumentare la vostra conoscenza di bash, vi mostrerò come ho implementato le parti del sistema ebuild riguardanti l'estrazione e la compilazione, passo dopo passo. Mentre spiegherò ogni passaggio, parlerò anche del perché sono state prese alcune decisioni. Alla fine di questo articolo, non solo avrete una eccellente conoscenza di progetti di programmazione bash su una scala più larga, ma avrete anche implementato una buona porzione di un sistema completo di autocompilazione.

Perché bash?

Bash è una componente essenziale del sistema ebuild di Gentoo Linux. È stata scelta come linguaggio principale di ebuild per diverse ragioni. In primo luogo, perché ha una sintassi semplice e familiare, adatta specialmente a lanciare programmi esterni. Un sistema di autocompilazione è un "codice collante" che automatizza l'invocazione di programmi esterni, e bash è molto adatta per questo tipo di utilizzo. In secondo luogo, il supporto bash per le funzioni ha consentito al sistema ebuild di avere un codice modulare, semplice da comprendere. In terzo luogo, il sistema ebuild sfrutta il supporto bash per le variabili d'ambiente, permettendo ai maintainers e agli sviluppatori dei pacchetti di configurarlo facilmente, al volo.

Esame del processo di compilazione

Prima di guardare al sistema ebuild, esaminiamo come avviene la compilazione e l'installazione di un pacchetto. Per il nostro esempio, prenderemo il pacchetto "sed", una utility standard GNU che serve ad editare flussi di testo e che è presente in tutte le distribuzioni Linux. Per prima cosa, scaricate il tarball dei sorgenti (sed-3.02.tar.gz) (vedi Risorse). Salveremo questo archivio in /usr/src/distfiles, una directory a cui ci riferiremo usando la variabile d'ambiente $DISTDIR. $DISTDIR è la directory dove si trovano tutti i tarball dei sorgenti originari; è un grande deposito di codice sorgente.

Il nostro prossimo passo consiste nel creare una directory temporanea chiamata work, che contenga i sorgenti estratti. In seguito ci riferiremo a questa directory usando la variabile d'ambiente $WORKDIR. Per fare ciò, spostiamoci in una directory in cui abbiamo il permesso di scrittura e digitiamo quanto segue:

Codice 1.1: Decomprimere sed in una directory temporanea

$ mkdir work
$ cd work
$ tar xzf /usr/src/distfiles/sed-3.02.tar.gz

Ora il tarball è stato decompresso, creando una directory chiamata sed-3.02 che contiene tutti i sorgenti. In seguito ci riferiremo alla directory sed-3.02 usando la variabile d'ambiente $SRCDIR. Per compilare il programma, digitate quanto segue:

Codice 1.2: Compilare sed

$ cd sed-3.02
$ ./configure --prefix=/usr
(autoconf deve generare i makefiles, può volerci un po' di tempo)

$ make

(il pacchetto viene compilato dai sorgenti, anche qui può volerci un po')

Salteremo la fase del "make install", dato che in questo articolo trattiamo solo le fasi dell'estrazione e della compilazione. Se volessimo scrivere uno script bash script che esegua per noi tutti questi passaggi, potremmo fare qualcosa del genere:

Codice 1.3: Esempio di script bash che esegua il processo dell'estrazione e della compilazione

#!/usr/bin/env bash

if [ -d work ]
then
# rimuovere la vecchia directory di lavoro, se presente
      rm -rf work
fi
mkdir work
cd work
tar xzf /usr/src/distfiles/sed-3.02.tar.gz
cd sed-3.02
./configure --prefix=/usr
make

Generalizzare il codice

Sebbene questo script di autocompilazione funzioni, non è molto flessibile. In breve, lo script bash contiene solo la lista di tutti i comandi che avremmo dovuto dare da linea di comando. Nonostante questa soluzione funzioni, sarebbe bene creare uno script generico che possa essere configurato facilmente per estrarre e compilare qualsiasi pacchetto, modificando solo poche righe. In questo modo, è molto meno faticoso per il mantainer aggiungere nuovi pacchetti alla distribuzione. Facciamo un primo tentativo in questo senso, usando molte variabili d'ambiente diverse per rendere il nostro script più generico:

Codice 1.4: Uno script nuovo, più generale

#!/usr/bin/env bash

# P è il nome del pacchetto

P=sed-3.02

# A è il nome dell'archivio

A=${P}.tar.gz

export ORIGDIR=`pwd`
export WORKDIR=${ORIGDIR}/work
export SRCDIR=${WORKDIR}/${P}

if [ -z "$DISTDIR" ]
then
# impostare DISTDIR a /usr/src/distfiles se non lo avete già fatto
        DISTDIR=/usr/src/distfiles
fi
export DISTDIR

if [ -d ${WORKDIR} ]
then
# rimuovere la vecchia directory di lavoro, se presente
        rm -rf ${WORKDIR}
fi

mkdir ${WORKDIR}
cd ${WORKDIR}
tar xzf ${DISTDIR}/${A}
cd ${SRCDIR}
./configure --prefix=/usr
make

Abbiamo aggiunto al codice molte variabili d'ambiente, ma in pratica esso fa ancora la stessa cosa. Tuttavia, ora, per compilare tarball di sorgenti standard GNU basati su autoconf, possiamo semplicemente copiare questo file in un nuovo file (con un nome appropriato, che rifletta il nome del nuovo pacchetto da compilare), e poi cambiare i valori di $A e $P in nuovi valori. Tutte le altre variabili d'ambiente acquisteranno automaticamente le impostazioni corrette, e lo script funzionerà come previsto. Sebbene questo sia comodo, c'è un ulteriore miglioramento che può essere apportato al codice. Questo particolare codice è molto più lungo dello script "transcript" che avevamo creato in origine. Dato che uno degli obiettivi di ogni progetto di programmazione dovrebbe essere la riduzione della complessità per l'utente, sarebbe bene ridurre il codice il più possibile, o almeno organizzarlo meglio. Possiamo fare ciò con un trucchetto: spezzeremo il codice in due file separati. Salvate questo file come sed-3.02.ebuild:

Codice 1.5: sed-3.02.ebuild

#il file ebuild sed -- molto semplice!
P=sed-3.02
A=${P}.tar.gz

Il nostro primo file è elementare, e contiene solo quelle variabili d'ambiente che devono essere configurate in modo diverso per ogni pacchetto. Ecco il secondo file, che contiene il cervello dell'operazione. Salvatelo come "ebuild" e rendetelo eseguibile:

Codice 1.6: Lo script ebuild

#!/usr/bin/env bash


if [ $# -ne 1 ]
then
        echo "one argument expected."
        exit 1
fi

if [ -e "$1" ]
then
        source $1
else
        echo "ebuild file $1 not found."
        exit 1
fi

export ORIGDIR=`pwd`
export WORKDIR=${ORIGDIR}/work
export SRCDIR=${WORKDIR}/${P}

if [ -z "$DISTDIR" ]
then
        # impostate DISTDIR a /usr/src/distfiles se non lo avete già fatto
        DISTDIR=/usr/src/distfiles
fi
export DISTDIR

if [ -d ${WORKDIR} ]
then
        # remove old work directory if it exists
        rm -rf ${WORKDIR}
fi

mkdir ${WORKDIR}
cd ${WORKDIR}
tar xzf ${DISTDIR}/${A}
cd ${SRCDIR}
./configure --prefix=/usr
make

Ora che abbiamo diviso il nostro sistema di compilazione in due parti, scommetto che vi starete chiedendo come faremo a farlo funzionare. In breve, per compilare sed, digitate:

Codice 1.7: Testare l'ebuild precedente

$ ./ebuild sed-3.02.ebuild

Quando "ebuild" viene eseguito, innanzitutto prova a "sorgentizzare" la variabile $1. Cosa significa? Dall'articolo precedente, vi ricorderete che $1 è il primo argomento da linea di comando, in questo caso sed-3.02.ebuild. In bash, il comando "source" legge i periodi bash da un file, e li esegue ciome se essi apparissero direttamente nel file in cui si trova il comando "source". Quindi, "source ${1}" fa sì che lo script "ebuild" esegua i comandi in sed-3.02.ebuild, il che porta alla definizione di $P e $A. Questo cambio di struttura è veramente molto comodo, in quanto se vogliamo compilare un altro programma al posto di sed, possiamo semplicemente creare un nuovo file .ebuild e passarlo come argomento al nostro script "ebuild". In questo modo, i file .ebuild finiscono per essere molto semplici, mentre il cuore complicato del sistema ebuild si trova in un unico luogo, il nostro script "ebuild". Così facendo, possiamo aggiornare o migliorare il sistema ebuild semplicemente editando lo script "ebuild", mantenendo i dettagli dell'implementazione fuori dai file ebuild. Ecco un esempio di file ebuild per gzip:

Codice 1.8: gzip-1.2.4a.ebuild

#un altro script ebuild molto semplice!
P=gzip-1.2.4a
A=${P}.tar.gz

Aggiungere funzionalità

OK, stiamo facendo qualche progresso. Tuttavia, c'è qualche ulteriore funzionalità che vorrei aggiungere. Vorrei che lo script ebuild accettasse un secondo argomento da linea di comando, che sarà compile, unpack, o all. Questo secondo argomento da linea di comando dice allo script ebuild quale particolare passaggio del processo di compilazione deve eseguire. In questo modo, posso dire ad ebuild di estrarre l'archivio, ma senza compilarlo (in caso volessi controllare l'archivio dei sorgenti prima della compilazione). Per fare ciò, aggiungerò un periodo "case" che esaminerà la variabile $2, compiendo azioni diverse a seconda del suo valore. Ecco come appare il codice adesso:

Codice 1.9: ebuild, revisione 2

#!/usr/bin/env bash

if [ $# -ne 2 ]
then
        echo "Please specify two args - .ebuild file and unpack, compile or all"
        exit 1
fi


if [ -z "$DISTDIR" ]
then
 # impostate DISTDIR a /usr/src/distfiles se non lo avete già fatto
        DISTDIR=/usr/src/distfiles
fi
export DISTDIR

ebuild_unpack() {
         #assicuratevi di essere nella giusta directory
        cd ${ORIGDIR}

        if [ -d ${WORKDIR} ]
        then
                rm -rf ${WORKDIR}
        fi

        mkdir ${WORKDIR}
        cd ${WORKDIR}
        if [ ! -e ${DISTDIR}/${A} ]
        then
            echo "${DISTDIR}/${A} does not exist.  Please download first."
            exit 1
        fi
        tar xzf ${DISTDIR}/${A}
        echo "Unpacked ${DISTDIR}/${A}."
        #source is now correctly unpacked
}


ebuild_compile() {

         #assicuratevi di essere nella giusta directory
        cd ${SRCDIR}
        if [ ! -d "${SRCDIR}" ]
        then
                echo "${SRCDIR} does not exist -- please unpack first."
                exit 1
        fi
        ./configure --prefix=/usr
        make
}

export ORIGDIR=`pwd`
export WORKDIR=${ORIGDIR}/work

if [ -e "$1" ]
then
        source $1
else
        echo "Ebuild file $1 not found."
        exit 1
fi

export SRCDIR=${WORKDIR}/${P}

case "${2}" in
        unpack)
                ebuild_unpack
                ;;
        compile)
                ebuild_compile
                ;;
        all)
                ebuild_unpack
                ebuild_compile
                ;;
        *)
                echo "Please specify unpack, compile or all as the second arg"
                exit 1
                ;;
esac

Abbiamo fatto un sacco di cambiamenti, quindi esaminiamoli. Per prima cosa, abbiamo messo le fasi della compilazione e dell'estrazione all'interno di apposite funzioni, che abbiamo chiamato rispettivamente ebuild_compile() e ebuild_unpack(). Questa è una buona mossa, perché il codice si sta facendo più complesso e le nuove funzioni forniscono un po' di modularità, che aiuta a mantenere le cose ordinate. Nella prima riga di ogni funzione, eseguo esplicitamente il cd nella directory in cui voglio stare, in quanto, dato che il nostro codice sta diventando più modulare che lineare, è più probabile che eseguiamo una funzione nella directory di lavoro sbagliata. I comandi cd ci mettono esplicitamente nel posto giusto, e ci impediscono di commettere errori più tardi; è un passaggio importante, soprattutto se all'interno delle funzioni cancellerete dei file.

Inoltre, ho aggiunto un controllo utile all'inizio della funzione ebuild_compile(). Questo si assicurerà che $SRCDIR esista, e, nel caso non esista, visualizzerà un messaggio di errore dicendo all'utente di estrarre l'archivio, dopodiché uscirà. Se volete, potete modificare questo comportamento in modo che, se $SRCDIR non esiste, il nostro script ebuild estragga l'archivio dei sorgenti automaticamente. Potete fare ciò sostituendo ebuild_compile() con il seguente codice:

Codice 1.10: Di nuovo su ebuild_compile()

ebuild_compile() {
        #assicuratevi di essere nella giusta directory
        if [ ! -d "${SRCDIR}" ]
        then
                ebuild_unpack
        fi
        cd ${SRCDIR}
        ./configure --prefix=/usr
        make
}

Una delle modifiche più evidenti nella seconda versione del nostro script ebuild è il nuovo periodo "case" alla fine del codice. Questo periodo "case" esamina semplicemente il secondo argomento da linea di comando, eseguendo l'azione corretta a seconda del suo valore. Se ora digitiamo:

Codice 1.11: Azione di default

$ ebuild sed-3.02.ebuild

Nei fatti otteniamo un messaggio di errore. ebuild infatti ora vuole che gli diciamo cosa fare, in questo modo:

Codice 1.12: Estrarre

$ ebuild sed-3.02.ebuild unpack

oppure:

Codice 1.13: Compilare

$ ebuild sed-3.02.ebuild compile

oppure:

Codice 1.14: Estrarre e compilare

$ ebuild sed-3.02.ebuild all

Importante: Se fornite da linea di comando un secondo argomento diverso da quelli elencati sopra, otterrete un messaggio di errore (la proposizione *), e il programma uscirà.

Modularizzare il codice

Ora che il codice è abbastanza avanzato e funzionale, potreste essere tentati di creare molti altri script ebuild, per estrarre e compilare i vostri programmi preferiti. Se lo fate, prima o poi vi imbatterete in sorgenti che non utilizzano autoconf (./configure), o forse in altri che hanno processi di compilazione non standard. Dobbiamo effettuare alcuni ulteriori cambiamenti al sistema ebuild, in modo da supportare questi programmi. Ma prima di farlo, è bene riflettere un po' sul come fare.

Il vantaggio di inserire di default i comandi ./configure --prefix=/usr; make nel nostro script di compilazione è che, la maggiorparte delle volte, funzionerà. Tuttavia, dobbiamo fare sì che il sistema ebuild funzioni anche con i sorgenti che non utilizzano autoconf o i normali Makefiles. Per risolvere questo problema, propongo che il nostro script ebuild dovrebbe, di default, fare quanto segue:

  1. Se esiste uno script configure in ${SRCDIR}, eseguirlo in questo modo: ./configure --prefix=/usr. Altrimenti, saltare questo passaggio.
  2. Eseguire il seguente comando: make

Dato che ebuild esegue configure solo se questo esiste, ora possiamo supportare automaticamente quei programmi che non usano autoconf ed hanno makefiles standard. Ma che fare se un semplice "make" non basta per alcuni sorgenti? Ci serve un modo per ignorare le nostre logiche impostazioni di default con del codice specifico che gestisca queste situazioni. Per fare ciò, trasformeremo la nostra funzione ebuild_compile() in due funzioni. La prima funzione, che può essere considerata una funzione "genitore", sarà ancora chiamata ebuild_compile(). Tuttavia, avremo una nuova funzione, chiamata user_compile(), che conterrà solo le nostre normali azioni di default:

Codice 1.15: ebuild_compile() spezzato in due funzioni

user_compile() {
        #siamo già in ${SRCDIR}
        if [ -e configure ]
        then
                #run configure script if it exists
                ./configure --prefix=/usr
        fi
        #run make
        make
}

ebuild_compile() {
        if [ ! -d "${SRCDIR}" ]
        then
                echo "${SRCDIR} does not exist -- please unpack first."
                exit 1
        fi
        #assicuratevi di essere nella giusta directory
        cd ${SRCDIR}
        user_compile
}

Potrebbe non sembrare ovvio il perché stiamo facendo questo proprio ora, ma fidatevi di me. Mentre il codice funziona in modo quasi identico alla nostra precedente versione di ebuild, adesso possiamo fare qualcosa che prima non potevamo fare: possiamo ignorare user_compile() in sed-3.02.ebuild. Quindi, se la funzione di default user_compile() non ci aiuta, possiamo definirne una nuova nel nostro file .ebuild, contenente i comandi necessari per compilare il pacchetto. Per esempio, ecco un file ebuild per e2fsprogs-1.18, che richiede una riga ./configure un po' diversa:

Codice 1.16: e2fsprogs-1.18.ebuild

#questo file ebuild ignora la funzione di default user_compile()
P=e2fsprogs-1.18
A=${P}.tar.gz

user_compile() {
       ./configure --enable-elf-shlibs
       make
}

A questo punto e2fsprogs potrà essere compilato esattamente nel modo in cui vogliamo. Tuttavia, per la maggiorparte dei pacchetti, possiamo omettere qualsiasi funzione user_compile() nel file .ebuild, lasciando che venga utilizzata la funzione user_compile() di default.

Come fa esattamente lo script ebuild a capire quale funzione user_compile() usare? Di fatto questo è molto semplice. Nello script ebuild, la funzione user_compile() di default viene definita prima che il file e2fsprogs-1.18.ebuild sia sorgentizzato. Se esiste una funzione user_compile() in e2fsprogs-1.18.ebuild, questa sovrascrive la versione di default definita precedentemente. Se non c'è, viene usata la funzione user_compile() di default.

Questo è grandioso: abbiamo aggiunto un sacco di flessibilità senza avere bisogno di codice complesso non necessario. Qui non ne parleremo, ma potreste anche fare modifiche simili a ebuild_unpack(), in modo che gli utenti possano ignorare il processo standard di estrazione. Questo potrebbe rivelarsi comodo nel caso in cui si debbano applicare delle patch, ooppure se i file sono contenuti in archivi multipli. È una buona idea anche modificare il nostro codice di estrazione in modo che riconosca di default i tarball compressi con bzip2.

Files di configurazione

Finora abbiamo trattato un sacco di tecniche bash, e ora è il momento di introdurne un'altra. Spesso, è comodo per un programma avere un file di configurazione globale residente in /etc. Fortunatamente, questo è semplice da fare usando bash. Create semplicemente il seguente file e salvatelo come /etc/ebuild.conf:

Codice 1.17: /ect/ebuild.conf

# /etc/ebuild.conf: impostare in questo file le opzioni globali ebuild

# MAKEOPTS sono le opzioni passate a make
MAKEOPTS="-j2"

In questo esempio, ho incluso una sola opzione di configurazione, ma voi potreste includerne molte di più. Uno dei pregi di bash è che questo file può essere analizzato semplicemente sorgentizzandolo. Questo è un trucco di strutturazione che funziona con la maggiorparte dei linguaggi interpretati. Dopo che /etc/ebuild.conf è stato sorgentizzato, all'interno del nostro script ebuild viene definito $MAKEOPTS. Lo useremo per permettere all'utente di passare opzioni a make. Normalmente, questa opzione sarebbe usata per consentire all'utente di dire a ebuild di effettuare una compilazione parallela. Questo viene spiegato sotto.

Nota: Cos'è un make parallelo? Per velocizzare la compilazione sui sistemi multiprocessore, make supporta la compilazione di un programma in parallelo. Questo vuol dire che anziché compilare un solo file sorgente alla volta, make compila simultaneamente un numero di file sorgenti definito dall'utente (così vengono utilizzati quei processori extra nei sistemi multiprocessore). Le compilazioni parallele vengono abilitate passando a make l'opzione -j #, in questo modo: make -j4 MAKE="make -j4". Questo codice dice a make di compilare quattro programmi simultaneamente. L'argomento MAKE="make -j4" dice a make di passare l'opzione -j4 a qualunque processo make figlio da esso lanciato.

Ecco la versione finale del nostro programma ebuild:

Codice 1.18: ebuild, la versione finale

#!/usr/bin/env bash

if [ $# -ne 2 ]
then
        echo "Please specify ebuild file and unpack, compile or all"
        exit 1
fi

source /etc/ebuild.conf

if [ -z "$DISTDIR" ]
then
        # impostare DISTDIR a /usr/src/distfiles se non è stato già fatto
        DISTDIR=/usr/src/distfiles
fi
export DISTDIR

ebuild_unpack() {
        #assicuratevi di essere nella giusta directory
        cd ${ORIGDIR}

        if [ -d ${WORKDIR} ]
        then
                rm -rf ${WORKDIR}
        fi

        mkdir ${WORKDIR}
        cd ${WORKDIR}
        if [ ! -e ${DISTDIR}/${A} ]
        then
                echo "${DISTDIR}/${A} does not exist.  Please download first."
                exit 1
        fi
        tar xzf ${DISTDIR}/${A}
        echo "Unpacked ${DISTDIR}/${A}."
        #ora i sorgenti sono stati estratti correttamente
}

user_compile() {
        #siamo già in ${SRCDIR}
        if [ -e configure ]
        then
                #eseguire lo script configure se esiste
                ./configure --prefix=/usr
        fi
        #eseguire make
        make $MAKEOPTS MAKE="make $MAKEOPTS"
}

ebuild_compile() {
        if [ ! -d "${SRCDIR}" ]
        then
                echo "${SRCDIR} does not exist -- please unpack first."
                exit 1
        fi
        #assicuratevi di essere nella giusta directory
        cd ${SRCDIR}
        user_compile
}

export ORIGDIR=`pwd`
export WORKDIR=${ORIGDIR}/work

if [ -e "$1" ]
then
        source $1
else
        echo "Ebuild file $1 not found."
        exit 1
fi

export SRCDIR=${WORKDIR}/${P}

case "${2}" in
        unpack)
                ebuild_unpack
                ;;
        compile)
                ebuild_compile
                ;;
        all)
                ebuild_unpack
                ebuild_compile
                ;;
        *)
                echo "Please specify unpack, compile or all as the second arg"
                exit 1
                ;;
esac

Notate che /etc/ebuild.conf è sorgentizzato vicino all'inizio del file. Notate inoltre che utilizziamo $MAKEOPTS nella nostra funzione user_compile() di default. Potreste chiedervi come farà a funzionare: dopotutto, ci riferiamo a $MAKEOPTS prima di aver sorgentizzato /etc/ebuild.conf, che di fatto definisce $MAKEOPTS come prima cosa. Fortunatamente per noi, questo funziona perché l'espansione della variabile avviene soltanto quando user_compile() viene eseguito. Quando user_compile() viene eseguito, /etc/ebuild.conf è già stato sorgentizzato, e $MAKEOPTS è impostato al valore corretto.

Per finire

Abbiamo trattato un sacco di tecniche di programmazione bash in questo articolo, ma abbiamo esaminato solo una piccola parte della potenza di bash. Per esempio, il sistema ebuild di Gentoo Linux non solo estrae e compila automaticamente ogni pacchetto, ma può anche:

  • Scaricare automaticamente i sorgenti, se questi non vengono trovati in $DISTDIR
  • Verificare che i sorgenti non siano corrotti usando i digest MD5
  • Se richiesto, installare l'applicazione compilata all'interno del filesystem, registrando tutti i file installati in modo che il pacchetto possa essere facilmente disinstallato in seguito.
  • Se richiesto, pacchettizzare l'applicazione compilata in un tarball (compresso come si vuole) in modo che possa essere installata successivamente, o su un altro computer, oppure durante il processo di installazione basato su CD (se state costruendo il CD di una distribuzione)

In aggiunta, il sistema ebuild ha diverse altre opzioni di configurazione globale, che permettono all'utente di specificare opzioni come le flag di ottimizzazione da usare durante la compilazione, oppure di scegliere se abilitare di default il supporto opzionale per pacchetti come GNOME e slang in quei pacchetti che lo supportano.

È chiaro che bash più fare molto più di quanto abbiamo trattato in questa serie di articoli. Spero che abbiate imparato molte cose su questo incredibile strumento, e che siate eccitati all'idea di poter usare bash per velocizzare e migliorare i vostri progetti di sviluppo.

2.  Risorse

Link utili



Stampa

Aggiornato il 9 ottobre 2005

Oggetto: In questo articolo finale su Bash, Daniel Robbins esamina in particolare il sistema ebuild di Gentoo Linux, un eccellente esempio della potenza di bash. Passo dopo passo, egli vi mostrerà come fu implementato il sistema ebuild e vi spiegherà molte pratiche tecniche bash e strategie di strutturazione. Alla fine di questo articolo, avrete una buona conoscenza di ciò che serve a produrre un'applicazione completamente basata su bash, e potrete iniziare a scrivere il vostro sistema personale di autocompilazione.

Daniel Robbins
Autore

Cristiano Chiucchiolo
Traduzione

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.