🔝 Retour au Sommaire
Lorsque vous écrivez un programme en C et que vous exécutez la commande gcc, il se passe bien plus qu’une simple « transformation » de votre code. En quelques fractions de seconde, votre fichier texte traverse une chaîne de compilation complexe composée de plusieurs outils distincts, chacun avec sa mission spécifique.
Comprendre cette chaîne est l’une des compétences fondamentales de tout développeur C. Ce n’est pas seulement de la théorie : cette connaissance vous servira au quotidien pour résoudre des problèmes, optimiser vos builds et maîtriser votre environnement de développement.
Quand vous débutez en C, les messages d’erreur peuvent sembler cryptiques :
undefined reference to `ma_fonction'
error: expected ';' before 'return'
warning: implicit declaration of function 'printf'
Ces erreurs proviennent de différentes étapes de la compilation. Savoir les distinguer vous permet de :
Une compréhension approfondie de la chaîne de compilation permet de :
Dans un contexte DevOps, maîtriser la chaîne de compilation est essentiel pour :
Voici le voyage que fait votre code C :
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ VOUS VOTRE ORDINATEUR │
│ │
│ ┌─────────┐ ┌─────────────┐ │
│ │ │ │ │ │
│ │ Écrit │ │ Exécute │ │
│ │ du │ │ le │ │
│ │ code │ │ programme │ │
│ │ │ │ │ │
│ └────┬────┘ └──────▲──────┘ │
│ │ │ │
│ │ │ │
│ ▼ │ │
│ ┌─────────┐ ┌─────────────────────┐ ┌────────┴────┐ │
│ │ │ │ │ │ │ │
│ │ hello.c │ ──────▶ │ CHAÎNE DE │ ──────▶ │ hello │ │
│ │ │ │ COMPILATION │ │ (exécutable)│ │
│ │ (texte) │ │ │ │ (binaire) │ │
│ └─────────┘ │ ┌───┐ ┌───┐ ┌───┐ │ └─────────────┘ │
│ │ │ 1 │▶│ 2 │▶│...│ │ │
│ │ └───┘ └───┘ └───┘ │ │
│ │ │ │
│ │ "La magie" │ │
│ │ (qu'on va │ │
│ │ démystifier) │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Ce qui semble être une seule commande :
gcc hello.c -o hello
Cache en réalité plusieurs programmes qui s’exécutent en séquence, chacun transformant votre code d’une forme à une autre.
La chaîne de compilation fait intervenir plusieurs outils. Voici les principaux :
Le préprocesseur est le premier maillon. Il traite votre code source avant toute compilation :
#include, #define, #ifdef…Le compilateur proprement dit transforme le code C en code assembleur :
L’assembleur convertit le code assembleur en code machine :
.o)L’éditeur de liens (ou linker) assemble le tout :
Quand vous utilisez gcc, vous n’appelez pas directement chacun de ces outils. GCC agit comme un pilote (driver) qui orchestre toute la chaîne :
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ GCC (le pilote) │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ "Je reçois vos fichiers .c et vos options, et je coordonne │ │
│ │ tous les outils pour produire l'exécutable final." │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ │
│ ┌──────────────────────┼──────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ cpp │ │ cc1 │ │ as │ │
│ │ │──────────▶│ │──────────▶│ │───────┐ │
│ │ Prépro- │ │ Compi- │ │ Assem- │ │ │
│ │ cesseur │ │ lateur │ │ bleur │ │ │
│ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ ld │ │
│ │ │ │
│ │ Éditeur │ │
│ │ de liens│ │
│ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
C’est pourquoi on dit souvent « compiler avec GCC » même si techniquement, GCC fait bien plus que compiler.
À chaque étape de la chaîne, un nouveau fichier est créé :
| Étape | Fichier d’entrée | Fichier de sortie | Extension |
|---|---|---|---|
| Préprocesseur | Code source | Code prétraité | .c → .i |
| Compilation | Code prétraité | Code assembleur | .i → .s |
| Assemblage | Code assembleur | Fichier objet | .s → .o |
| Édition de liens | Fichiers objets | Exécutable | .o → (aucune) |
Ces fichiers intermédiaires sont normalement temporaires et supprimés après la compilation. Mais comme nous le verrons, il est possible de les conserver et de les examiner pour mieux comprendre ce qui se passe.
Dans ce chapitre, nous allons explorer en détail chaque aspect de la chaîne de compilation :
Nous examinerons chacune des quatre étapes de la compilation, en comprenant précisément ce qui se passe à chaque phase et quels types d’erreurs peuvent survenir.
Nous visualiserons concrètement le pipeline de compilation avec des schémas et des exemples, pour voir comment votre code se transforme étape par étape.
Nous découvrirons les options GCC les plus importantes : warnings, débogage, optimisation, standards C, et bien d’autres.
Nous décortiquerons entièrement le programme Hello World pour comprendre tout ce qui se cache derrière ces quelques lignes de code apparemment simples.
Nous apprendrons à conserver et examiner les fichiers intermédiaires (.i, .s, .o) pour comprendre ce que fait réellement le compilateur.
Nous explorerons le concept de symboles, essentiel pour comprendre comment les différentes parties de votre programme sont liées ensemble.
Pour suivre ce chapitre, vous devez avoir :
Si vous n’avez pas encore configuré votre environnement, référez-vous au chapitre 2 « Configuration de l’environnement Ubuntu ».
# Vérifier que GCC est installé
gcc --version
# Vérifier que les outils d'analyse sont disponibles
which objdump nm readelf
Avant de plonger dans les détails, voici un avant-goût de ce que nous allons explorer. Créez un fichier demo.c :
#include <stdio.h>
int main(void) {
printf("Bienvenue dans la chaîne de compilation !\n");
return 0;
}
Et observez ce qui se passe avec le mode verbeux de GCC :
gcc -v demo.c -o demo
Vous verrez défiler de nombreuses lignes montrant les différents programmes appelés, les chemins des fichiers, et les options utilisées. Ne vous inquiétez pas si cela semble complexe pour l’instant : à la fin de ce chapitre, vous comprendrez chaque ligne de cette sortie.
Dans les sections suivantes, nous utiliserons ces conventions :
$ omisexemple.c, programme.o, etc.)Chaque section est conçue pour être lue dans l’ordre, mais peut aussi servir de référence indépendante.
La chaîne de compilation peut sembler intimidante au premier abord, mais une fois que vous en comprendrez les mécanismes, vous aurez une vision beaucoup plus claire de ce qui se passe quand vous développez en C.
Vous ne verrez plus jamais la commande gcc de la même façon !
Passons maintenant à la première section : Les 4 Étapes Détaillées.