Introduction à la compilation
Une introduction à la compilation des fichiers sources en C++ afin de pouvoir utiliser directement les notions apprise. Le texte développe les différentes options à utiliser avec le compilateur GCC afin de compiler un fichier source en un exécutable.
Le but du présent document est d'introduire la compilation de programme C++ en code machine. A la fin vous devriez comprendre la compilation à l'aide de GCC, dont toutes les commandes utilisés dans la ligne suivante:
g++ -Wall -g -O0 -o prog def.cpp main.cpp
Ceci compile le programme écrit dans les deux fichiers sources def.cpp et main.cpp en un fichier exécutable nommé prog.
Cette exemple est typique dans le développement d'application en C++. D'autres options existent pour l'optimisation (-0x, -march) et pour le profiling (-pg) mais ces options ne sont pas utile pour le développement.
La compilation
La compilation est l'étape dans laquelle les sources écrite en C++ sont traduite en code compréhensible par la machine. Tout les langages ne nécessitent pas de compilation, et la compilation ne mène pas toujours à un code compréhensible par la machine, mais dans le cas de C++ le code est compilé et fonctionne directement sur le processeur, ce qui confère une rapidité d'exécution maximale.

L'outil qu'on utilisera pour compiler les programmes C++ sera la suite de compilateur GCC (GNU Compiler Collection). La commande de GCC utilisé pour compiler du C++ est g++. Pour compiler du C, la commande est simplement gcc.
Programme d'exemple
Dans les exemples subséquents, nous allons compiler le petit programme suivant dont le but est de calculer la factorielle d'un nombre.
#include <iostream>
using namespace std;
// Calcul la factorielle du nombre entier passé en paramètre
unsigned long factorial(unsigned long const &integer)
{
unsigned long response=1;
for(int i=integer; i>1; --i)
{
response *=i;
}
return response;
}
// Point d'entré du programme
int main(int argc, char **argv, char **envp)
{
const unsigned long number=10;
unsigned long fact_number;
fact_number=factorial(number);
cout << "factorielle de " << number
<< " = " << fact_number << endl;
return 0;
}
Le code de l'exemple est uniquement mis pour vous permettre d'essayer de compiler le programme, ne vous inquiétez pas si vous ne comprenez pas tout pour le moment, les explications viendront dans les autres chapitres.
Cette exemple montre deux propriétés courantes d'un ordinateur, une grande capacité de calcul mais aussi des limites sur les objets calculable (ici la taille du nombre, parfois la précision ou simplement la possibilité de faire le calcul en un temps fini).
Compiler l'exemple
Pour compiler l'exemple, sauvez le dans un fichier dont l'extension est de préférence .cpp, nous prendrons ici fact.cpp, et tapez la commande suivante à l'invite de commande:
g++ fact.cpp
C'est la façon la plus simple de compiler des fichiers source, mais aussi la moins pratique pour programmer. Commençons par ajouter les avertissements de compilation à l'aide de l'option -Wall.
Les avertissements
Lors de la compilation, GCC peut analyser le code source afin de trouver des indices d'erreurs, les avertissement. Ce ne sont pas de vrai erreurs de programmation (le programme peut compiler malgré les avertissements) mais il est fort probable que cela soit des erreurs du programmeur.
Il est possible d'activer chaque type d'avertissement à l'aide d'une option commençant par -W, par exemple -Wunused-variable active les avertissements pour les variables déclarés mais non utilisés. Plutôt que d'activer des types d'avertissement particuliers, il est recommandé d'activer tout les avertissement à l'aide de -Wall.
g++ -Wall fact.cpp
Bien que les avertissements ne bloquent pas la compilation et peuvent, en théorie, être ignorés par le programmeur, c'est une bonne pratique de systématiquement corriger le programme jusqu'à la disparition de tout les avertissements. Certains avertissement apparaissent pour des constructions licites et correctes et il peut sembler étrange de devoir y remédier, néanmoins, réécrire un code correct pour supprimer les avertissements le rend généralement plus clair et en diminue la complexité.
Pour des logiciels comportant plusieurs milliers de lignes de code, certains avertissements sont considérés comme acceptable et ne sont pas affichés à l'aide de certaines technique de construction. Pour les petits programmes développés ici les avertissements peuvent assurément être évités.
Nommer le programme créé
Par défaut, GCC compile les fichiers source en un fichier exécutable nommé a.out. Il est bien plus commode de spécifier le nom à donner au programme compilé, ce qui peut se faire à l'aide de l'option -o.
Par exemple on peut compiler le programme d'exemple en activant les avertissements et en nommant le fichier compilé de la façon suivante:
g++ -Wall -o factorial fact.cpp
Le programme ici compilé s'appellera factorial, on peut ensuite le lancer de la façon suivante:
./factorial
factorielle de 10 = 3628800
Prévoir le débugage
Finalement il reste à expliquer les options -g et -O0 du premier exemple. L'option -g sert au débugage de l'application et c'est une bonne idée de l'activer systématiquement. L'option -00 est lié à l'optimisation du code produit par GCC, dans ce cas ci on précise qu'on ne veut pas optimiser, ce qui rend le debugage plus facile.
Le debugage (ou débogage) est l'étape dans laquelle on traque et on corrige les bugs connus. Afin de pouvoir déboguer un programme compilé comme C++, on peut demander au compilateur d'ajouter des symboles supplémentaires dans le code généré afin de retrouver les informations du code initial. Avec GCC, l'ajout des options de débugage se fait avec -g.
L'option -0 est une des options permettant de gérer l'optimisation du code machine généré par le compilateur, on peut préciser le niveau d'optimisation en vitesse de 0 à 3 ou optimiser la taille du fichier généré avec -Os. Les options d'optimisations sont expliqués dans un autre chapitre car pour le développement, les optimisations peuvent gêner considérablement le débugage. On précisera au compilateur de ne pas optimiser à l'aide du niveau 0 : -O0 (tiret - lettre O - chiffre zéro).
La commande classique pour compiler le programme est finalement:
g++ -Wall -g -O0 -o factorial fact.cpp

