c makefile tutorial
Dans ce didacticiel Makefile C ++, nous discuterons des principaux aspects de l'outil Make et du makefile, y compris ses avantages et ses applications en C ++:
Dans tout projet C ++, l'un des objectifs importants est de simplifier la construction du projet afin que nous ayons toutes les dépendances et tous les fichiers de projet en un seul endroit et que nous les exécutions en une seule fois afin d'obtenir le résultat souhaité avec une seule commande.
exemple de table de hachage c ++
Dans le même temps, chaque fois que l'un des fichiers du projet est modifié, nous n'avons pas à nous soucier de reconstruire l'intégralité du projet, c'est-à-dire chaque fois qu'un fichier ou deux sont modifiés dans le projet, nous ne reconstruisons que ces fichiers modifiés, puis procédons avec l'exécution.
=> Lisez la série de formations Easy C ++.
Ce sont exactement les fonctionnalités qui sont abordées par l'outil «make» et «makefiles» en C ++. Dans ce tutoriel, nous aborderons tous les aspects majeurs des makefiles ainsi que leurs applications en C ++.
Ce que vous apprendrez:
Faire un outil
Make est un outil UNIX et est utilisé comme un outil pour simplifier la création d'exécutables à partir de différents modules d'un projet. Il existe différentes règles qui sont spécifiées comme entrées cibles dans le makefile. L'outil make lit toutes ces règles et se comporte en conséquence.
Par exemple, si une règle spécifie une dépendance, l'outil make inclura cette dépendance à des fins de compilation. La commande make est utilisée dans le makefile pour construire des modules ou pour nettoyer les fichiers.
La syntaxe générale de make est:
%make target_label #target_label is a specific target in makefile
Par exemple , si nous voulons exécuter des commandes rm pour nettoyer les fichiers, nous écrivons:
% make clean #here clean est un target_label spécifié pour les commandes rm
Makefile C ++
Un makefile n’est rien d’autre qu’un fichier texte qui est utilisé ou référencé par la commande ‘make’ pour construire les cibles. Un makefile contient également des informations telles que les dépendances au niveau source pour chaque fichier ainsi que les dépendances d'ordre de construction.
Voyons maintenant la structure générale de makefile.
Un makefile commence généralement par des déclarations de variables suivies d'un ensemble d'entrées cibles pour la construction de cibles spécifiques. Ces cibles peuvent être .o ou d'autres fichiers exécutables en C ou C ++ et des fichiers .class en Java.
Nous pouvons également avoir un ensemble d'entrées cibles pour exécuter un ensemble de commandes spécifiées par l'étiquette cible.
Donc, un makefile générique est comme indiqué ci-dessous:
# comment target: dependency1 dependency2 ... dependencyn command # (note: the in the command line is necessary for make to work)
Un exemple simple du makefile est montré ci-dessous.
# a build command to build myprogram executable from myprogram.o and mylib.lib all:myprogram.o mylib.o gcc –o myprogram myprogram.o mylib.o clean: $(RM) myprogram
Dans le makefile ci-dessus, nous avons spécifié deux libellés cibles, le premier est le libellé «all» pour construire l'exécutable à partir des fichiers objets myprogram et mylib. Le deuxième libellé cible «nettoyer» supprime tous les fichiers portant le nom «mon programme».
Voyons une autre variante du makefile.
# the compiler: gcc for C program, define as g++ for C++ CC = gcc # compiler flags: # -g - this flag adds debugging information to the executable file # -Wall - this flag is used to turn on most compiler warnings CFLAGS = -g -Wall # The build target TARGET = myprogram all: $(TARGET) $(TARGET): $(TARGET).c $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c clean: $(RM) $(TARGET)
Comme le montre l'exemple ci-dessus, dans ce makefile, nous utilisons la variable «CC» qui contient la valeur du compilateur que nous utilisons (GCC dans ce cas). Une autre variable «CFLAGS» contient les drapeaux du compilateur que nous utiliserons.
La troisième variable «TARGET» contient le nom du programme pour lequel nous devons construire l'exécutable.
L'avantage de mesure de cette variante du makefile est que nous avons juste besoin de changer les valeurs des variables que nous avons utilisées chaque fois qu'il y a un changement dans le compilateur, les drapeaux du compilateur ou le nom du programme exécutable.
Exemple de Make et Makefile
Prenons un exemple de programme avec les fichiers suivants:
- Main.cpp: Programme pilote principal
- Point.h: Fichier d'en-tête pour la classe de points
- Point.cpp: Fichier d'implémentation CPP pour la classe de points
- Square.h: Fichier d'en-tête pour la classe carrée
- Square.cpp; Fichier d'implémentation CPP pour la classe carrée
Avec les fichiers .cpp et .h ci-dessus, nous devons compiler ces fichiers séparément pour générer des fichiers .o, puis les lier dans l'exécutable nommé main.
Ensuite, nous compilons ces fichiers séparément.
- g ++ -c main.cpp: génère main.o
- g ++ -c point.cpp: génère un point. o
- g ++ -c carré.cpp: génère square.o
Ensuite, nous lions les fichiers objets ensemble pour générer l'exécutable main.
g ++ -o main.o principal.o point.o carré.o
Ensuite, nous devons décider lesquels des fichiers que nous devrons recompiler et régénérer lorsque certaines parties du programme seront mises à jour. Pour cela, nous aurons un tableau de dépendance qui montre diverses dépendances pour chacun des fichiers d'implémentation.
Vous trouverez ci-dessous le tableau des dépendances pour les fichiers ci-dessus.
Ainsi, dans le tableau des dépendances ci-dessus, nous pouvons voir l'exécutable «main» à la racine. L’exécutable «main» se compose de fichiers objets, à savoir. main.o, point.o, square.o qui est généré en compilant respectivement main.cpp, point.cpp et square.cpp.
Toutes les implémentations cpp utilisent des fichiers d'en-tête comme indiqué dans le tableau ci-dessus. Comme indiqué ci-dessus, main.cpp fait référence à la fois à point.h et à square.h car il s'agit du programme pilote et utilise des classes point et carré.
Le fichier suivant point.cpp fait référence à point.h. Le troisième fichier square.cpp fait référence à square.h ainsi qu'au point.h car il aura également besoin d'un point pour dessiner le carré.
D'après le tableau des dépendances ci-dessus, il est clair que chaque fois qu'un fichier .cpp ou un fichier .h référencé par un fichier .cpp change, nous devons régénérer ce fichier .o. Par exemple, lorsque main.cpp change, nous devons régénérer le fichier main.o et relier à nouveau les fichiers objets pour générer l'exécutable principal.
Toutes les explications ci-dessus que nous avons données fonctionneront sans problème s'il y a peu de fichiers dans le projet. Lorsque le projet est énorme et que les fichiers sont gros et trop nombreux, il devient alors difficile de régénérer les fichiers à plusieurs reprises.
Ainsi, nous optons pour créer des fichiers et nous utilisons pour créer un outil pour construire le projet et générer l'exécutable.
Nous avons déjà vu différentes parties d'un fichier make. Notez que le fichier doit être nommé «MAKEFILE» ou «makefile» et doit être placé dans le dossier source.
Maintenant, nous allons écrire le makefile pour l'exemple ci-dessus.
Nous définirons des variables pour contenir les valeurs des indicateurs du compilateur et du compilateur comme indiqué ci-dessous.
CC = g++ CFLAGS = -wall -g
Ensuite, nous créons la première cible dans notre makefile, c'est-à-dire l'exécutable main. Nous écrivons donc une cible avec ses dépendances.
principal: main.o point.o square.o
Ainsi, la commande pour générer cette cible est
$(CC) $(CFLAGS) –o main main.o point.o square.o
Noter: La commande ci-dessus se traduit en fait par g ++ -wall –g –o main main.o point.o square.o
Notre prochain objectif sera de générer des fichiers objets, main.o, point.o, square.o
Maintenant, pour générer main.o, la cible sera écrite comme suit:
Main.o: main.cpp point.h square.h
La commande pour cette cible est:
$(CC) $(CFLAGS) –c main.cpp
Le fichier point.o suivant peut être généré à l'aide de la commande ci-dessous:
$(CC) $(CFLAGS) –c point.h
Dans la commande ci-dessus, nous avons ignoré point.cpp. En effet, make sait déjà que les fichiers .o sont générés à partir des fichiers .cpp, donc seul .h (fichier d'inclusion) suffit.
De même, square.o peut être généré avec la commande suivante.
$(CC) $(CFLAGS) –c square.h point.h
L'ensemble du makefile pour cet exemple ressemblera à celui ci-dessous:
# Makefile for Writing Make Files Example # ***************************************************** # Variables to control Makefile operation CC = g++ CFLAGS = -Wall -g # **************************************************** # Targets needed to bring the executable up to date main: main.o Point.o Square.o $(CC) $(CFLAGS) -o main main.o Point.o Square.o # The main.o target can be written more simply main.o: main.cpp Point.h Square.h $(CC) $(CFLAGS) -c main.cpp Point.o: Point.h Square.o: Square.h Point.h
Ainsi, nous voyons que nous avons un makefile complet qui compile trois fichiers C ++ puis génère un exécutable main à partir des fichiers objets.
Avantages des Makefiles
- Lorsqu'il s'agit de grands projets, l'utilisation de makefiles nous aide à représenter le projet de manière systématique et efficace.
- Les makefiles rendent le code source plus concis et plus facile à lire et à déboguer.
- Makefiles compile automatiquement uniquement les fichiers modifiés. Ainsi, nous n'avons pas besoin de régénérer l'ensemble du projet lorsque certaines parties du projet sont modifiées.
- Make tool nous permet de compiler plusieurs fichiers à la fois afin que tous les fichiers puissent être compilés en une seule étape.
Conclusion
Les makefiles sont une aubaine pour le développement de logiciels. En utilisant un makefile C ++, nous pouvons créer des solutions en moins de temps. De même, lorsqu'une partie du projet est modifiée, le makefile recompile et régénère uniquement cette partie sans avoir à régénérer l'ensemble du projet.
C ++ Makefile nous permet de représenter le projet de manière systématique et efficace, le rendant ainsi plus lisible et facile à déboguer.
Dans ce tutoriel C ++ Makefile, nous avons vu makefile et make tools en détail. Nous avons également expliqué comment écrire un makefile à partir de zéro.
=> Consultez le guide de formation Perfect C ++ ici.
lecture recommandée
- 70+ MEILLEURS tutoriels C ++ pour apprendre la programmation C ++ gratuitement
- Développement IDE C ++: installation, fonctionnalités et développement C ++
- Un aperçu complet de C ++
- Objets de fichier VBScript: CopyFile, DeleteFile, OpenTextFile, lecture et écriture de fichier texte
- Tutoriel sur la gestion de fichiers Python: Comment créer, ouvrir, lire, écrire
- Commandes du système de fichiers Unix Touch, Cat, Cp, Mv, Rm, Mkdir (partie B)
- 12 meilleurs IDE et éditeurs de code Python en 2021
- Top 15 des meilleurs éditeurs de code gratuits pour une expérience de codage parfaite