J'utilise un Makefile GNU-make pour construire un projet C avec plusieurs cibles (all
, clean
, et quelques cibles spécifiques au projet). Dans le processus de débogage, je voudrais ajouter quelques drapeaux à une seule génération sans modifier définitivement le Makefile (par exemple, ajouter des symboles de débogage ou définir un drapeau de préprocesseur).
Dans le passé, je l'ai fait comme suit (en utilisant l'exemple des symboles de débogage):
make target CFLAGS+=-g
Malheureusement, cela ne s'ajoute pas à la variable CFLAGS
, mais à la place, l'efface et l'empêche de compiler. Existe-t-il un moyen propre de le faire sans définir une sorte de variable fictive ajoutée à la fin de CFLAGS
et LDFLAGS
?
Consultez la directive override . Vous devrez probablement modifier le makefile une fois, mais il devrait faire ce que vous voulez.
Exemple de makefile:
override CFLAGS += -Wall
app: main.c
gcc $(CFLAGS) -o app main.c
Exemples de lignes de commande:
$ make
gcc -Wall -o app main.c
$ make CFLAGS=-g
gcc -g -Wall -o app main.c
Pour mémoire, la réponse de @Carl Norum ajoute la variable, du point de vue de la ligne de commande.
J'avais besoin d'un moyen d'ajouter réellement et j'ai trouvé:
override CFLAGS := -Wall $(CFLAGS)
Il existe deux façons de transmettre des variables:
Utilisation d'arguments de ligne de commande:
make VAR=value
Utilisation de l'environnement:
export VAR=var; make
ou (mieux car il ne change l'environnement que pour la commande courante)
VAR=var make
Ils sont légèrement différents. Le premier est plus fort. Cela signifie que vous savez ce que vous voulez. Le second peut être considéré comme un indice. La différence entre eux concerne les opérateurs =
et +=
(sans override
). Ces opérateurs sont ignorés lorsqu'une variable est définie sur la ligne de commande, mais ne sont pas ignorés lorsque la variable est définie dans l'environnement. Ainsi, je vous suggère d'avoir un Makefile avec:
CC ?= gcc
CFLAGS += -Wall
INTERNAL_VARS = value
et appelez-le avec:
CFLAGS=-g make
Remarquez, si vous souhaitez retirer -Wall
, vous pouvez utiliser:
make CFLAGS=
Veuillez ne pas utiliser le mot clé override
, sinon vous n'aurez aucun moyen de modifier une variable affectée par override
.
Juste une note, car je suis confus - que ce soit le fichier testmake
:
$(eval $(info A: CFLAGS here is $(CFLAGS)))
override CFLAGS += -B
$(eval $(info B: CFLAGS here is $(CFLAGS)))
CFLAGS += -C
$(eval $(info C: CFLAGS here is $(CFLAGS)))
override CFLAGS += -D
$(eval $(info D: CFLAGS here is $(CFLAGS)))
CFLAGS += -E
$(eval $(info E: CFLAGS here is $(CFLAGS)))
Alors:
$ make -f testmake
A: CFLAGS here is
B: CFLAGS here is -B
C: CFLAGS here is -B
D: CFLAGS here is -B -D
E: CFLAGS here is -B -D
make: *** No targets. Stop.
$ make -f testmake CFLAGS+=-g
A: CFLAGS here is -g
B: CFLAGS here is -g -B
C: CFLAGS here is -g -B
D: CFLAGS here is -g -B -D
E: CFLAGS here is -g -B -D
make: *** No targets. Stop.
Avec les directives override
supprimées du fichier testmake
:
$ make -f testmake
A: CFLAGS here is
B: CFLAGS here is -B
C: CFLAGS here is -B -C
D: CFLAGS here is -B -C -D
E: CFLAGS here is -B -C -D -E
make: *** No targets. Stop.
$ make -f testmake CFLAGS+=-g
A: CFLAGS here is -g
B: CFLAGS here is -g
C: CFLAGS here is -g
D: CFLAGS here is -g
E: CFLAGS here is -g
make: *** No targets. Stop.
Donc,
override
une fois, elle ne peut être ajoutée qu'à une autre instruction avec override
(les affectations normales seront ignorées);override
du tout; essayer d'ajouter (comme dans +=
) de la ligne de commande écrase chaque instance de cette variable.