Sei sulla pagina 1di 7

CAPITOLO 9

COMPILARE IN UNIX, GCC E MAKEFILE


Genericamente, i programmi responsabili della traduzione da un linguaggio ad alto
livello a programmi scritti in linguaggio macchina sono detti traduttori.
Essi normalmente si distinguono in Compilatori ed Interpreti:
- gli interpreti traducono di volta in volta la singola istruzione in linguaggio
macchina e quindi devono essere sempre attivi durante l'esecuzione del
programma principale.
Passano alla cpu riga per riga, il programma in esecuzione.
La shell un esempio di interprete, che quindi risulta essere lento.
- i compiatori invece, traducono lintero file sorgente (scritto nel linguaggio del
programma in esame) in file oggetto, scritto in codice macchina. Dopo di vi
unoperazione di linking per integrare i vari moduli cui il programma fa
riferimento (ad esempio le librerie); viene cos creata ununica unit eseguibile.
STANDARD DI UNIX
UNIX segue la famigia di standard POSIX, ovvero gli standard indicati formalmente
con IEEE 1003.1.
Posix lacronimo di Portable Operating System Interface, esso mira alla portabilit
dei programmi e ne guida limplementazione.
Posix
-

costituito da tre parti:


System API (system calls, networking)
Shell e editor (vi, awk)
System administration

ANSI C
Il C un linguaggio standardizzato dallANSI, American National Standards Institute,
nel 1983.
Lo standard di tale linguaggio ne consente la portabilit e la conformit della sintassi e
della libreria standard.
UNIX scritto in linguaggio C.
Sezione A - gcc
Lacronimo gcc sta per GNU Compiler Collection, si tratta di un compilatore ed in
quanto tale il suo compito tradurre un codice sorgente in codice macchina che possa
poi essere eseguito.
In realt non fa solo questo, il compilatore infatti, oltre a trasformare le istruzioni in
linguaggio macchina (binario), genera gli indirizzi nei quali il programma deve essere
allocato. Il programma da eseguire va allocato in memoria centrale e il compilatore
funge da allocatore di spazio nella memoria RAM.
Il compilatore gcc, nato come compilatore per C, ma ora mostra vari front end
(traduttori di codice sorgente) per molti altri linguaggi; tra i quali citiamo C/C+
+/Objective-C, Ada, Fortran, Java.
Questo compilatore molto utilizzato su UNIX ed il compilatore standard di Linux.
molto flessibile, ma soprattutto portabile:funziona infatti su molte piattaforme tra
cui GNU/Linux, BSD, Windows.
I passi della compilazione

gcc processa i file in input attraverso uno o pi dei seguenti passi:


1. Preprocessing
Fase durante la quale controlla la sintassi e interpreta speciali direttive per il
preprocessore denotate da #.
Il file in questa fase ha estensione .c
2. Compilazione
Durante la quale controlla la sintassi del programma.
Il file ha estensione .s
3. Assemblaggio
In questa fase viene generato il file oggetto, scritto in linguaggio macchina.
Il file ha estensione .o
4. Linking
In questa fase vi la combinazione delle funzioni definite in altri file sorgente o
definite in librerie con la funzione main() per creare il file eseguibile.
Il file a.out ed eseguibile.
I nomi
*.c
*.h
*.i
*.s
*.S
*.o
*.a
*.so
a.out

dei file dingresso e di uscita devono rispettare le seguenti convenzioni:


Sorgenti C (Programma scritto in linguaggio ad alto livello)
Header
Sorgenti che non devono essere preprocessati
Codice assembly simbolico puro
Codice assembly simbolico da preprocessore
Codice oggetto
Libreria statica
Libreria dinamica
Eseguibile di default

possibile fermare il processo di compilazione ad un punto qualsiasi del flusso


