Bernd
Pol
Ian
Wadham

# Compilazione e gestione dei progetti

Questo capitolo si occupa solo di progetti compilati, come C++, Java o Fortran. I progetti per linguaggi di scripting come Python e Php funzionano in modo molto diverso.

Si troveranno informazioni sui seguenti argomenti:

- Sommario sul gestore Automake contenente una panoramica sul gestore Automake,

- Operazioni con il gestore Automake dove sono descritte le operazioni principali per lavorare con il gestore Automake,

## Sommario sul gestore Automake

Nel capitolo Sistemi di compilazione è stata esposta una panoramica approssimativa sui sistemi di compilazione usati comunemente sui sistemi &UNIX;. Nelle sezioni seguenti verranno esaminati più in dettaglio.

È presente una certa confusione su come chiamare questi sistemi. &GNU; parla di sistemi di compilazione (build systems) quando descrive Automake, Autoconf e Libtool. QMake si descrive come uno strumento per scrivere Makefile per diversi compilatori e piattaforme. In &kde; è spesso usato il termine sistemi di gestione di progetti (project management systems). Si userà questo permine in senso più ampio per descrivere l'ambiente incorporato di &kdevelop; che è usato per organizzare e compilare i progetti. Nel contesto di questa sezione, comunque si parlerà principalmente di sistemi di compilazione automatici.

### Il necessario per un sistema di compilazione automatico

Se si ha un semplice programma Hello World scritto in C, lo si può compilare ed effettuare il linking usando &gcc; `-o hello hello.c` e può essere eseguito usando il comando `./hello`, perciò non è addirittura necessario un `Makefile`.

Se si ha un'applicazione C con diversi moduli e file header che viene eseguita solo sulla propria macchina (cioè un'applicazione "interna"), servirà solo un `Makefile` abbastanza semplice da scrivere a mano (per maggiori informazioni consultare `info Make`).

Le complicazioni iniziano quando:

- Il codice sorgente, la documentazione, la grafica, i suoni, le traduzioni, i file di dati, ecc. sono presenti in più di una directory,

- Si ha una gerarchia di directory e sottodirectory,

- Si stanno usando librerie che non fanno parte dell'insieme tradizionale presente in &UNIX;, come le librerie &Qt; o le librerie &kde;,

- Si sta usando un pre-processore per generare parte del codice sorgente, come il pre-compilatore MOC di Qt,

- Si vuole distribuire l'applicazione a livello mondiale, a persone che potrebbero non avere lo stesso sistema &UNIX;/&Linux; o lo stesso software e hardware,

- Si necessita di un sistema di installazione e disinstallazione,

- Si vuole far sì che l'applicazione faccia parte di &kde; Desktop.

Se si è in una o tutte tra queste situazioni, probabilmente sarà necessario un sistema di compilazione. Nell'esempio sopra è stato usato &gcc; per compilare il programma Hello World, ma non tutti i compilatori C si chiamano &gcc;. Quindi se si distribuisce l'applicazione a qualcuno che sta usando un altro compilatore C, il Makefile deve usare in qualche modo il nome del compilatore di quella persona, altrimenti l'applicazione non compilerà — e questo è solo un semplice esempio di quello che può andare storto.

Un sistema di compilazione nasconderà queste differenze.

- Controllerà che le librerie necessarie siano presenti su ogni macchina di destinazione,

- scansionerà automaticamente tutte le directory dell'applicazione per cercare i file da pre-processare, compilare o installare e

- installerà i componenti dell'applicazione nelle directory di destinazione corrette, assicurandosi che

- le directory vengano create come richiesto sulla macchina di destinazione.

In poche parole, un sistema di compilazione offre un metodo sicuro per compilare e installare correttamente l'applicazione sulla macchina di destinazione. Come è stato mostrato prima nella panoramica Sistemi di gestione dei progetti, &kdevelop; fornisce tre sistemi di compilazione automatici e le opzioni per creare i propri Makefile. In breve (cliccare sul nome del progetto per ricevere ulteriori informazioni):

