CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
Que font $@
et $<
font exactement?
Réponses:
$@
est le nom du fichier généré et$<
le premier prérequis (généralement le fichier source). Vous pouvez trouver une liste de toutes ces variables spéciales dans le manuel GNU Make .Par exemple, considérez la déclaration suivante:
Dans ce cas:
$@
évalue àall
$<
évalue àlibrary.cpp
$^
évalue àlibrary.cpp main.cpp
la source
$@
cela ne doit pas nécessairement être un fichier, il peut également s'agir du nom d'une.PHONY
cible.$@s
pour générer une sortie d'assembly telle que name.os?Les
$@
et$<
sont appelés variables automatiques . La variable$@
représente le nom du fichier créé (c'est-à-dire la cible) et$<
représente la première condition préalable requise pour créer le fichier de sortie.Par exemple:
Voici
hello.o
le fichier de sortie. C'est ce qui se$@
développe. La première dépendance esthello.c
. C'est ce qui se$<
développe.Le
-c
drapeau génère le.o
fichier; voirman gcc
pour une explication plus détaillée. Le-o
spécifie le fichier de sortie à créer.Pour plus de détails, vous pouvez lire cet article sur les Makefiles Linux .
Vous pouvez également consulter les manuels GNU
make
. Cela facilitera la création de Makefiles et leur débogage.Si vous exécutez cette commande, elle affichera la base de données makefile:
la source
$<
s'étendre àhello.c hello.h
(les deux). Précisez s'il vous plaît.$<
n'est que le premier élément. Pour tout inclure, utilisez$^
.Extrait de Gestion de projets avec GNU Make, 3e édition, p. 16 (il est sous licence de documentation gratuite GNU ):
la source
Les
$@
et$<
sont des macros spéciales.Où:
$@
est le nom de fichier de la cible.$<
est le nom de la première dépendance.la source
Le Makefile construit l'
hello
exécutable si l'unemain.cpp
,hello.cpp
, afactorial.cpp
changé. Le Makefile le plus petit possible pour atteindre cette spécification aurait pu être:Pour améliorer ce qui précède, nous compilons uniquement les fichiers C ++ qui ont été modifiés. Ensuite, nous lions simplement les fichiers d'objets résultants ensemble.
Pour améliorer cela, nous pouvons remplacer toutes les règles de fichier objet par une seule
.cpp.o
règle:Ici, la
.cpp.o
règle définit comment construire àanyfile.o
partir deanyfile.cpp
.$<
correspond à la première dépendance, dans ce cas,anyfile.cpp
$@
correspond à la cible, dans ce casanyfile.o
,.Les autres modifications présentes dans le Makefile sont:
la source
par exemple si vous souhaitez compiler des sources mais avoir des objets dans un répertoire différent:
Tu as besoin de faire :
mais avec la plupart des macros, le résultat sera tous les objets suivis de toutes les sources, comme:
donc cela ne compilera rien ^^ et vous ne pourrez pas mettre vos fichiers objets dans un répertoire différent :(
la solution est d'utiliser ces macros spéciales
cela générera un fichier .o (obj / file.o) pour chaque fichier .c dans SRC (src / file.c)
ça veut dire :
mais lignes par lignes AU LIEU de toutes les lignes de OBJ suivies de toutes les lignes de SRC
la source