В чем разница между назначениями переменных GNU Makefile =,?=,:= и +=?
может ли кто-нибудь дать четкое объяснение того, как назначение переменных действительно работает в Makefiles.
в чем разница между :
VARIABLE = value
VARIABLE ?= value
VARIABLE := value
VARIABLE += value
прочитал раздел в руководстве GNU Make, но это все еще не имеет смысла для меня.
5 ответов:
Ленивый Набор
VARIABLE = valueнормальная настройка переменной-значения внутри нее рекурсивно расширяются при использовании переменной, а не при ее объявлении
Незамедлительной Установки
VARIABLE := valueустановка переменной с простым расширением значений внутри - значения внутри нее расширяются во время объявления.
Установить, Если Отсутствует
VARIABLE ?= valueнастройки переменной, только если она не имеет значение
добавить
VARIABLE += valueдобавить значение к существующему значению (или параметр это значение, если переменная не существует)
используя
=вызывает присвоение переменной значения. Если переменная уже имела значение, она заменяется. Это значение будет расширено при его использовании. Например:HELLO = world HELLO_WORLD = $(HELLO) world! # This echoes "world world!" echo $(HELLO_WORLD) HELLO = hello # This echoes "hello world!" echo $(HELLO_WORLD)используя
:=похоже на использование=. Однако вместо расширения значения при его использовании оно расширяется во время назначения. Например: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)используя
?=присваивает переменной значение iff переменная ранее не назначалась. Если переменной ранее было присвоено пустое значение (VAR=), он по-прежнему считается set я думаю. В противном случае, функции точно так же, как=.используя
+=как использовать=, но вместо замены значения, значение добавляется к текущему, с пробелом между ними. Если переменная ранее была установлена с:=, он расширяется I думай. Полученное значение расширяется при его использовании я думаю. Например:HELLO_WORLD = hello HELLO_WORLD += world! # This echoes "hello world!" echo $(HELLO_WORLD)если что-то вроде
HELLO_WORLD = $(HELLO_WORLD) world!были использованы, рекурсия приведет, что, скорее всего, завершит выполнение вашего Makefile. Если , результат не будет точно таким же, как при использовании+=, потому чтоBрасширяется с:=, тогда как+=не приведетBбудет расширен.
Я предлагаю вам сделать некоторые эксперименты, используя "make". Вот простая демонстрация, показывающая разницу между
=и:=./* 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принты:x - later y - foo bar a - later b - later bar
при использовании
VARIABLE = value, Еслиvalueна самом деле является ссылкой на другую переменную, то значение определяется только тогда, когда есть. Это лучше всего проиллюстрировать на примере:VAL = foo VARIABLE = $(VAL) VAL = bar # VARIABLE and VAL will both evaluate to "bar"при использовании
VARIABLE := value, вы получаете значениеvalueкак сейчас. Например:VAL = foo VARIABLE := $(VAL) VAL = bar # VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"используя
VARIABLE ?= valозначает, что вы устанавливаете только значениеVARIABLEеслиVARIABLEеще не установлен. Если он еще не установлен, установка значение откладывается доVARIABLEиспользуется (как в Примере 1).
VARIABLE += valueпросто добавляетvalueдоVARIABLE. Фактическое значениеvalueопределяется, как это было, когда он был первоначально установлен, используя либо=или:=.
в приведенных выше ответах,важно понять что означает "значения расширяются во время объявления/использования". Давая значение, как
*.cне влечет за собой какого-либо расширения. Это только для этой строки используется команда, что она может вызвать какие-то подстановка. Аналогично, значение типа$(wildcard *.c)или$(shell ls *.c)не влечет за собой никакого расширения и полностью оценивается во время определения, даже если мы использовали:=в определении переменной.попробуйте следующий Makefile в каталоге, где у вас есть некоторые файлы 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под управлением
makeвызовет правило, которое создает дополнительный (пустой) файл C, называемыйfoo.cно ни одна из 6 переменных не имеетfoo.cв его стоимости.
Comments