Come compilare un programma in C con GCC
Per compilare un programma in linguaggio C con il compilatore GCC uso questa sintassi
gcc nome.c -o nome
Dove nome.c è il file con il programma sorgente scritto in linguaggio C.
L'opzione -o precede il nome del file eseguibile che voglio creare.
Nota. In mancanza dell'opzione -o il compilatore GCC crea un file eseguibile con nome a.out.
Il compilatore non fornisce alcun messaggio se la compilazione va a buon fine, ma segnala solo eventuali warning o errori.
Quindi, se dopo aver dato invio torna il cursore lampeggiante sul prompt, la compilazione è andata bene.
Un esempio pratico
Scrivo un semplice programma in C
#include <stdio.h>
int main() {
int a = 1;
printf("hello world\n");
return 0;
}
Lo salvo con nome prova.c
Per tradurre il sorgente C in un file eseguibile digito
gcc prova.c -o prova
Il compilatore crea un file oggetto eseguibile con il nome prova.
Nota. In questo caso sto lavorando su Linux, ma su Windows il processo è simile. Su Windows il nome eseguibile deve avere estensione .exe e può essere eseguito semplicemente digitando il nome del file exe dal prompt dei comandi.
La compilazione non ha dato errori.
A questo punto eseguo il file eseguibile su Linux per vedere se funziona.
./prova
Nota. Per eseguire il file su Windows basta digitare prova.exe
Sullo schermo appare la scritta
hello world
Le fasi della compilazione
Il compilatore GCC mi permette anche di compilare step by step un programma C.
Preprocessamento
gcc -E programma.c -o programma.i
L'opzione -E prende in input un programma scritto in linguaggio C, esegue le operazioni di preprocessamento (direttive, include, ecc.) e crea in output (-o) un file con estensione .i
Codifica in assembly
gcc -S programma.i -o programma.s
L'opzione -S prende in input il codice sorgente di un programma C già preprocessato, lo converte in linguaggio assembly e crea in output un file con estensione .s
Assemblatore
gcc -c programma.s -o programma.o
L'opzione -c prende in input il codice sorgente del programma in assembly, lo assembla ossia lo trasforma in linguaggio macchina e crea in output un file oggetto con estensione -o
Nota. Per fare l'operazione inversa utilizzo il programma objdump che prende in input un file oggetto con estensione .o e lo converte in un file sorgente assembly. Ad esempio objdump -d programma.o oppure objdump -d programma.o > filedump.s
Linker
gcc file.o -o programma
Il linker collega gli oggetti tra loro creando un file eseguibile.
Per utilizzare il linker tra più file oggetto basta elencarli uno dopo l'altro.
gcc file1.o file2.o -o programma
In questo caso il linker collega gli oggetti tra loro e crea un unico file eseguibile.
Nota. Il processo di compilazione in più fasi (-E, -S, -c) è utile per la comprensione del funzionamento del compilatore, ma che normalmente gcc programma.c -o programma esegue automaticamente tutti questi passaggi.
E così via.