- I Progetti Automake che usano gli strumenti standard di sviluppo &GNU;.

- I Progetti QMake che usano il gestore di progetti Qmake di Trolltech.

- I Progetti ANT che usano il gestore di progetti ANT di Apache per lo sviluppo con &Java;.

- I Progetti personalizzati che richiedono che si gestiscano i propri `Makefile`.

Quando si crea un progetto si deve scegliere una di queste quattro alternative e questa scelta è difficile da cambiare in seguito, quindi ci si dovrebbe pensare un momento prima di iniziare.

### Tutorial su Autoconf/Automake/Libtool

Esistono diversi tutorial disponibili sul sistema di compilazione &GNU; usato dal Gestore Automake (`Autoconf`, `Automake` e `Libtool`).

- Un breve tutorial su autoconf scritto da Christopher W. Curtis è disponibile sulla home page di KDevelop. Esso illustra in pochi passi le istruzioni su come modificare un `Makefile`.

- Un tutorial più dettagliato può essere trovato qui: Sviluppo di software con GNU.

- E questo è il famoso Goat Book inititolato Autoconf, Automake and Libtool. È un'introduzione concisa e facile da leggere ai principali aspetti degli Autotool &GNU;.

### Cosa fa il Gestore Automake?

Quando si crea un Nuovo progetto che usa il sistema di compilazione &GNU;, come C++ KDE Application Framework, la procedura guidata imposta i primi file `Makefile.am`.

Ci sarà un file `Makefile.am` in ogni directory del progetto, che conterrà le istruzioni per compilare, costruire e installare i file, assieme ad un riferimento ad eventuali sottodirectory che avranno a loro volta un file `Makefile.am` e altri file da compilare, costruire ed installare.

La directory del progetto e i file sorgente possono essere strutturati a qualunque livello di profondità, oppure si può preferire una struttura piatta con tutte le sottodirectory al livello più alto.

Lo scopo del sistema di compilazione &GNU; consiste nel produrre strutture di file sorgenti che possano essere compilati e installati su ogni sistema &UNIX; o &Linux; usando questi semplici comandi:

    ./configure
    make
    make install    # Normalmente come "root".

e possano essere disinstallati dal comando `make uninstall` (normalmente come utente root).

Come funziona? `configure` è uno script che

- risolve le problematiche relative ai dettagli del sistema in cui si trova, come quale compilatore e librerie usare e dove sono localizzate

- crea file `Makefile` ricorsivi completando le sostituzioni nei corrispondenti file `Makefile.in`.

I `Makefile.in` sono file di input — modelli che forniscono le informazioni di base per i `Makefile` che saranno prodotti a partire da essi utilizzando alcune informazioni relative al sistema. Essi sono generati dall'utility `Automake` a partire dai file `Makefile.am`.

Il processo che parte dai `Makefile.am` (`.am` significa file modello di Automake) fino ad arrivare ai file `Makefile` viene gestito automaticamente dal &promanag; di &kdevelop;, usando l'utility `Autoconf`, le macro `M4` e altre cose arcane in cui non è necessario addentrarsi.

In questo modo, quando viene avviato `make`, esso ottiene automaticamente i componenti corretti dal sistema, come compilatori e librerie. Analogamente, `make install` installa i componenti dell'applicazione, come i file eseguibili, la documentazione e i file di dati nei posti corretti per quell'ambiente.

Se si distribuisce l'applicazione come tarball (un singolo file compresso che può essere creato da &kdevelop;), saranno inclusi i file `Makefile.in` e il file script `configure`, in modo che il destinatario potrà compilare e installare l'applicazione senza possedere sul proprio computer `Automake`, `Autoconf` o &kdevelop;. Vengono inclusi anche i file `Makefile.am`, nel caso in cui il destinatario debba fare qualche modifica al codice sorgente.

