J'ai créé un fichier makefile pour compiler et lier mon programme, cependant, je ne peux pas comprendre pourquoi je reçois cette erreur. Est-ce à voir avec SDL?
GCC = gcc
CFLAGS = -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g
SDL = -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer
all: ./game
game: global.o display.o player.o entities.o controls.o sound.o menu.o
$(GCC) $(CFLAGS) global.o display.o player.o entities.o controls.o sound.o menu.o -o game
global.o: global.c
$(GCC) $(CFLAGS) $(SDL) global.c
display.o: display.c
$(GCC) $(CFLAGS) $(SDL) display.c
player.o: player.c
$(GCC) $(CFLAGS) $(SDL) player.c
entities.o: entities.c
$(GCC) $(CFLAGS) $(SDL) entities.c
controls.o: controls.c
$(GCC) $(CFLAGS) $(SDL) controls.c
sound.o: sound.c
$(GCC) $(CFLAGS) $(SDL) sound.c
menu.o: menu.c
$(GCC) $(CFLAGS) $(SDL) menu.c
clean:
rm *o game
il y a plusieurs petits oublis dans le makefile posté.
Parmi eux:
par exemple:
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
.PHONY:
tôt dans le fichier make:similaire à:
.PHONY : all clean
le fichier de marque publié ne dispose d'aucun moyen pour gérer les fichiers d'en-tête associés. Il existe plusieurs façons de gérer cela. Ceci suit le fil conducteur des OP et ne gère pas les fichiers d’en-tête, donc changer un fichier d’en-tête ne recompilera/ne reliera pas les fichiers source affectés.
cette ligne: rm *o game
ne supprimera pas les fichiers name.o car il manque le '.' entre le nom de la racine et l'extension 'o'. De plus, le drapeau '-f' devrait être utilisé avec la commande 'rm'.
suggérer:
rm -f *.o game
all: ./game
peut créer des problèmes suggérer:
all: game
en utilisant les opérateurs make:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ -I.
le paramètre -g
du compilateur et de l'éditeur de liens permet d'utiliser un débogueur. Si ce débogueur est gdb
, un meilleur paramètre est -ggdb
presque toujours, il n'est pas nécessaire d'évaluer une définition de macro plus d'une fois. Par conséquent, plutôt que d'utiliser =
dans une définition de macro, utilisez :=
Si vous souhaitez que la variable game
soit exécutable, insérez une commande chmod
comme dernière ligne de la règle 'link'
Suggérez des lectures sur les opérateurs spéciaux pouvant être employés dans une makefile
pour vous aider à comprendre le fichier Make suggéré suivant.
Il est généralement préférable de remplacer les appels aux commandes reconnues du shell par des macros.
CC := /user/bin/gcc
RM := /usr/bin/rm
CFLAGS := -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -ggdb
LFLAGS := -std=c99 -O3 -ggdb
SDL := -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer
SRC := $(wildcard *.c)
OBJS := $(SRC:.c=.o)
.PHONY : all clean
all: game
game: $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o $@ $(SDL) -lm
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ -I.
clean:
$(RM) -f *.o game
Votre commande de liaison s'étend à:
gcc -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g global.o display.o player.o entities.o controls.o sound.o menu.o -o game
qui, comme vous pouvez le constater, contient l'indicateur -c
. L’indicateur -c
indique à gcc not de faire un lien. Donc, cela n’a rien à faire. (Les fichiers .o
ne peuvent être utilisés que pour la liaison et vous avez désactivé la liaison, raison pour laquelle vous recevez ce message)
Vous ne voulez pas utiliser les mêmes drapeaux pour la compilation et la liaison. Pour la compilation, vous voulez probablement -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g
, et pour la liaison, vous voulez -lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g
.
Ne mettez pas -lm
ni les bibliothèques SDL dans CFLAGS
, les opérandes de bibliothèque vont à la fin de la ligne de commande. À la place, utilisez une variable supplémentaire LDLIBS
et modifiez votre règle game
comme suit:
game: global.o display.o player.o entities.o controls.o sound.o menu.o
$(GCC) $(CFLAGS) -o $@ global.o display.o player.o entities.o controls.o sound.o menu.o $(LDLIBS)
L'opérande -lm
(ce n'est pas une option) et les opérandes pour SDL s'appliquent uniquement lors de la liaison. Par conséquent, ils ne doivent pas faire partie de CFLAGS
et ne doivent pas être spécifiés lors de la compilation sans liaison (c'est-à-dire lorsque -c
est fourni).