Question Quelle est la différence entre les affectations de variables GNU Makefile =,? =,: = Et + =?


Quelqu'un peut-il donner une explication claire de la façon dont l'affectation variable fonctionne vraiment dans Makefiles.

Quelle est la différence entre :

 VARIABLE = value
 VARIABLE ?= value
 VARIABLE := value
 VARIABLE += value

J'ai lu le section dans le manuel de GNU Make, mais ça n'a toujours pas de sens pour moi.


610
2018-01-15 23:19


origine


Réponses:


Lazy Set

VARIABLE = value

Le réglage normal d'une variable - les valeurs à l'intérieur sont récursivement développées quand la variable est utilisée, pas quand elle est déclarée

Set immédiat

VARIABLE := value

La définition d'une variable avec une expansion simple des valeurs internes à l'intérieur de celle-ci est développée au moment de la déclaration.

Définir si absent

VARIABLE ?= value

Réglage d'une variable uniquement si elle n'a pas de valeur

Ajouter

VARIABLE += value

Ajout de la valeur fournie à la valeur existante (ou réglage à cette valeur si la variable n'existe pas)


831
2018-01-15 23:25



En utilisant = provoque l'attribution d'une valeur à la variable. Si la variable avait déjà une valeur, elle est remplacée. Cette valeur sera développée quand elle sera utilisée. Par exemple:

HELLO = world
HELLO_WORLD = $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# This echoes "hello world!"
echo $(HELLO_WORLD)

En utilisant := est similaire à l'utilisation =. Cependant, au lieu que la valeur soit étendue lorsqu'elle est utilisée, elle est développée pendant l'affectation. Par exemple:

HELLO = world
HELLO_WORLD := $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# Still echoes "world world!"
echo $(HELLO_WORLD)

HELLO_WORLD := $(HELLO) world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

En utilisant ?= affecte une valeur à la variable sff la variable n'a pas été précédemment affectée. Si la valeur précédemment attribuée à la variable était vide (VAR=), il est toujours considéré comme je pense. Sinon, des fonctions exactement comme =.

En utilisant += est comme utiliser =, mais au lieu de remplacer la valeur, la valeur est ajoutée à la valeur actuelle, avec un espace entre les deux. Si la variable a été définie précédemment avec :=, il est élargi je pense. La valeur résultante est développée lorsqu'elle est utilisée je pense. Par exemple:

HELLO_WORLD = hello
HELLO_WORLD += world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

Si quelque chose comme HELLO_WORLD = $(HELLO_WORLD) world! étaient utilisés, la récursivité en résulterait, ce qui mettrait probablement fin à l'exécution de votre Makefile. Si A := $(A) $(B) ont été utilisés, le résultat ne serait pas exactement le même que += car B est élargi avec := tandis que += ne causerait pas B être étendu.


216
2018-01-15 23:34



Je vous suggère de faire quelques expériences en utilisant "make". Voici une démo simple, montrant la différence entre = et :=.

/* Filename: Makefile*/
x := foo
y := $(x) bar
x := later

a = foo
b = $(a) bar
a = later

test:
    @echo x - $(x)
    @echo y - $(y)
    @echo a - $(a)
    @echo b - $(b)

make test impressions:

x - later
y - foo bar
a - later
b - later bar

Vérifiez l'explication plus élaborée ici


43
2017-12-23 14:43



Lorsque vous utilisez VARIABLE = value, si value est en fait une référence à une autre variable, alors la valeur est seulement déterminée quand VARIABLE est utilisé. Ceci est mieux illustré avec un exemple:

VAL = foo
VARIABLE = $(VAL)
VAL = bar

# VARIABLE and VAL will both evaluate to "bar"

Lorsque vous utilisez VARIABLE := value, vous obtenez la valeur de value  comme c'est maintenant. Par exemple:

VAL = foo
VARIABLE := $(VAL)
VAL = bar

# VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"

En utilisant VARIABLE ?= val signifie que vous définissez uniquement la valeur de VARIABLE  si  VARIABLE n'est pas déjà défini. Si ce n'est déjà fait, le réglage de la valeur est différé jusqu'à VARIABLE est utilisé (comme dans l'exemple 1).

VARIABLE += value vient s'ajouter value à VARIABLE. La valeur réelle de value est déterminé tel qu'il était à l'origine, en utilisant soit = ou :=.


27
2018-01-15 23:26



Dans les réponses ci-dessus, il est important de comprendre ce que l'on entend par "les valeurs sont étendues au moment de la déclaration / utilisation". Donner une valeur comme *.cn'entraîne aucune extension. Ce n'est que lorsque cette chaîne est utilisée par une commande qu'elle déclenchera peut-être une certaine globalisation. De même, une valeur comme $(wildcard *.c) ou $(shell ls *.c) n'entraîne aucune expansion et est complètement évalué au moment de la définition même si nous avons utilisé := dans la définition de la variable.

Essayez le Makefile suivant dans le répertoire où vous avez des fichiers C:

VAR1 = *.c
VAR2 := *.c
VAR3 = $(wildcard *.c)
VAR4 := $(wildcard *.c)
VAR5 = $(shell ls *.c)
VAR6 := $(shell ls *.c)

all :
    touch foo.c
    @echo "now VAR1 = \"$(VAR1)\"" ; ls $(VAR1)
    @echo "now VAR2 = \"$(VAR2)\"" ; ls $(VAR2)
    @echo "now VAR3 = \"$(VAR3)\"" ; ls $(VAR3)
    @echo "now VAR4 = \"$(VAR4)\"" ; ls $(VAR4)
    @echo "now VAR5 = \"$(VAR5)\"" ; ls $(VAR5)
    @echo "now VAR6 = \"$(VAR6)\"" ; ls $(VAR6)
    rm -v foo.c

Fonctionnement make déclenchera une règle qui crée un fichier C supplémentaire (vide), appelé foo.c mais aucune des 6 variables a foo.c dans sa valeur.


5
2017-12-12 11:40