Ceci est une ancienne révision du document !
Initialiment appelé Gnu C Compiler, il a été renommé Gnu Compiler Collection puisqu'il permet de compiler divers languages tels que:
Gnu Compiler Collection est l'outil généraliste de compilation du projet GNU. Il s'articule autour de plusieurs outils:
La commande gcc est une interface permettant d'appeler de facon unifiée les différentes étapes de compilation.
Le compilateur gcc de GNU passe par les étapes suivante pour compiler un fichier C:
Dans le fichier source, une ligne commencant par # n'est pas du C mais une directive pour le préprocesseur. Les directives telles que #define permettent d'augmenter la lisibilité et la maintenabilité du code. Le preprocesseur, appelé cpp (C PreProcessor) traite le fichier source en remplace les directives #includes, les commentaires etc. Le fichier obtenu en sortie est un fichier source contenant exclusivement des instructions C.
Le travail du preprocesseur peut être révelé avec l'argument -E de gcc
exemple hello.c
/* ######################################### # hello.c # # Mon premier programme C # ######################################### */ #include <stdio.h> #define carre(a) ((a)*(a)) int main(void) { printf("hello big world!\n"); int nb=8; printf("nb=%d et %d est son carre.\n", nb, carre(nb) ); return 0; }
gcc -E hello.c
# 1 "hello.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "hello.c" ... typedef struct { int __count; union { unsigned int __wch; char __wchb[4]; } __value; } __mbstate_t; ... int main(void) { printf("hello big world!\n"); int nb=8; printf("nb=%d et %d est son carre.\n", nb, ((nb)*(nb)) ); return 0; }
A titre d'info:
cat hello.c | wc -l 17 gcc -E hello.c | wc -l 851
Notre fichier source hello.c passe de 17 lignes a 851 apres traitement via le préprocesseur
pour demander a gcc de compiler un fichier source la syntaxe est la suivante:
gcc -c monfichier.c -o monfichier.o
(gcc genere un fichier assembleur (phase assemblage) puis un fichier objet) on peut demander a gcc de stopper la compilation a la phase de traduction en language assembleur pour voir le code assembleur intermediaire:
gcc -S hello.c
et traduire ensuite le code assembleur en code machine
as hello.c -o hello.o
Une fois les fichiers objets créés, il faut les fusioner correctement pour creer le fichier executable (j'evite ici le terme assembler): c'est la phase d'édition des liens faite par le linker. la commande permettant d'invoquer le linker:
gcc monfichier.o -o monfichier
Sous Linux la plupart des executables sont liés dynamiquement, c'est a dire qu'ils n'incluent pas directement le code des fonctions utilisées. Lors de la phase d'edition de liens un code spécifique est ajouté, il est capable d'appeller du code en dehors de l'executable. pour voir a quelles bibliothèques un executable est lié commande ldd yoann@hermes:/tmp/helloWorld$ ldd hello.exe
linux-gate.so.1 => (0x00915000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc4000) /lib/ld-linux.so.2 (0x009b9000)
pour forcer le linker a faire une liaison statique: gcc -static monficheir.o -o monfichier
Utiliser des bibliothèque Si bibliothèque n'est pas dans un dossier standard il faut preciser au linker le dossier dans lequel elle est présente et son nom gcc -L ~/repertoire -lmalib monfichier.o -o monfichier
libmalib.so: dynamique (.so = shared object)) libmalib.a: statique
S'il s'agit d'une bibliothèque dynamique (libXXX.so), il faudra impérativement indiquer au programme chargeant les bibliothèques dynamiques ou elle se trouve. ceci peut etre fait grace a la variable d'environnement LD_LIBRARY_PATH
Creer une bibliothèque Pour liaison statique c'est rassembler plusieurs ficheirs objets dans un seul fichier (une archive) avec ar (options ur (ajouter et remplace et v verbeux) on crée les fichiers lib/module1.c lib/module2.c lib/module3.c et malib.h on compile les fichiers sources puis on crée l'archive
ar ruv libmalib.a module*.o ar: creating libmalib.a a - module1.o a - module2.o a - module3.o
dans le repertoire parent on modifie hello.c pour lui faire utiliser les fonctions on compile ensuite gcc hello.c -Llib -lm -lmalib -o hello
Pour liaison dynamique pour creer une bibliothèque dynamique gcc -shared module*.o -o libmalib.so le fichier libmalib.so est créé, il peut etre ensuite liée dynamiquement a l'executable hello gcc hello.o -L./lib -lmalib -lm -o hello.dyn
ldd hello.dyn
linux-gate.so.1 => (0x00fc1000) libmalib.so => not found libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00698000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00cb4000) /lib/ld-linux.so.2 (0x004f8000)
yoann@hermes:/tmp/helloWorld$ ./hello.dyn ./hello.dyn: error while loading shared libraries: libmalib.so: cannot open shared object file: No such file or directory