Le regole sono piuttosto diverse se si distribuisce attraverso un repository di codice sorgente come il &cvs; di &kde;.

### Riassunto delle funzioni del Gestore Automake

- Genera i file `Makefile.am` nelle sottodirectory conosciute come sottoprogetti.

- Aggiorna i file `Makefile.am` quando cambia la struttura del progetto.

- Aggiorna i file `Makefile.am` quando vengono aggiunti o rimossi dei file dal progetto.

- Interpreta le definizioni sulla compilazione e installazione dei vari file e modifica adeguatamente i file `Makefile.am`.

- Accetta i parametri usati nella compilazione o installazione (ad es. i nomi di libreria) e si assicura che siano usati nelle fasi di compilazione.

### Contenuti dei file Automake

Le linee di un file `Makefile.am` contengono nomi di variabile seguiti dal segno di uguale e una lista di file o parametri. Le variabili hanno nomi costituiti da due parti, come `bin_PROGRAMS`, `myapp_SOURCES` o `kdelnk_DATA`. La seconda parte è detta primaria e rappresenta qualcosa da compilare o installare. La prima parte è chiamata il prefisso e rappresenta:

- Una directory nella quale effettuare l'installazione (ad es. `bin`),

- Un qualificatore per la parte primaria (ad es. `myapp` per `SOURCES`, indicando che i file sorgente elencati dopo `myapp_SOURCES` finiranno nella compilazione di `myapp`),

- Lo speciale prefisso `noinst` (abbreviazione per nessuna installazione), normalmente usato per elencare i file header (`.h`),

- O lo speciale prefisso `EXTRA`, per tutte le cose dipendenti dalla configurazione.

Per ulteriori informazioni sui file `Automake` e `Makefile.am`, controllare `info Automake`.

Fondamentalmente il gestore Automake crea e aggiorna i nomi delle variabili e le liste di file o parametri. Vedere il seguente esempio di un `Makefile.am` per una applicazione tipica chiamata `myapp`.

    ## Makefile.am for myapp

    # questo è il programma che viene installato. Il suo nome è usato per
    # tutte le altre variabili del Makefile.am
    bin_PROGRAMS = myapp

    # impostare i percorsi di include per X, qt e KDE
    INCLUDES = $(all_includes)

    # percorso di ricerca per le librerie.
    myapp_LDFLAGS = $(KDE_RPATH) $(all_libraries)

    # le librerie con cui verrà fatto il link.
    myapp_LDADD   = $(LIB_KFILE) $(LIB_KDEPRINT)

    # quali file sorgente dovrebbero essere compilati per myapp
    myapp_SOURCES = main.cpp myapp.cpp myappview.cpp

    # questi sono gli header per il proprio progetto
    noinst_HEADERS = myapp.h myappview.h

    # permetti ad automoc di gestire tutti i metafile (moc)
    METASOURCES = AUTO

    KDE_ICON = myapp

    # qui è dove andrà il file kdelnk
    kdelnkdir = $(kde_appsdir)/Utilities
    kdelnk_DATA = myapp.desktop

    # qui è dove vanno i file risorsa XML-GUI
    rcdir = $(kde_datadir)/myapp
    rc_DATA = myappui.rc

    AM_CXXFLAGS = -DMY_C++_PREPROCESSOR_OPTION

Come si può vedere, molti degli elementi a destra sono simboli del tipo `$(xxxx)`. Queste sono variabili d'ambiente che sono definite nell'attuale ambiente &kde; e vengono sostituite con i veri valori quando `./configure` genera i file `Makefile` finali nel computer destinatario.

Inoltre, è una buona idea avviare il comando `./configure --help` che visualizzerà tutte le opzioni che si possono cambiare nel momento della compilazione. In particolare, il comando:

    ./configure --prefix=/dove/si/desidera

eseguirà l'intera installazione in una struttura di directory a scelta, cambiando il valore della variabile interna `$(prefix)` in `/dove/si/desidera`.

## Operazioni del gestore Automake

