Il Compilatore GCC su Linux

Il compilatore C/C++ GCC della GNU Free Software Foundation è disponibile ormai su tutti i sistemi Unix; la sigla GCC originariamente stava per “GNU C Compiler”, sviluppato molto tempo fa da Richard Stallman, creatore dello stesso progetto GNU e successivamente utilizzato dagli sviluppatori Linux per l’implementazione del sistema operativo. Oggi, al momento in cui scrivo questo articolo, siamo arrivati alla versione 4.5.0 del compilatore, che non compila solo il C/C++, ma anche Fortran e Java e per questo la sigla GCC significa quest’oggi “GNU Compiler Collection”. Nel 1991 la versione 1 del compilatore aveva ormai raggiunto un buon punto di stabilità e nella versione 2 si cercava di riscrivere il design del compilatore per migliorarlo ulteriormente. La Cygnus aveva iniziato, intanto, a sviluppare il compilatore egcs, che per un certo periodo era un’ottima alternativa al gcc, anche se continuava ad avere problemi con il kernel 2.0.x, che furono poi risolti con la versione del kernel 2.2.x. Nell’aprile del 1999 la Free Software Foundation ha ufficialmente interrotto lo sviluppo della versione 2 del gcc, nominando maintainer ufficiali quelli del progetto egcs, arrivando quindi alla versione 2.95.2 rilasciata nell’ottobre del 1999. Oggi sapete tutti la storia, prima la versione 3 e poi la versione 4 attuale. Si tenga presente che il gcc viene utilizzato per compilare i sorgenti del gcc stesso, e anche per creare dei cross compiler, cioé dei compilatori in grado di compilare programmi su processori differenti.
Un compilatore è un programma che traduce da un linguaggio detto sorgente in un altro linguaggio detto target. Nel nostro caso il linguaggio sorgente è il C ed il linguaggio target è il linguaggio macchina binario, formato cioé da 0 e 1. Anche se un programmatore fosse bravissimo sarebbe difficilissimo scrivere un programma completo in linguaggio macchina, quindi se ne utilizza uno a più alto livello, sarà poi compito del compilatore trasformare questo linguaggio ad alto livello in codice macchina creando l'”eseguibile”.
Come esempio prendiamo il classico programma HelloWorld, il sorgente in C ( hello.c ) sarà:

/* classico programma per iniziare a programmare */
#include <stdio.h>
int main()
{
   printf("Ciao Mondo!\n");
}

per compilare il programma occorre dare il comando:

gcc -o hello hello.c

e potremmo eseguire il programma con il comando:

./hello

attenzione ad inserire il punto con lo slash perché questa directory non è in PATH.
L’opzione -o del compilatore gcc indica il nome del file di output e nel nostro esempio abbiamo creato direttamente l’eseguibile; se volessimo creare prima l’oggetto e poi effettuare il linking, dobbiamo dare questi due comandi:

gcc -c hello.c
gcc -o hello hello.o

il primo crea l’oggetto ( hello.o ) ed il secondo crea l’eseguibile vero e proprio effettuando il linking con le librerie appropriate standard del C. Potete notare che abbiamo utilizzato sempre lo stesso comando, sia per compilare che per linkare, in effetti il comando gcc è un front end per i vari comandi che compongono la “suite” del gcc e provvederà, basandosi sull’estensione del file che passiamo come argomento, a richiamare i metodi opportuni: nel primo caso chiamerà il compilatore insieme al preprocessore cpp, mentre nel secondo caso chiamerà il linker ld passandogli anche le librerie standard.
Conoscere il compilatore del sistema operativo sul quale si lavora è estremamente importante, anche solo per i principi di funzionamento, come abbiamo spiegato in questo articolo. In un prossimo post ho intenzione di spiegare le varie opzioni per la compilazione e soprattutto come creare i Makefile per la gestione dei grandi progetti.

Pubblicato
Categorie: Linux Taggato

Di Giampaolo Rossi

Sviluppatore software da oltre 16 anni.