Annuaire d'articles
Avant-propos :
Dans l'article précédent, j'ai présenté comment utiliser vim . Après avoir appris vim, vous pouvez écrire du code, mais vim n'est qu'un éditeur de texte. Pour faire fonctionner notre code, nous devons utiliser L'outil de compilation que je vais vous présenter aujourd'hui : gcc/g++ . Parmi eux, gcc est un compilateur pour le langage C, et g++ est un compilateur pour C++. Ils sont les mêmes en termes d'utilisation, donc aujourd'hui nous nous concentrons principalement sur gcc. Permettez-moi de vous présenter leurs méthodes d'utilisation afin que vous puissiez démarrer rapidement.
La compilation est principalement divisée en quatre processus : prétraitement, compilation, assemblage et liaison . Les quatre processus spécifiques suivants seront combinés pour introduire l'utilisation de gcc, et quelques connaissances marginales pour améliorer notre force interne seront intercalées.
1. Prétraitement
- Les principales fonctions du prétraitement incluent principalement le remplacement de macros, l'expansion du fichier d'en-tête, la compilation conditionnelle et la suppression des commentaires .
- Les directives de prétraitement sont des lignes de code commençant par # .
- instruction:
gcc -E test.c -o test.i
-E
: indique à gcc d'arrêter le processus de compilation une fois le prétraitement terminé.-o
: écrivez le résultat de la compilation actuelle dans le fichier test.i,.i
qui est un programme source C prétraité (remarque : il s'agit toujours d'un programme source pour le moment).
1.1 Extension du fichier d'en-tête
L'expansion du fichier d'en-tête consiste à copier le contenu du fichier d'en-tête dans le code source actuel, ce qui signifie que le fichier d'en-tête doit exister dans le système avant la compilation, alors comment savoir s'il existe dans le système ? En fait, il n'y a pas lieu de s'inquiéter du tout. Les fichiers d'en-tête font partie de l'environnement de développement. Dans l'environnement Windows, les vs et dev que nous utilisons sont appelés environnements de développement intégrés, qui intègrent l'écriture de code et la compilation. Lorsque nous téléchargeons ces outils, Un kit de développement sera sélectionné, qui consiste en fait à télécharger des fichiers d'en-tête et des fichiers de bibliothèque liés au C. L'environnement Linux est spécialement utilisé par les programmeurs, donc dans la plupart des environnements Linux, les éléments liés à l'environnement de développement, tels que : les éditeurs de code, les compilateurs de code, les fichiers d'en-tête/fichiers de bibliothèque, etc., ont été préparés pour nous à l'avance. Maintenant, nous peut commencer à écrire du code directement. Le répertoire est le chemin de recherche par défaut
/usr/include/
pour les fichiers d'en-tête gcc/g++ sous Linux , et il existe de nombreux fichiers d'en-tête liés au développement sous ce chemin.
1.2 Compilation conditionnelle
La compilation conditionnelle semble rarement apparaître lorsque nous écrivons habituellement du code, mais son rôle ne doit pas être ignoré. Vraisemblablement, lorsque vous téléchargerez un logiciel, il y aura une version communautaire, une version professionnelle, etc. De manière générale, la version communautaire du logiciel aura moins de fonctions que la version professionnelle. Les quelques fonctions sont découpées par compilation conditionnelle. S'il n'y a pas de compilation conditionnelle, alors pour chaque version, le fabricant doit écrire un code correspondant, ce qui est très gênant lors de la maintenance, et il peut y avoir des problèmes avec la version communautaire. Modifié, mais pas pour la version professionnelle. Mais avec la compilation conditionnelle, les fabricants n'ont besoin de maintenir qu'un seul code du début à la fin, pour la version communautaire, ils n'ont qu'à compiler conditionnellement le code de la version professionnelle et à découper les fonctions correspondantes.
Petites astuces : Le fichier obtenu après prétraitement .i
est toujours en langage C, mais il est plus propre que notre code source.
Deux, compilez
- À ce stade, gcc vérifie d'abord la normalisation du code et s'il y a des erreurs grammaticales pour déterminer le travail réel à faire par le code. Une fois la vérification correcte, gcc traduit le code en langage d'assemblage.
- instruction:
gcc -S test.i -o test.s
3. compilation
- L'étape d'assemblage consiste à convertir les instructions d'assemblage du
.s
fichier compilé en un binaire reconnaissable par la machine. Ce fichier binaire est également appelé fichier binaire objet réadressable, ou fichier objet en abrégé . - instruction:
gcc -c test.s -o test.o
4. Liens
- L'étape de liaison consiste à lier le fichier objet et le fichier bibliothèque pour former un programme exécutable
- instruction:
gcc test.o -o mytest
Parfois, nous ferons référence et appellerons d'autres sous-programmes externes dans le programme, ou utiliserons les fonctions fournies par d'autres logiciels . A ce moment, nous devons ajouter la bibliothèque de fonctions dans le processus de compilation. De cette façon, la compilation Le compilateur peut lier tous les codes du programme avec la bibliothèque de fonctions pour générer des fichiers d'exécution corrects.
4.1 Qu'est-ce qu'une bibliothèque ?
Les concepts de bibliothèques et de fonctions de bibliothèque ont été mentionnés ci-dessus. Pour donner un exemple simple : lorsque vous avez appris le langage C pour la première fois, vous devez avoir utilisé printf
des fonctions pour afficher une chaîne de caractères à l'écran. À cette époque, nous savions seulement que #include <stdio.h>
printf pouvait être utilisé tant que nous écrivions une phrase au début de notre code. Nous savons maintenant qu'il stdio.h
s'agit d'un fichier d'en-tête, qui contient certaines déclarations, car il y a printf
des déclarations de fonction dans ce fichier d'en-tête, donc après l'avoir enveloppé, nous pouvons utiliser la fonction printf. La méthode d'implémentation spécifique de printf est en fait placée dans la bibliothèque. On peut dire que la bibliothèque nous fournit l'implémentation de la méthode. La bibliothèque est en fait le fichier source, après une certaine traduction, puis empaqueté, ne fournissant qu'un fichier pour l'utilisateur, pas pour nous. Fournir trop de fichiers source peut également atteindre l'objectif de cacher les fichiers source . Dans le même temps, la bibliothèque empêche également les programmeurs d'inventer leurs propres roues. Donc printf voici ce que nous appelons une fonction de bibliothèque. L'étape de liaison consiste à lier le fichier cible compilé à partir du code source que nous avons écrit avec la bibliothèque, car nous utilisons le langage C, donc le lien par défaut est la bibliothèque standard du langage C. Une bibliothèque est essentiellement un fichier qui existe dans un répertoire spécifique sur le système . La grande majorité des bibliothèques de fonctions sont placées /usr/lib
dans /lib
le répertoire.
La figure ci-dessus montre libc.so.6
la bibliothèque standard du langage C.
4.2 Classement des bibliothèques
Il existe deux types de bibliothèques : les bibliothèques dynamiques et les bibliothèques statiques . Dans l'environnement Linux, le suffixe de la bibliothèque dynamique est .so
, et le suffixe de la bibliothèque statique est .a
. Dans l'environnement Windows, le suffixe de la bibliothèque dynamique est .dll
, et le suffixe de la bibliothèque statique est .lib
. Tous les fichiers de la bibliothèque suivent les mêmes règles de nommage, à savoir : libname.后缀.xxx
.
Petites astuces : Le compilateur gcc trouvera la bibliothèque standard de C par défaut, et il liera le fichier objet obtenu en compilant le code source que nous avons écrit avec le fichier de bibliothèque. C'est pourquoi gcc ne peut pas compiler les fichiers source C++, car gcc recherche la bibliothèque standard C par défaut et ne trouve pas la bibliothèque C++.
4.3 Comment sont liés les fichiers objets et les bibliothèques ?
En général, les liens se répartissent en deux catégories : les liens dynamiques et les liens statiques .
4.3.1 Liaison dynamique
La liaison du fichier objet avec la bibliothèque dynamique est appelée liaison dynamique . La bibliothèque dynamique est comme un cybercafé. Quiconque souhaite se connecter peut se rendre dans ce cybercafé. C'est-à-dire que la bibliothèque dynamique est partagée par tous les programmes et est généralement appelée bibliothèque partagée . Cela signifie qu'une seule bibliothèque dynamique suffit et qu'elle peut répondre aux besoins de tous les programmes.
Les caractéristiques du partage de bibliothèque dynamique rendent impossible la perte de la bibliothèque dynamique , tout comme les cybercafés sont bloqués et les gens ne peuvent pas se connecter. Une fois la bibliothèque dynamique correspondante perdue, non seulement un programme sera affecté, mais plusieurs programmes risquent de ne pas pouvoir s'exécuter normalement.
- Instructions
ldd 可执行程序
, vous pouvez afficher les bibliothèques dynamiques dont dépend un programme exécutable.
Sous Linux, un programme exécutable est compilé dans un programme exécutable et la liaison dynamique est préférée.
4.3.2 Liaison statique
La liaison d'un fichier objet avec une bibliothèque statique est appelée liaison statique . Une bibliothèque statique est comme un centre commercial informatique. Lorsque quelqu'un a besoin d'aller en ligne, il ira au centre commercial informatique pour acheter un ordinateur dédié à son usage personnel uniquement. Lorsque le compilateur utilise la bibliothèque statique pour la liaison statique, il copie sa propre méthode dans le programme cible et le programme ne dépendra plus de la bibliothèque statique à l'avenir .
gcc test.c -o mytest-static -static
- Cela
-static
signifie effectuer une liaison statique, à condition qu'il existe une bibliothèque statique. yum install -y glibc-static
: Installer la bibliothèque statique C
Gcc donne la priorité aux bibliothèques dynamiques par défaut . Si nous n'avons pas de bibliothèques dynamiques mais uniquement des bibliothèques statiques, c'est également possible. -static
L'essentiel est de changer la priorité. Le processus de création de liens n'est pas nécessairement un lien dynamique pur ou un lien statique, les deux peuvent apparaître en même temps, mais si l' -static
option est ajoutée, tous les liens seront transformés en liens statiques.
file mytest
: Vérifiez quel lien le programme exécutable mytest utilise.
4.4 Comparaison des avantages et des inconvénients des liens dynamiques et statiques
avantage | défaut | |
---|---|---|
bibliothèque dynamique | Économisez efficacement les ressources (espace disque, espace mémoire, espace réseau, etc.) | Une fois manquant, tous les programmes ne peuvent pas fonctionner |
bibliothèque statique | Ne dépend pas de la bibliothèque, le programme exécutable compilé avec succès peut être exécuté indépendamment, et il n'est pas nécessaire de demander à l'extérieur de lire le contenu de la fonction de bibliothèque | Grande taille, consomme plus de ressources |
五、Déboguer&&publier
Le débogage est le mode développeur, et l'utilisateur utilise enfin la release . Le code en mode débogage peut être suivi et débogué, car le programme exécutable formé en mode débogage contient des informations de débogage ajoutées. Cela signifie que le programme exécutable obtenu en mode Debug doit être plus grand que le programme exécutable obtenu en mode release.
Le compilateur gcc, par défaut, compile les programmes exécutables en mode release. Pour compiler les programmes exécutables en mode Debug, vous devez ajouter -g
les options suivantes :
gcc test.c -o mytest-Debug -g
readelf -S mytest
: Lit le programme exécutable correspondant sous forme de segments.readelf -S mytest-Debug | grep debug
: Filtrez les segments liés au débogage.
Le partage d'aujourd'hui, c'est par ici ! Si vous pensez que l'article n'est pas mauvais, vous pouvez le soutenir trois fois de suite . Votre soutien est le moteur pour que Chunren avance !