In questo capitolo si troverà una descrizione essenziale degli elementi del gestore Automake e sul loro uso. Questo comprende:

- La finestra del gestore Automake descrive la struttura di base della finestra principale del gestore Automake.

- La vista panoramica descrive gli elementi della parte superiore.

- La vista dettagli descrive gli elementi della parte inferiore.

- Navigare nel gestore Automake elenca le operazioni fondamentali che possono essere compiute con il gestore Automake.

- Menu a comparsa del gestore Automake descrive i menu che appaiono quando si seleziona una azione nel gestore Automake.

### La finestra del gestore Automake

- Il gestore Automake funziona in una finestra divisa in due. La parte superiore è chiamata panoramica e la parte inferiore è chiamata dettagli. Tra esse c'è una barra sottile che può essere trascinata con il mouse per modificare la dimensione delle due finestre. Nella modalità IDEAl si può trascinare anche il lato della finestra in modo da modificarne la larghezza.

- Nella parte alta di entrambe le viste c'è una barra degli strumenti, nella quale i pulsanti vengono attivati quando si seleziona un elemento in quella visuale. Questo fornisce un modo per accedere alle azioni disponibili per quell'elemento. Gli altri sono menu contestuali che appaiono con il clic del tasto destro del mouse, come verrà spiegato dopo.

- Nella modalità IDEAl sono presenti due piccoli pulsanti in più nella parte sinistra della barra del titolo della finestra del gestore Automake — un freccia a destra a forma di triangolo e un pulsante con un punto. Il pulsante con la freccia viene usato per chiudere la finestra. Il pulsante con il punto invece manterrà la finestra aperta anche se viene selezionata un'altra finestra di &kdevelop; (Altrimenti la finestra del gestore Automake si chiuderà automaticamente quando un'altra finestra riceve il focus).

### La finestra panoramica

La finestra panoramica contiene una lista ad albero di tutte le directory del progetto che contengono file di programma, documentazione o dati. Ogni directory contiene un file `Makefile.am` e viene riconosciuta dal gestore Automake come un sottoprogetto. Ci sono tre sottoprogetti tipici in un progetto di tipo &kde;, come mostrato nella illustrazione precedente:

- `src` – file sorgente dell'applicazione.

- `doc` – manuale utente o guida,

- `po` – estratti delle stringhe dei file sorgente che devono essere tradotte in altri linguaggi umani (ad esempio titoli delle finestre, nomi di menu, etichette dei pulsanti, testi delle finestre di dialogo e messaggi di vario tipo).

Notare che il sottoprogetto `doc` ha sempre un sottoprogetto `en`, che si può vedere se si fa clic sul simbolo + vicino alla parola `doc`. Questo è dovuto al fatto che il linguaggio di base di tutta la documentazione &kde; è l'inglese (en). Se la propria applicazione farà parte di &kde;, i team di traduzione potranno tradurre la documentazione dall'inglese in altri linguaggi e queste le traduzioni saranno inserite in altri sottoprogetti, come `de` (Tedesco) o `fr` (Francese). Anche le stringhe nel sottoprogetto `po` potranno essere tradotte e memorizzate, consentendo quindi all'applicazione di essere utilizzata dalle persone che non conoscono l'inglese.

I sottoprogetti `doc` e `po` servono a diversi scopi: `doc` contiene la documentazione come il manuale utente, mentre `po` contiene le stringhe di testo traducibili dell'interfaccia utente che è integrata nel codice sorgente dell'applicazione.

La finestra panoramica funziona — tra le altre cose — come strumento di navigazione. Se si seleziona un sottoprogetto nella finestra panoramica verranno visualizzati i dettagli corrispondenti nella finestra dettagli.

### la finestra dettagli

Questa finestra contiene una lista ad albero di tutti i file del sottoprogetto selezionato nella finestra panoramica, così come le regole di compilazione e installazione del sottoprogetto. Quindi le due visuali assieme forniscono un accesso a tutti i componenti dell'applicazione e a tutte le informazioni per compilarla e installarla.

