Cet article est une introduction à la suite de compilateurs GCC et à son port win32, MinGW. Cet article ne se veut pas être une référence complète, mais plutôt un guide de « démarrage », ou à la limite une petite référence sur les options les plus utilisées de GCC.

Ce document s'adresse plus particulièrement aux programmeurs débutant voulant utiliser le compilateur libre GCC, ou aux développeurs qui veulent apprendre à utiliser GCC pour porter leurs programmes sur une autre platforme.

Je vais traiter ici à la fois de la compilation native avec GCC sous GNU/Linux et sous Windows, ainsi que comment faire de la compilation croisée avec MinGW pour Windows sur des systèmes autres que Windows.

Introduction to GCC

GCC signifie « GNU Compiler Collection ». C'est une suite de compilateurs distribuée par le projet GNU. GCC a été créé par Richard Stallman en 1987 dans le but de fournir un compilateur C libre pour le développement du système d'exploitation GNU. À l'origine, GCC signifiait « GNU C Compiler » (il n'y avait que le compilateur C). GCC est distribué sous les termes de la licence GNU Public Licence (GPL).

GCC est une suite de compilateurs impressionnante, elle supporte 7 langages de programmation (officiellement, des front ends pour d'autres langages existent), permet de compiler pour une large variété d'architectures (environ 50 processeurs !) et a été porté sur un bon nombre de systèmes d'exploitation dont GNU/Linux, MacOS et Windows (les systèmes libres sont d'ailleurs généralement construits avec GCC). Il existe d'autres compilateurs dérivés de GCC visant des architectures plus spécifiques, comme les microcontrôleurs ou les circuits logiques programmables.

Voici la liste des langages supportés « officiellement » (faisant partie du projet GCC) et leur front end (compilateur spécifique au langage) respectif :

Utilisation de GCC

GCC est un compilateur en ligne de commande. Il ne fait que ce pour quoi il a été conçu : compiler. Vous pouvez écrire votre code avec n'importe quel éditeur de texte, comme vim, emacs (meilleur), kwrite, ou même avec les bloatwares que sont les IDE tels Kdevelop, Eclipse (ouch!) ou Code::blocks.

Afin d'illustrer les commandes de cet article, je vais utiliser le bien connu programme « hello world », dont voici le code en C :

#include <stdio.h>

int main ()
{
  printf ("Hello world!\n");
  return 0;
}

