web-dev-qa-db-fra.com

Ajouter à GNU créer des variables via la ligne de commande

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?

57
Michael Koval

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 
79
Carl Norum

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)
26
aib

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.

16
Jezz

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,

  • si une variable a utilisé override une fois, elle ne peut être ajoutée qu'à une autre instruction avec override (les affectations normales seront ignorées);
  • quand il n'y a pas eu de override du tout; essayer d'ajouter (comme dans +=) de la ligne de commande écrase chaque instance de cette variable.
6
sdaau