mediante opportune opzioni sulla linea di comando.
Opzioni di gcc
Il gcc supporta centinaia di opzioni, nel seguito descriviamo solo le principali suddivise
per classe.
Opzioni generali:
-- help
Stampa un sommario delle opzioni
-- version
Stampa la versione di gcc
-v
Stampa i comandi corrispondenti alle diverse fasi
- x language Specifica il linguaggio dei file sorgenti. Se assente, si basa
sullestensione
-- pipe
Usa delle pipe tra uno stadio e il successivo
Opzioni per il controllo del flusso:
-E
Arresta il flusso dopo il preprocessing e stampa il codice ottenuto sullo
standard output
-S
Arresta il flusso dopo la compilazione e genera un file assembly simbolico
-c
Arresta il flusso dopo lassemblaggio e genera un file oggetto
-o file Specifica il nome del file di uscita (non quello di default)
Opzioni per i messaggi di warning:
- pedantic
Segnala come warning o come errore ogni discrepanza dallo standard
ANSI
-w
Sopprime tutti i messaggi di warning
- wunused
Segnala le variabili non utilizzate

wuninitialize
d
- wall

Segnala le variabili automatiche non utilizzate


Attiva tutte le opzioni di warning

Sezione B Makefile
make un'utility di Unix utilizzata per conservare, aggiornare e ricreare file relativi ad
un dato progetto tenendo conto delle dipendenze che questi hanno con altri file e tra
di loro.
Affinch make svolga il suo compito ha bisogno di un file, chiamato makefile, in cui
siano descritte le cosiddette:

regole di dipendenza

azioni da eseguire

I makefile sono file di testo che consentono di specificare e gestire le dipendenze che
intercorrono tra un certo gruppo di file.
Storicamente i makefile sono stati inventati per coadiuvare il lavoro dei programmatori
minimizzando i tempi di compilazione dei programmi e gestendo in maniera
automatica le dipendenze tra i vari moduli.
In un progetto possiamo mettere pi file sorgente (.c), il principale sempre main.
Pu accadere che dei file siano dipendenti tra loro; ad esempio, supponiamo che il file
file.o dipenda da file.c e da t.h e r.h, in terminologia make avremo:
- file.o detto target (obiettivo), scritto in linguaggio macchina.
La macchina pu leggerlo ma non pu eseguirlo.
- file.c, t.h, r.h costituiscono una dependency list
makefile permette di esprimere cosa deve fare il sistema per aggiornare il target
se uno dei file nella dependency list stato modificato.
Ad esempio, se qualcuno ha modificato file.c, t.h e r.h, per aggiornare file.o si
pu semplicemente ricompilare file.c usando il comando

gcc -Wall -pedantic -c file.c


tramite questo comando possiamo aggiornare la compilazione solo delle parti
modificate.
In terminologia make, la regola di aggiornamento di uno o pi target viene detta
make rule.
Lidea fondamentale
- descrivere tutte le azioni che devono essere compiute per mantenere il sistema
consistente, come make rule in un file (makefile)
- usare il comando make per fare in modo che tutte le regole descritte da
makefile vengano applicate automaticamente al sistema.
FORMATO DELLE MAKE RULE
Come abbiamo detto, nel file makefile sono contenute le make rule, ossia le regole di
dipendenza e le azioni da eseguire.

Una regola di dipendenza formata da una parte sinistra contenente il target che
deve essere creato e la parte destra contiene i file da cui dipende il file target.
Le due parti sono separate da ":", per cui il suo formato pi semplice Target list

Dependency list
L'azione viene scritta nella linea sotto i file di dipendenza e ricordiamo che tale linea
DEVE iniziare con un separatore Tab e non con uno spazio.
Per cui il suo formato pi semplice Target list : Dependency list

Comando 1

Lista di comandi
Comando n
1. Riprendendo lesempio precedente, possiamo scrivere:

file.o : file.c t.h r.h


gcc -Wall -pedantic -c file.c
2. Vediamo ora un esempio di file con pi regole:

