Leniwy zestaw
VARIABLE = value
Normalne ustawienie zmiennej, ale wszelkie inne zmienne wymienione w value
polu są rekurencyjnie rozszerzane o ich wartość w punkcie, w którym zmienna jest używana, a nie w tej, którą miała w momencie deklaracji
Zestaw natychmiastowy
VARIABLE := value
Ustawienie zmiennej z prostym rozszerzaniem wartości wewnątrz - wartości w niej są rozszerzane w czasie deklaracji.
Lazy Set If Absent
VARIABLE ?= value
Ustawienie zmiennej tylko wtedy, gdy nie ma wartości. value
jest zawsze oceniany, kiedy VARIABLE
jest dostępny. Jest to równoważne z
ifeq ($(origin FOO), undefined)
FOO = bar
endif
Więcej informacji znajduje się w dokumentacji .
Dodać
VARIABLE += value
Dołączanie podanej wartości do wartości istniejącej (lub ustawienie tej wartości, jeśli zmienna nie istnieje)
Użycie
=
powoduje przypisanie zmiennej wartości. Jeśli zmienna ma już wartość, jest zastępowana. Ta wartość zostanie rozszerzona, gdy zostanie użyta. Na przykład:Korzystanie
:=
jest podobne do korzystania=
. Jednak zamiast wartości, która jest używana, jest ona rozwijana podczas przypisywania. Na przykład:Użycie
?=
przypisuje zmiennej wartość, jeśli zmienna nie była wcześniej przypisana. Jeśli do tej zmiennej wcześniej przypisano pustą wartość (VAR=
), myślę , że nadal jest uważana za zestaw . W przeciwnym razie działa dokładnie tak samo=
.Używanie
+=
jest jak używanie=
, ale zamiast zamiany wartości, wartość jest dołączana do bieżącej, z odstępem pomiędzy nimi. Jeśli zmienna była wcześniej ustawiona za pomocą:=
, to myślę , że jest rozwinięta . Otrzymana wartość jest rozszerzona, gdy jest używany myślę . Na przykład:Jeśli zostanie
HELLO_WORLD = $(HELLO_WORLD) world!
użyte coś podobnego , nastąpi rekurencja, co najprawdopodobniej zakończy wykonanie pliku Makefile. JeśliA := $(A) $(B)
użyto, wynik nie byłby dokładnie taki sam, jak przy użyciu+=
ponieważB
jest rozszerzona o:=
natomiast+=
nie spowodujeB
zostać rozszerzony.źródło
VARIABLE = literal
iVARIABLE := literal
zawsze jest równoważna. Czy dobrze to zrozumiałem?Sugeruję wykonanie kilku eksperymentów z użyciem „make”. Oto proste demo pokazujące różnicę między
=
i:=
.make test
drukuje:Sprawdź bardziej szczegółowe wyjaśnienie tutaj
źródło
@
przodu każdego przepisu, aby uniknąć mylącego powtarzania wyników./* ... */
komentowania blokówGdy używasz
VARIABLE = value
, jeślivalue
tak naprawdę jest odwołaniem do innej zmiennej, to wartość jest określana tylko wtedy, gdyVARIABLE
jest używana. Najlepiej ilustruje to przykład:Kiedy używasz
VARIABLE := value
, otrzymujesz wartośćvalue
taką, jaka jest teraz . Na przykład:Używanie
VARIABLE ?= val
oznacza, że ustawiasz tylko wartośćVARIABLE
if, któraVARIABLE
nie jest już ustawiona. Jeśli nie jest jeszcze ustawiony, ustawienie wartości jest odraczane do momentuVARIABLE
użycia (jak w przykładzie 1).VARIABLE += value
po prostu dołączavalue
doVARIABLE
. Rzeczywista wartośćvalue
jest ustalana w stanie, w jakim była początkowo ustawiona, przy użyciu albo=
lub:=
.źródło
W powyższych odpowiedziach ważne jest, aby zrozumieć, co należy rozumieć przez „wartości są rozszerzane w czasie deklaracji / użytkowania”. Podanie wartości podobnej
*.c
nie pociąga za sobą żadnego rozszerzenia. Tylko wtedy, gdy ten ciąg jest używany przez polecenie, może wywołać trochę globowania. Podobnie, wartość taka jak$(wildcard *.c)
lub$(shell ls *.c)
nie pociąga za sobą żadnego rozszerzenia i jest całkowicie oceniana w czasie definicji, nawet jeśli zastosowaliśmy ją:=
w definicji zmiennej.Wypróbuj następujący Makefile w katalogu, w którym masz jakieś pliki C.
Uruchomienie
make
uruchomi regułę, która tworzy dodatkowy (pusty) plik C, wywoływany,foo.c
ale żadna z 6 zmiennych nie mafoo.c
swojej wartości.źródło