#### Target

La lista ad albero nella finestra dettagli ha due livelli. Il livello principale è composto dai cosiddetti target e il sottolivello contiene la lista dei file che andranno a costruire quel target.

Il concetto di target per il gestore Automake differisce da quello dei target dei file `Makefile`. In breve:

- Il modo in cui deve essere compilato o installato un insieme di file è chiamato target nel Gestore Automake, mentre viene rappresentato come variabile nello stesso `Automake`.

- In `make` un target è spesso qualcosa di completamente differente, essendo il parametro di un comando `make` (ad es. `make install`, `make clean`).

  Comunque, alcune variabili di `Makefile.am` rappresentano un sub-target in `make`.

### Navigare nel gestore Automake

In entrambe le finestre panoramica e dettagli si può cliccare con il tasto sinistro sul simbolo + o - vicino ad un sottoprogetto o al nome di un target per espandere o raggruppare la vista ad albero. Se lo si fa con un sottoprogetto nella finestra panoramica, verrà mostrato o nascosto il sottoprogetto del livello più basso (se esiste). Se lo si fa con un target nella finestra dettagli, verrà mostrata o nascosta la lista dei file relativi di quel target.

#### Aprire un file per la modifica

Se si fa clic con il tasto sinistro sul nome di un file nella finestra dettagli, verrà aperto.

#### Attivare i pulsanti della barra degli strumenti del gestore Automake

Se si fa clic con il tasto sinistro sul nome di un sottoprogetto nella finestra panoramica oppure sul nome di un target nella finestra dettagli, il nome verrà evidenziato e saranno resi attivi alcuni pulsanti nella barra degli strumenti nella parte superiore di quella finestra.

È raccomandato l'uso del pulsante destro del mouse e dei menu a comparsa al posto dei pulsanti della barra degli strumenti, poichè risulta più semplice vedere e capire quello che si sta facendo.

Le operazioni sui sottoprogetti e sui target hanno effetti molto estesi sulla struttura, la compilazione e l'installazione dell'applicazione.

#### Selezionare Azioni/Menu a comparsa

Se si fa clic con il tasto destro del mouse sul nome di un sottoprogetto, target o file apparirà un menu a comparsa con il quale si potranno selezionare le azioni da eseguire su un sottoprogetto, target o file, come aggiungere un target ad un sottoprogetto, aggiungere un file ad un target o rimuovere logicamente il file selezionato dal suo target.

### Menu a comparsa nel gestore Automake

Le sezioni seguenti illustreranno brevemente le operazioni disponibili nei menu contestuali che appaiono quando si fa clic con il tasto destro del mouse nella finestra del Gestore Automake. Questa è solo una panoramica generale, si troveranno le descrizioni dettagliate della maggior parte delle operazioni in un successivo capitolo.

#### Menu a comparsa per un file

Quando si fa clic con il tasto destro sul nome di un file nella finestra dettagli, apparirà il seguente menu a comparsa che permette di scegliere una operazione da effettuare su quel file. Nell'illustrazione seguente viene selezionato il file icona `hi-16app-kdevel.png` del target Dati icona in kde_icon del sottoprogetto myapp/src.

- La voce principale del menu a comparsa per un file è Rimuovi, che rimuove un file dal suo target (cioè non verrà più usato per compilare, costruire o installare quel target).

- La voce CVS fornisce una serie di operazioni CVS per quel file.