exe : f.o r.o


gcc f.o r.o -o exe
f.o : f.c t.h r.h
gcc -Wall -pedantic -c f.c
r.o : r.h r.c
gcc -Wall -pedantic -c r.c
Nella prima linea abbiamo i target, sottolineiamo che si DEVE mettere exe alla
prima linea, in quanto il file eseguibile non pu essere eseguito prima degli
oggetti. Mentre le due linee successive possono anche essere invertite.
Inoltre osserviamo che tra due regole DEVE esserci almeno una linea vuota.
Infine, il file DEVE terminare con un newline.
Come si deduce dallesempio, lordine delle regole importante in quanto make
costruisce lalbero delle dipendenze a partire dalla prima regola del makefile.
In questo albero, i target della prima regola trovata sono la radice (exe),

ex
mentre ogni nodo della dependency list della radice viene appeso come foglio
(f.o, r.o)

exe
f.o

r.o

Poi, si visitano le foglie e si aggiungono le dipendenze allo stesso modo


(si considerano le regole che hanno f.o e r.o come target)

exe
f.o
f.c

r.o

r.o
r.h

r.c

La generazione dellalbero termina quando non ci sono pi regole che hanno


come target una foglia.
Come viene usato lalbero
Per ogni nodo X, si controlla che il tempo dellultima modifica del padre sia successivo
al tempo dellultima modifica di X.

exe
t2

f.odella regola
r.o
Se t1 > t2, si esegue la command list
che ha coma target il padre.

gcc -Wall -pedantic -c f.c


t1

f.c

r.o

r.h

r.c

Se il file corrispondente ad un nodo X non esiste (ad esempio stato rimosso), si


esegue comunque la regola che ha come target X.

gcc -Wall -pedantic -c f.c


Come se esegue il make
Se il file delle regole si chiama makefile, basta eseguire
> make
altrimenti
> make f nomefile

gcc -Wall -pedantic -c f.c


>
Stampa dei comandi eseguiti per aggiustare i tempi sullalbero delle dipendenze.
possibile specificare una radice dellalbero diversa dal target nella prima regola del
file.
Per farlo, dobbiamo passare il nome del target come parametro al make.
Ad esempio:
> make f.o
In questo caso creiamo solo il seguente sottoalbero

f.o
f.c

r.o

r.h

Variabili
possibile usare delle variabili per semplificare la scrittura del makefile.
Queste possono essere:
stringhe di testo definite una volta ed usate in pi punti
Ad esempio
# nomi oggetti

objects = r.o f.o

regole
exe : $ (objects)
ccc $(objects) -o exe
#

variabili predefinite che permettono di comunicare al make le nostre preferenze


Ad esempio:
1. quale compilatore C utilizzare per la compilazione
CC = gcc
2. le opzioni di compilazione preferite
CFLAGS = -Wall -pedantic

Regole implicite
Le regole viste finora sono pi estese del necessario.
Infatti make conosce gi delle regole generali di dipendenza fra file, basate sulle
estensioni dei nomi.
Ad esempio, nel caso di C, il make sa gi che per aggiornare XX.o necessario
ricompilare il corrispondente XX.c usando $CC e $FLAGS.
Quindi una regola della forma XXX.o : XXX.c t.h r.h

gcc -Wall -pedantic -c XXX.c


equivalente a

XXX.o : XXX.c t.h r.h


$ (CC) $ (CFLAGS) XXX.c

E sfruttando le regole implicite del make pu essere riscritta come

XXX.o : XXX.c

t.h r.h
Riscriviamo il nostro esempio con le regole implicite e le variabili:

CC = gcc
CFLAGS = -Wall -pedantic -o exe
objects = f.o r.o
exe : f.o r.o
$ (CC) $ (OBJECTS) -o exe
f.o : t.h r.h
r.o : r.h
Phony target
possible specificare target che non sono file e che hanno come scopo solo
lesecuzione di una sequenza di azioni.
Ad esempio