En supposant que ce code a été sauvegardé dans le fichier hello.c, vous pouvez le compiler simplement en invoquant GCC avec le nom du fichier en paramètre. Dans un shell, tappez la commande suivante (le $ indique l'invite de commande, ne la recopiez pas !) :

$ gcc hello.c

Ceci produira un fichier binaire nommé a.out. Vous pouvez l'exécuter avec la commande suivante :

$ ./a.out

Comme prévu, le programme affichera la phrase « Hello world! » dans le shell. Si vous avez plusieurs fichiers source, vous pouvez tous les passer en paramètre à GCC ; ils seront compilés et liés ensemble :

$ gcc hello.c foo.c bar.c

Vous voudrez certainement donner un nom à votre programme autre que « a.out ». Utilisez l'option -o suivie du nom que vous souhaitez (notez que vous pouvez placer cette option n'importe où dans la liste des options, comme toutes les autres d'ailleurs) :

$ gcc -o hello hello.c

Vous pouvez demander à GCC de seulement compiler un fichier source avec l'option -c :

$ gcc -c hello.c

Ceci produira un fichier objet intermédiaire hello.o. Vous devrez alors appeler l'éditeur de liens afin d'obtenir un binaire exécutable. Pour invoquer l'éditeur de liens, appelez simplement GCC avec les fichiers objet en paramètre :

$ gcc -o hello hello.o

Vous pouvez ainsi compiler chaque fichier source de votre programme séparément, et appeler ensuite l'éditeur de liens :

$ gcc -c hello.c
$ gcc -c foo.c
$ gcc -c bar.c
$ gcc -o hello hello.o foo.o bar.o

Par défaut, GCC recherche les fichiers d'en-tête (vous savez, ceux que incluez avec la directive #include) dans les dossiers /usr/local/include et /usr/include.

Vous pouvez spécifier des répertoires d'include additionnels avec l'option -I suivie du chemin d'accès relatif ou absolu. Par convention, on ne place pas d'espace entre l'option -I et le chemin d'accès. Par exemple, si vous avez des fichiers d'en-tête dans le dossier /somewhere/include, appelez :

$ gcc -o hello -I/somewhere/include hello.c

Pour lier votre exécutable avec une bibliothèque, utilisez l'option -l suivie du nom de la bibliothèque sans le préfixe « lib » ni son extension. Par exemple, imaginons que vous vouliez lier votre programme hello avec la bibliothèque libpng (parce que votre programme peut sortir un super smiley dans un fichier PNG). Vous devez avoir le fichier libpng.a (la bibliothèque statique nécessaire pour la compilation) installé dans le dossier /usr/lib (le dossier standard des bibliothèques) :

$ gcc -o hello hello.c -lpng

Comme pour les fichiers d'en-tête, GCC recherche les bibliothèques par défaut dans les dossiers /usr/local/lib et /usr/lib. Vous pouvez spécifier des répertoires additionnels avec l'option -L, comme pour les includes :

$ gcc -o hello -L/somewhere/lib hello.c

Vous pouvez définir des macros avec l'option -D, suivie du nom de la macro et éventuellement sa valeur (séparés par un signe égal). La commande suivante va compiler notre fichier source et définir la macro VALUE avec une valeur de 10 :

$ gcc -o hello hello.c -DVALUE=10

GCC possède des options pour optimiser la compilation. Vous pouvez contrôler l'optimisation avec cinq options : -O (ou -O1), -O2, -O3, -Os et -O0 (ne pas optimiser). Chacune d'entre elle active en réalité un groupe d'optimisations individuelles. Les options pour les optimisations individuelles commencent par la lettre « f » dans leur nom (voir le manuel pour plus d'infos à leur sujet).

Par défaut, les exécutables produits par GCC gardent leur table de symboles et les informations de relocation. Ceci a pour conséquence d'alourdir le fichier exécutable. Vous pouvez retirer ces données en passant l'option -s (pour « strip ») à l'éditeur de liens :

$ gcc -o hello hello.o foo.o bar.o -s

La table de symboles est utile lors du déboguage, donc n'utilisez pas cette option si vous comptez ensuite utiliser un débogueur avec votre programme !