- La voce Apri con permette di aprire il file con diversi editor o applicazioni (ad es. si può aprire il file icona dell'esempio con KIcon).

- La voce Perforce è usata in operazioni simili a quelle del CVS, usando il version control system commerciale Perforce.

#### Il menu a comparsa di un target

Quando si fa clic con il tasto destro su un target nella finestra dettagli apparirà il seguente menu, che permetterà di selezionare una delle operazioni da effettuare. Nell'illustrazione seguente è stato selezionato il target myapp (Programma in bin) del sottoprogetto myapp/src.

- La voce Opzioni per un target riguarda solo i file sorgente. Nella finestra di dialogo corrispondente si può specificare i flag del linker, i percorsi per localizzare le librerie e si può fornire una lista di librerie con cui effettuare il link nell'applicazione.

- La voce Crea nuovo file mostrerà una finestra di dialogo nella quale si potrà impostare il nome e il tipo di file che sarà generato (da una lista).

- La voce Aggiungi file esistenti visualizza una finestra di dialogo nella quale si può aggiungere al progetto dei file esistenti.

- La voce Rimuovi per un target permette di rimuovere logicamente un target e tutti i suoi file dalla struttura del progetto.

- La voce Rendi target attivo si riguarda solo i target che contengono codice sorgente. I nuovi file verranno sempre aggiunti ad un target attivo.

- La voce Compila target avvia tutte le operazioni di compilazione per costruire il codice solo di questo target.

#### Il menu a comparsa per un sottoprogetto.

Quando si fa clic con il tasto destro su un sottoprogetto nella finestra panoramica apparirà il seguente menu a comparsa che permetterà di effettuare cambiamenti alla struttura del progetto e al modo in cui sarà compilato, costruito e installato. Lo si può usare per espandere o modificare la struttura iniziale del progetto costruita dalla procedura guidata.

- La voce Opzioni controlla il modo in cui un sottoprogetto verrà compilato, costruito e installato. La finestra di dialogo che appare possiede le etichette per le opzioni che riguardano la compilazione, le directory include, i prefissi e l'ordine di costruzione.

- La voce Aggiungi sottoprogetto crea una nuova directory e lo scheletro di un file Makefile.am.

- La voce Aggiungi Target fa comparire una finestra di dialogo con la quale si possono impostare le regole per la compilazione, la costruzione o l'installazione di un gruppo di file all'interno del sottoprogetto.

- Aggiungi servizio (... da scrivere ...)

- Aggiungi Applicazione (... da scrivere ...)

- Aggiungi sottoprogetti esistenti (... da scrivere ...)

- Il modo appropriato per rimuovere un sottoprogetto consiste nell'uso della voce Elimina sottoprogetto del menu a comparsa del un sottoprogetto. Verranno corretti i file `Makefile.am`. Sarà mostrata l'opzione di cancellare tutti i file (o collegamenti) della directory corrispondente. Ovviamente, questa caratteristica dovrebbe essere usata con cautela.

- La voce Compila avvia le operazioni necessarie per compilare solo il codice di quel sottoprogetto.

- Forza Reedit (... da scrivere ...)

- Ripulisci (... da scrivere ...)

- Installa (... da scrivere ...)

- Installa (come superutente) (... da scrivere ...)

## Progetti automake

(... da scrivere ...)

### Autoconf

#### Effetti dello script configure

da `Makefile.in` a `Makefile`

    prefix = @prefix@
    INSTALL = @INSTALL@
    build_triplet = @build@
    CXX = @CXX@

    prefix = /home/bernd/kde3
    INSTALL = /usr/bin/ginstall -c -p
    build_triplet = i686-pc-linux-gnu
    CXX = g++

da `config.h.in` a `config.h`

    /* Define if you have libz */
    #undef HAVE_LIBZ
    /* The size of a `int', as computed by sizeof. */
    #undef SIZEOF_INT

    /* Define if you have libz */
    #define HAVE_LIBZ 1
    /* The size of a `int', as computed by sizeof. */
    #define SIZEOF_INT 4

### Automake

(... da scrivere ...)

### Gestore Automake di &kdevelop;

#### Uno screenshot del gestore automake

### Compilare e installare librerie

- -rpath

- PIC

- static

- plugins: no-undefined

## Makefile e script di compilazione personalizzati

(... da scrivere ...)

## Opzioni del compilatore

(... da scrivere ...)

## Opzioni Make

(... da scrivere ...)