Outils pour utilisateurs

Outils du site


dev:outils:gcc

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
dev:outils:gcc [2013/01/20 14:36] – ajout notes gcc rootdev:outils:gcc [2021/02/01 21:51] (Version actuelle) – modification externe 127.0.0.1
Ligne 1: Ligne 1:
 +{{tag>dev c compilation gcc}}
 +
 ====== GCC ====== ====== GCC ======
  
-Initialiment appelé Gnu C Compiler, il a été renommé Gnu Compiler Collection puisqu'il permet de compiler divers languages tels que:+Initialement appelé Gnu C Compiler, il a été renommé Gnu Compiler Collection puisqu'il permet de compiler divers langages tels que:
   * C/C++   * C/C++
   * Objective C   * Objective C
Ligne 11: Ligne 13:
 Gnu Compiler Collection est l'outil généraliste de compilation du projet GNU. Il s'articule autour de plusieurs outils: Gnu Compiler Collection est l'outil généraliste de compilation du projet GNU. Il s'articule autour de plusieurs outils:
   * Le frontend gcc qui a pour but d'analyser et de traduire les fichiers sources en code assembleur correspondant à la cible.   * Le frontend gcc qui a pour but d'analyser et de traduire les fichiers sources en code assembleur correspondant à la cible.
-  * Le backend constitué par les bin-utils assemble et lie aux biliothèques les fichiers objets pour produire les fichiers executables.+  * Le backend constitué par les bin-utils assemble et lie aux bibliothèques les fichiers objets pour produire les fichiers exécutables.
  
-La commande gcc est une interface permettant d'appeler de facon unifiée les différentes étapes de compilation.+La commande gcc est une interface permettant d'appeler de façon unifiée les différentes étapes de compilation.
  
  
-===== Etapes de compilation =====+===== Étapes de compilation =====
  
 Le compilateur gcc de GNU passe par les étapes suivante pour compiler un fichier C: Le compilateur gcc de GNU passe par les étapes suivante pour compiler un fichier C:
-  - preprocesseur,+  - préprocesseur,
   - compilation,   - compilation,
   - liaison.   - liaison.
Ligne 25: Ligne 27:
 ==== préprocesseur ==== ==== préprocesseur ====
  