Clean :
rm $ (exe) $ (objects) *~ core

(core un file particolare, generato ogni volta che si verifica un errore di sistema nelle nostre
procedure. Solitamente UNIX non sin ferma per errori di questo tipo.)

Siccome la regola non crea nessun file chiamato


ogni volta che invoco
> make clean

clean, il comando rm verr eseguito

Clean un target fittizio (phony) inserito per provocare lesecuzione del comando in
ogni caso.
Questo stile di programmazione tipico ma ha qualche controindicazione:
se casualmente nella directory viene creato un file chiamato clean il gioco non
funziona pi, siccome la dependency list vuota sempre aggiornato, ed
inefficiente, il make cerca prima in tutte le regole implicite per cercare di risolvere
una cosa che messa apposta per essere risolta.
La soluzione prendere labitudine di dichiarare esplicitamente i target

.PHONY : clean
clean :
-rm $ (exe) $ (objects) *~core
rm significa che lesecuzione del make pu continuare anche in caso di errori
nellesecuzione del comando rm (ad esempio, uno dei file specificati non c).

Potrebbero piacerti anche

  • Appunti Struttura Della Materia
    Appunti Struttura Della Materia
    Documento19 pagine
    Appunti Struttura Della Materia
    Ange
    Nessuna valutazione finora
  • Cocktail
    Cocktail
    Documento2 pagine
    Cocktail
    Ange
    Nessuna valutazione finora
  • Diagramma Di Stato Acqua
    Diagramma Di Stato Acqua
    Documento1 pagina
    Diagramma Di Stato Acqua
    Ange
    Nessuna valutazione finora
  • Capitolo 9
    Capitolo 9
    Documento7 pagine
    Capitolo 9
    Ange
    Nessuna valutazione finora
  • Svilippo in Serie Fourier 01
    Svilippo in Serie Fourier 01
    Documento20 pagine
    Svilippo in Serie Fourier 01
    cadiz
    Nessuna valutazione finora
  • Capitolo 8
    Capitolo 8
    Documento6 pagine
    Capitolo 8
    Ange
    Nessuna valutazione finora
  • Appunti Struttura Della Materia
    Appunti Struttura Della Materia
    Documento19 pagine
    Appunti Struttura Della Materia
    Ange
    Nessuna valutazione finora
  • Capitolo 7
    Capitolo 7
    Documento5 pagine
    Capitolo 7
    Ange
    Nessuna valutazione finora
  • Echo
    Echo
    Documento2 pagine
    Echo
    Ange
    Nessuna valutazione finora
  • Rumore Nei Circuiti
    Rumore Nei Circuiti
    Documento11 pagine
    Rumore Nei Circuiti
    Rhoen
    Nessuna valutazione finora
  • Capitolo 6
    Capitolo 6
    Documento13 pagine
    Capitolo 6
    Ange
    Nessuna valutazione finora
  • Capitolo 5
    Capitolo 5
    Documento6 pagine
    Capitolo 5
    Ange
    Nessuna valutazione finora
  • Capitolo 4
    Capitolo 4
    Documento5 pagine
    Capitolo 4
    Ange
    Nessuna valutazione finora
  • Capitolo 2
    Capitolo 2
    Documento19 pagine
    Capitolo 2
    Ange
    Nessuna valutazione finora
  • Capitolo 3
    Capitolo 3
    Documento12 pagine
    Capitolo 3
    Ange
    Nessuna valutazione finora
  • Essenza Di Unix
    Essenza Di Unix
    Documento11 pagine
    Essenza Di Unix
    Ange
    Nessuna valutazione finora
  • Echo
    Echo
    Documento2 pagine
    Echo
    Ange
    Nessuna valutazione finora
  • Bash
    Bash
    Documento2 pagine
    Bash
    Ange
    Nessuna valutazione finora