Le processus de compilation du compilateur gcc sous Linux

1. Qu'est-ce que GCC

GCC est un logiciel libre publié sous licence GPL et est également un élément clé du projet GNU. L'intention originale de GCC était d'écrire un compilateur pour le système d'exploitation GNU, et il a été adopté comme compilateur standard par la plupart des systèmes d'exploitation de type Unix (tels que Linux, BSD, MacOS X, etc.), et il peut même être utilisé sur Microsoft Windows GCC. GCC prend en charge une variété de puces d'architecture informatique, telles que x86, ARM, MIPS, etc., et a été porté sur une variété d'autres plates-formes matérielles. Ici, nous expliquons d'abord principalement l'utilisation du langage C gcc sous Linux.

1. Comment utiliser gcc

gcc [选项] 文件名
在linux下我们可以使用 gcc --help 查看gcc的各个选项

2. Options courantes de gcc

Insérez la description de l'image ici

Le processus de compilation de gcc

Le processus de compilation gcc peut être décomposé en 4 étapes principales:

Prétraitement (Prétraitement)
Compilation (Compilation)
Assemblage (Assemblage)
Liaison (Liaison)

Insérez la description de l'image ici

Parlons des étapes spécifiques de la compilation gcc

1. Prétraitement

Le prétraitement consiste à lire le programme source c et à "remplacer" les pseudo-instructions et les symboles spéciaux qu'il contient; après ce traitement, un fichier de sortie sans définitions de macro, sans instructions de compilation conditionnelle et sans symboles spéciaux est généré. La signification de ce fichier est la même que celle du fichier source qui n'a pas été prétraité. Il s'agit toujours d'un fichier C, mais le contenu est différent. Les pseudo-instructions incluent principalement les trois aspects suivants:
(1) Instructions de définition de macro, telles que #define NAME TokenString, #undef et certaines macros intégrées dans le compilateur, telles que __DATE__, FILE, LINE, TIME, __FUNCTION__, etc. .
(2) Instructions de compilation conditionnelle, telles que #ifdef, #ifndef, #else, #elif, #endif, etc.
(3) Le fichier d'en-tête contient des instructions, telles que #include "FileName" ou #include, etc.

Le processus de prétraitement comprend principalement les processus suivants:

  • Supprimez tous les #defines et développez toutes les définitions de macro
  • Traitez toutes les instructions de précompilation conditionnelle, telles que #if, #ifdef, #elif, #else, #endif, etc.
  • Traitez la directive précompilée #include et insérez le fichier inclus à la position de la directive précompilée.
  • Supprimer tous les commentaires "//" et "/ * * /"
  • Ajoutez des numéros de ligne et des identificateurs de fichier afin que les numéros de ligne de débogage et les numéros de ligne d'avertissement d'erreur de compilation puissent être générés lors de la compilation.
  • Conservez toutes les directives du compilateur #pragma, car le compilateur doit les utiliser

La commande suivante est généralement utilisée pour le prétraitement. Le paramètre -E signifie uniquement le prétraitement:
gcc -E hello.c -o hello.i
Vous pouvez également utiliser la commande suivante pour terminer le processus de prétraitement, où cpp est le préprocesseur:
cpp hello. c> bonjour.i

Le résultat prétraité hello.i est toujours le code source du langage c, nous pouvons utiliser la commande cat ou vim pour afficher son code
vim hello.i

2. Compilez

Le travail que le compilateur doit faire est de passer une analyse lexicale et une analyse grammaticale, après avoir confirmé que toutes les instructions sont conformes aux règles grammaticales, les traduire en représentations de code intermédiaire équivalentes ou en codes d'assemblage . Si vous souhaitez en savoir plus sur le processus de compilation, vous pouvez vous référer à d'autres blogs.

Nous pouvons utiliser la commande suivante pour compiler et générer un fichier d'assemblage:
gcc -S hello.i> hello.s
Nous pouvons utiliser la commande cat pour afficher son code:
cat hello.s

3. Compilation

Le processus d'assemblage traduit en fait le code du langage d'assemblage en instructions de la machine cible . Pour chaque programme source en langage c traité par le système de traduction, le fichier cible correspondant sera finalement obtenu par un processus.

Nous pouvons utiliser la commande suivante pour assembler:
gcc -c hello.s -o hello.o

4. Lien

Le fichier objet généré par l'assembleur ne peut pas être exécuté immédiatement et il peut y avoir de nombreux problèmes non résolus. Par exemple, une fonction dans un fichier source peut référencer un symbole défini dans un autre fichier source (tel qu'un appel de variable ou de fonction, etc.); une fonction dans un fichier de bibliothèque peut être appelée dans un programme, etc., tous Ces problèmes doivent être liés pour être résolus. La tâche principale de l'éditeur de liens est de relier les fichiers objets pertinents les uns aux autres, c'est-à-dire de lier les symboles référencés dans un fichier avec la définition du symbole dans un autre fichier, de sorte que tous ces les fichiers objets deviennent un tout unifié qui peut être chargé et exécuté par le système d'exploitation, c'est-à-dire des programmes exécutables. Selon les différentes méthodes de liaison des fonctions de la bibliothèque spécifiées par le développeur, le processus de liaison peut être divisé en deux types: ①Lien statique ②Lien dynamique.

Pour l'appel de fonction dans le fichier exécutable, les méthodes de liaison dynamique ou de liaison statique peuvent être adoptées respectivement. L'utilisation de la liaison dynamique peut raccourcir le fichier exécutable final et économiser de la mémoire lorsque l'objet partagé est utilisé par plusieurs processus, car une seule copie du code de l'objet partagé doit être stockée dans la mémoire . Cependant, l'utilisation de la liaison dynamique n'est pas nécessairement meilleure que celle de la liaison statique. Dans certains cas, la liaison dynamique peut nuire aux performances .

Je suppose que tu aimes

Origine blog.csdn.net/KingRing_/article/details/115051281
conseillé
Classement