В чем разница между назначениями переменных GNU Makefile =,?=,:= и +=?



может ли кто-нибудь дать четкое объяснение того, как назначение переменных действительно работает в Makefiles.



в чем разница между :



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


прочитал раздел в руководстве GNU Make, но это все еще не имеет смысла для меня.

560   5  

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

    Ничего не найдено.