-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.+Dans le fichier source, une ligne commençant 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 préprocesseur, 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 +Le travail du préprocesseur peut être révélé avec l'argument **-E** de gcc:
- +
-exemple hello.c+
  
 +<code c>
 /* /*
 ######################################### #########################################
Ligne 48: Ligne 49:
         return 0;         return 0;
 } }
 +</code>
  
 +<code bash>
 gcc -E hello.c  gcc -E hello.c 
 +</code>
  
 +<code c>
 # 1 "hello.c" # 1 "hello.c"
 # 1 "<built-in>" # 1 "<built-in>"
Ligne 69: Ligne 74:
   } __value;   } __value;
 } __mbstate_t; } __mbstate_t;
 +...
 +...
 ... ...
 int main(void) int main(void)
Ligne 77: Ligne 84:
  return 0;  return 0;
 } }
 +</code>
  
 +Pour info, les commandes ci-dessous permettent de comparer les fichiers:
  
-A titre d'info: 
 <code bash> <code bash>
 cat hello.c | wc -l cat hello.c | wc -l
Ligne 87: Ligne 95:
 </code> </code>
  
-Notre fichier source hello.c passe de 17 lignes a 851 apres traitement via le préprocesseur+Notre fichier source hello.c passe de 17 lignes a 851 après traitement du préprocesseur.
  
 ==== compilateur ==== ==== compilateur ====
  
-pour demander gcc de compiler un fichier source la syntaxe est la suivante:+Pour demander à gcc de compiler un fichier source la syntaxe est la suivante:
 <code bash> <code bash>
 gcc -c monfichier.c -o monfichier.o gcc -c monfichier.c -o monfichier.o
 </code> </code>
  
-(gcc genere un fichier assembleur (phase assemblage) puis un fichier objet+(gcc génère un fichier assembleur (phase assemblage) puis un fichier objet. On peut demander à gcc de stopper la compilation a la phase de traduction en langage assembleur pour voir le code assembleur produit: 
-on peut demander gcc de stopper la compilation a la phase de traduction en language assembleur pour voir le code assembleur intermediaire:+
 <code bash> <code bash>
 gcc -S hello.c gcc -S hello.c
 </code> </code>
  
-et traduire ensuite le code assembleur en code machine+Et traduire ensuite le code assembleur en code machine
 <code bash> <code bash>
 as hello.c -o hello.o as hello.c -o hello.o
 </code> </code>
  
-===== Bibliothèques, liaison statique / dynamique =====+==== linker ====
  
-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.+Une fois les fichiers objets créés, il faut les fusionner correctement pour créer le fichier exécutable (j’évite ici le terme assembler): c'est la phase d'édition des liens faite par le linker.
 la commande permettant d'invoquer le linker: la commande permettant d'invoquer le linker:
  
Ligne 116: Ligne 124:
 </code> </code>
  
-Sous Linux la plupart des executables sont liés dynamiquement, c'est 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.  +Sous Linux la plupart des exécutables sont **liés dynamiquement**, c'est à dire qu'ils n'incluent pas directement le code des fonctions utilisées. Lors de la phase d’édition de liens un code spécifique est ajouté, il est capable d’appeler du code en dehors de l’exécutable
-pour voir quelles bibliothèques un executable est lié commande ldd +  
-yoann@hermes:/tmp/helloWorld$ ldd hello.exe+Pour voir à quelles bibliothèques un exécutable est lié, utiliser la commande **ldd** 
 +<code bash> 
 +$ ldd hello.exe
         linux-gate.so.1 =>  (0x00915000)         linux-gate.so.1 =>  (0x00915000)
         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc4000)         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc4000)
         /lib/ld-linux.so.2 (0x009b9000)         /lib/ld-linux.so.2 (0x009b9000)
 +</code>
  
-pour forcer le linker a faire une liaison statique+On peut faire le choix d'utiliser à la place de la liaison dynamique la liaison statique. Lors de la phase d'édition des liens on utilise l'argument **-static**:
-gcc -static monficheir.-o monfichier+
  
-Utiliser des bibliothèque +<code bash> 
-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 -static monficheir.o -o monfichier 
 +</code> 
 + 
 +On obtient un binaire moins modulaire mais qui inclus le code dont il a besoin. S'il repose sur des bibliothèques qui ont été mises à jour, il faudra recompiler le programme pour qu'il intègre les modifications. 
 + 
 +===== Bibliothèques, liaison statique / dynamique ===== 
 + 
 +Lors de l'édition des liens, des fichiers objets présents dans des bibliothèques peuvent être spécifiés. 
 +Si la bibliothèque n'est pas dans un dossier standard il faut préciser au linker le dossier dans lequel elle est présente ainsi que son nom, c'est que permettent de faire les options **-L** (**%%--library-path=%%**) et **-l** (**%%--library=%%**) : 
 + 
 +<code bash>
 gcc -L ~/repertoire -lmalib monfichier.o -o monfichier gcc -L ~/repertoire -lmalib monfichier.o -o monfichier
 +</code>
  
-libmalib.so: dynamique (.so = shared object)) +<note> 
-libmalib.a: statique+A propos de la nomenclature du paramètre suivant l'option **-l**: s'il a la forme d'un nom de fichier, le linker recherche le fichier dans les répertoires des bibliothèques, sinon il considère que la bibliothèque est nommée libxx.so **-ltoto** correspond aux fichier **libtoto.so**   
 +</note>
  
-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+  * libmalib.so: bibliothèque contenant des fichiers objets pour liaison dynamique (.so = shared object)). 
-ceci peut etre fait grace la variable d'environnement LD_LIBRARY_PATH+  * libmalib.a: bibliothèque contenant des fichiers objets pour liaison statique.
  
-Creer une bibliothèque +Pour un programme se reposant sur les liaisons dynamiques (libXXX.so), il faudra impérativement indiquer dans quels répertoires sont stockées les bibliothèquesCeci peut être fait notamment grâce à la variable d'environnement **LD_LIBRARY_PATH**
-Pour liaison statique +
-c'est rassembler plusieurs ficheirs objets dans un seul fichier (une archiveavec 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+===== Créer une bibliothèque ===== 
 + 
 +==== Pour liaison statique ==== 
 + 
 +C'est rassembler plusieurs fichiers 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 
 + 
 +<code bash> 
 +ar ruv libmalib.a module*.o
 ar: creating libmalib.a ar: creating libmalib.a
 a - module1.o a - module1.o
 a - module2.o a - module2.o
 a - module3.o a - module3.o
 +</code>
  
-dans le repertoire parent on modifie hello.c pour lui faire utiliser les fonctions +Dans le répertoire parent on modifie hello.c pour lui faire utiliser les fonctions. On compile ensuite:
-on compile ensuite +
-gcc hello.c -Llib -lm -lmalib -o hello+
  
 +<code bash>
 +$ gcc hello.c -Llib -lm -lmalib -o hello
 +</code>
  
-Pour liaison dynamique +==== 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 +Pour créer une bibliothèque dynamique, utiliser l'option **-shared** 
 + 
 +<code> 
 +$ gcc -shared module*.o -o libmalib.so 
 +</code> 
 + 
 +Le fichier libmalib.so est créé, il peut être ensuite liée dynamiquement à l’exécutable hello: 
 + 
 +<code bash> 
 +$ gcc hello.o -L./lib -lmalib -lm -o hello.dyn 
 +</code> 
 + 
 +Pour vérifier à quelles bibliothèques dynamiques est lié notre exécutable: 
 + 
 +<code bash> 
 +ldd hello.dyn 
         linux-gate.so.1 =>  (0x00fc1000)         linux-gate.so.1 =>  (0x00fc1000)
         libmalib.so => not found         libmalib.so => not found
Ligne 165: Ligne 206:
         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00cb4000)         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00cb4000)
         /lib/ld-linux.so.2 (0x004f8000)         /lib/ld-linux.so.2 (0x004f8000)
-yoann@hermes:/tmp/helloWorld$ ./hello.dyn +</code> 
 + 
 +<code bash> 
 +$ ./hello.dyn 
 ./hello.dyn: error while loading shared libraries: libmalib.so: cannot open shared object file: No such file or directory ./hello.dyn: error while loading shared libraries: libmalib.so: cannot open shared object file: No such file or directory
 +</code>
 +
 +===== Références =====
  
 +  * https://www.cmi.univ-mrs.fr/~contensi/coursC/index.php?section=env&page=comp
  
dev/outils/gcc.1358692571.txt.gz · Dernière modification : 2021/02/01 21:51 (modification externe)