Je vous recommande aussi d'activer les messages d'avertissement avec l'option -Wall et de distribuer vos programmes compilant sans aucun avertissement. Les options individuelles contrôlant les avertissement commencent par la lettre « W » dans leur nom (voir le manuel). Mieux encore, vous pouvez utiliser l'option -Werror pour demander à GCC de traîter les avertissements comme des erreurs ! (il est bon d'être rigoureux quand on programme)

Vous pouvez spécifier à GCC quelle norme (standard ?) vous voulez utiliser avec l'option -std, suivie du symbol égal et du nom de la norme. Voir le manuel pour la liste des normes supportées pour chaque langage. Pour le langage C, vous pouvez utiliser par exemple c89 pour du C Ansi ou c99 pour du C99. Pour le C Ansi, vous pouvez également utiliser l'option -ansi à la place de -std :

$ gcc -o hello1 hello.c -ansi
$ gcc -o hello2 hello.c -std=c99

L'option -pedantic affichera tous les avertissements requis par les standards ISO C et ISO C++, et rejettera tout programme utilisant des extensions de ces langages ou qui ne suivent pas la norme strictement. L'option -pedantic-errors génère des erreurs au lieu d'avertissements.

À présent, peut-être aimeriez vous savoir comment compiler en C++. C'est quasiment la même chose. Voici notre fameux hello world porté en C++ :

#include <iostream>

int main ()
{
  std::cout << "Hello world!" << std::endl;
  return 0;
}

La compilation est similaire à la compilation du programme en C. Notez qu'on lie l'exécutable avec la bibliothèque libstdc++ (du fait qu'on utilise iostream) :

$ g++ -o hello hello.cpp -lstdc++

Pour finir, je vais vous présenter l'ultime option d'avertissement de g++, teh -Weffc++ option ! Si vous arrivez à compiler tout un projet avec cette option activée, combinée avec l'option -Werror, alors vous êtes un Jedi :p
(astuce : c'est actuellement impossible avec la bibliothèque standard)

C'est tout pour GCC. Je pense avoir fait le tour des options les plus usuelles. Si vous en voulez plus, je vous recommande de jeter un œil au manuel de GCC.

GCC sous Windows : MinGW

MinGW est le port natif de GCC sous Windows. MinGW signifie « Minimalist GNU for Windows ». Le projet MinGW — démarré en juillet 1998 — apporte une collection d'outils afin de produire des programmes Windows natifs. Malheureusement, le développement de MinGW est un peu en retard par rapport à GCC.

MinGW inclut les fichiers d'en-tête et bibliothèques nécessaires pour programmer avec l'API win32. Il fournit également une implémentation (parfois partielle) de certaines fonctions POSIX qui ne sont pas présentes sous d'autres compilateurs, comme Microsoft Visual Studio. Les fonctions opendir/readdir pour la lecture des dossiers en sont un exemple.

L'installation de MinGW est très simple. Vous pouvez l'obtenir sur la page de télécchagrement de MinGW. Téléchargez la dernière version de l'installeur mingw et lancez-le. Par défaut, MinGW sera installé dans C:\MinGW.

Je vous recommande également de télécharger et installer MSYS, un package qui apporte quelques outils très utiles lorsqu'on travaille avec GCC, comme un shell (bash) ou l'outil make.

Votre environnement de développement sous Windows est maintenant prêt. Vous pouvez lancer le shell de MSYS et utiliser GCC comme expliqué dans la section précédente.

Utiliser MinGW sous Linux comme compilateur croisé

MinGW peut également être utilisé sous Linux comme un compilateur croisé, permettant ainsi de construire des exécutables Windows natifs depuis son système préféré ;-)

Certaines distributions comme Debian proposent des paquets pour MinGW. Utilisez simplement apt-get (ou les outils de package de votre distro) pour les installer :

# apt-get install mingw32

Les paquets mingw32-binutils et mingw32-runtime seront également installé en tant que dépendances. Vous pouvez ensuite invoquer GCC en appelant i586-mingw32msvc-gcc, i586-mingw32msvc-g++, etc., au lieu de gcc, g++, ...

À noter que les programmes C++ seront bien plus gros en taille que ceux produits pour Linux ou par Microsoft Visual Studio. Ceci est dû au fait que la bibliothèque standard doit être liée statiquement avec l'exécutable.

Autres outils utilisés avec GCC

Dans cette section je vais présenter succinctement quelques autres outils souvent utilisés avec GCC. Cependant, leur fonctionnement sort du cadre de cet article et je ne le détaillerai donc pas.

make est l'outil à connaître lorsqu'on veut développer avec GCC ! Il est utilisé afin d'automatiser les compilations. Vous placez vos instructions de compilation dans un fichier Makefile puis invoquez make dans votre shell pour lancer la compilation. make peut également déterminer les portions de votre programme qui doivent être recompilées, évitant ainsi une recompilation complète à chaque fois que vous apportez une modification.

gdb est le débogueur GNU. Pour activer le déboguage vous vous devez compiler avec l'option -g et désactiver toutes les optimisations. valgrind est un autre outil excellent pour déboguer les fuites de mémoire.

colorgcc est un wrapper pour GCC affichant les messages d'erreur et d'avertissement en couleurs. Très pratique !

References

Voici quelques liens si vous voulez en connaître un peu plus sur GCC et MinGW :

Creative Commons Logo Contrat Creative Commons

Cet article est mis à disposition sous un contrat Creative Commons (licence CC-BY-ND).