359 lines
4.2 KiB
Markdown
359 lines
4.2 KiB
Markdown
# Chapitre 3 — Outils et chaîne de compilation
|
||
|
||
## 3.1 Compilateurs : rôle et implémentations
|
||
|
||
Un compilateur transforme du code C en instructions exécutables par le processeur.
|
||
|
||
Le C est un langage compilé.
|
||
Cela signifie que le programme est transformé avant exécution.
|
||
|
||
### Compilateurs courants
|
||
|
||
- GCC (GNU Compiler Collection)
|
||
- Clang (LLVM)
|
||
- MSVC (Microsoft Visual C)
|
||
|
||
Chaque compilateur :
|
||
- implémente la norme C
|
||
- peut ajouter des extensions
|
||
- produit du code pour une architecture donnée
|
||
|
||
### Exemple
|
||
|
||
```bash
|
||
gcc main.c -o prog
|
||
```
|
||
|
||
---
|
||
|
||
## 3.2 Étapes de la chaîne de compilation
|
||
|
||
La compilation est une pipeline.
|
||
|
||
### Étape 1 — Préprocesseur
|
||
|
||
Traite :
|
||
- #include
|
||
- #define
|
||
- #ifdef
|
||
|
||
---
|
||
|
||
Exemple :
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
```
|
||
|
||
Le contenu du fichier est copié dans le code.
|
||
|
||
### Étape 2 — Compilation
|
||
|
||
C → assembleur
|
||
|
||
```bash
|
||
gcc -S main.c
|
||
```
|
||
|
||
Produit :
|
||
|
||
```
|
||
main.s
|
||
```
|
||
|
||
### Étape 3 — Assemblage
|
||
|
||
ASM → objet (.o)
|
||
L’assembleur transforme le code assembleur en code machine.
|
||
|
||
Produit :
|
||
|
||
```
|
||
main.o
|
||
```
|
||
|
||
|
||
### Étape 4 — Linking
|
||
|
||
Objets → binaire final
|
||
Le linker assemble tous les objets.
|
||
Il résout les dépendances.
|
||
|
||
---
|
||
|
||
## 3.3 Assembleur utilisé selon la toolchain
|
||
|
||
Le compilateur ne génère pas un assembleur universel.
|
||
Il dépend de la toolchain.
|
||
|
||
- **GCC** :
|
||
- utilise GAS **(GNU assembler)**
|
||
- syntaxe par défaut : **AT&T**
|
||
- **Clang/LLVM** :
|
||
- utilise un **assembleur intégré LLVM**
|
||
- peut aussi utiliser GAS
|
||
- **MSVC** :
|
||
- utilise son backend interne
|
||
- eut utiliser **MASM**
|
||
- **Android (NDK)** :
|
||
- utilise **Clang + LLVM**
|
||
|
||
### Exemple GAS
|
||
|
||
```asm
|
||
movl $5, %eax
|
||
```
|
||
|
||
### Exemple Intel
|
||
|
||
```asm
|
||
mov eax, 5
|
||
```
|
||
|
||
Ces syntaxes ne sont pas compatibles directement.
|
||
|
||
---
|
||
|
||
## 3.4 Fichiers générés
|
||
|
||
Chaque étape produit un fichier.
|
||
|
||
### Source
|
||
|
||
```
|
||
main.c
|
||
```
|
||
|
||
### Assembleur
|
||
|
||
```
|
||
main.s
|
||
```
|
||
|
||
### Objet
|
||
|
||
```
|
||
main.o
|
||
```
|
||
|
||
### Exécutable
|
||
|
||
```
|
||
prog
|
||
```
|
||
|
||
### Exemple — compilation séparée
|
||
|
||
```bash
|
||
gcc -c main.c
|
||
gcc main.o -o prog
|
||
```
|
||
|
||
---
|
||
|
||
## 3.5 Warnings et erreurs
|
||
|
||
Le compilateur analyse aussi le code.
|
||
|
||
### Erreur
|
||
|
||
Empêche la compilation.
|
||
|
||
### Warning
|
||
|
||
Indique un problème potentiel.
|
||
|
||
### Exemple — variable non initialisée
|
||
|
||
```c
|
||
int main(void)
|
||
{
|
||
int x;
|
||
return x;
|
||
}
|
||
```
|
||
|
||
```bash
|
||
gcc -Wall -Wextra -Werror main.c
|
||
```
|
||
|
||
---
|
||
|
||
## 3.6 Options du compilateur
|
||
|
||
Les options contrôlent le comportement.
|
||
|
||
### Optimistion
|
||
|
||
```bash
|
||
gcc -O0 main.c
|
||
gcc -O2 main.c
|
||
gcc -O3 main.c
|
||
```
|
||
|
||
### Debug
|
||
|
||
```bash
|
||
gcc -g main.c
|
||
```
|
||
|
||
### Standard
|
||
|
||
```bash
|
||
gcc -std=c11 main.c
|
||
```
|
||
|
||
---
|
||
|
||
## 3.7 Informations de debug
|
||
|
||
Les informations de debug permettent :
|
||
|
||
inspection mémoire
|
||
suivi d’exécution
|
||
|
||
### Exemple
|
||
|
||
```bash
|
||
gdb prog
|
||
```
|
||
|
||
---
|
||
|
||
## 3.8 Compilation séparée
|
||
|
||
Permet de compiler fichier par fichier.
|
||
|
||
### Exemple
|
||
|
||
```bash
|
||
gcc -c a.c
|
||
gcc -c b.c
|
||
gcc a.o b.o -o prog
|
||
```
|
||
|
||
---
|
||
|
||
## 3.9 Compilation croisée
|
||
|
||
Compiler pour une autre architecture.
|
||
|
||
### Exemple
|
||
|
||
```bash
|
||
arm-none-eabi-gcc main.c
|
||
```
|
||
|
||
---
|
||
|
||
## 3.10 Linker
|
||
|
||
Le linker combine les objets.
|
||
|
||
Il :
|
||
- fusionne les sections
|
||
- résout les symboles
|
||
- construit le binaire
|
||
|
||
---
|
||
|
||
## 3.11 Symboles
|
||
|
||
Un symbole est un nom utilisé par le linker.
|
||
|
||
#### Exemple
|
||
|
||
```c
|
||
void f(void)
|
||
{
|
||
}
|
||
```
|
||
|
||
➡ symbole f
|
||
|
||
---
|
||
|
||
Le linker associe :
|
||
|
||
- déclaration
|
||
- définition
|
||
|
||
---
|
||
|
||
## 3.12 Formats binaires
|
||
|
||
### Le binaire final a un format.
|
||
|
||
- ELF (Linux)
|
||
- PE (Windows)
|
||
- Mach-O (macOS)
|
||
|
||
|
||
### Contenu :
|
||
- `.text` → code
|
||
- `.data` → données
|
||
- `.bss` → mémoire non initialisée
|
||
|
||
### Rôle du loader
|
||
|
||
Le système :
|
||
|
||
- charge le binaire
|
||
- mappe les sections
|
||
- résout les dépendances
|
||
|
||
---
|
||
|
||
## 3.13 ABI (introduction)
|
||
|
||
L’ABI définit :
|
||
|
||
- comment appeler une fonction
|
||
- comment passer les arguments
|
||
- comment organiser la mémoire
|
||
|
||
### Exemple
|
||
|
||
Linux x86_64 :
|
||
- rdi, rsi, rdx
|
||
|
||
Windows x86_64 :
|
||
- rcx, rdx, r8
|
||
|
||
---
|
||
|
||
Même CPU ≠ même ABI
|
||
|
||
---
|
||
|
||
## 3.14 Linker script
|
||
|
||
Un linker script contrôle la disposition mémoire.
|
||
|
||
### Exemple
|
||
|
||
```ld
|
||
SECTIONS
|
||
{
|
||
.text 0x1000 : { *(.text) }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
Utilisation
|
||
- embarqué
|
||
- systèmes bas niveau
|
||
|
||
---
|
||
|
||
## 3.15 Résumé
|
||
|
||
- le C est compilé en code machine
|
||
- la compilation est une chaîne
|
||
- assembleur dépend de la toolchain
|
||
- linker construit le binaire
|
||
- format dépend du système
|
||
- ABI dépend de l’OS
|
||
|