Spec-Zone.ru › GNU Make

Добавление текста к переменным

Часто бывает полезно добавить текст к значению уже определенной переменной. Это делается с помощью строки, содержащей ‘+=’, например:

objects += another.o

Это берет значение переменной objects, и добавляет к нему текст ‘another.o’ (предваряя его одним пробелом, если он уже имеет значение). Таким образом:

objects = main.o foo.o bar.o utils.o
objects += another.o

устанавливает objects в значение ‘main.o foo.o bar.o utils.o another.o’.

Использование ‘+=’ аналогично:

objects = main.o foo.o bar.o utils.o
objects := $(objects) another.o

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

Когда переменная, о которой идет речь, не была определена ранее, ‘+=’ ведет себя так же, как обычный ‘=’: она определяет рекурсивно-расширяемую переменную. Однако, когда существует предыдущее определение, то, что делает ‘+=’, зависит от типа переменной, которую вы изначально определили. См. Два типа переменных для объяснения двух типов переменных.

Когда вы добавляете к значению переменной с помощью ‘+=’, make действует так, как будто вы включили дополнительный текст в исходное определение переменной. Если вы сначала определили ее с помощью ‘:=’ или ‘::=’, сделав ее просто-расширяемой переменной, ‘+=’ добавляет к этому просто-расширяемому определению и расширяет новый текст перед добавлением его к старому значению, точно так же, как ‘:=’ (см. Установка переменных для полного объяснения ‘:=’ или ‘::=’). Фактически,

variable := value
variable += more

точно эквивалентно:

variable := value
variable := $(variable) more

С другой стороны, когда вы используете ‘+=’ с переменной, которую вы сначала определили как рекурсивно-расширяемую, используя просто ‘=’ или ‘:::=’, make добавляет нерасширенный текст к существующему значению, какое бы оно ни было. Это означает, что

variable = value
variable += more

приблизительно эквивалентно:

temp = value
variable = $(temp) more

за исключением того, что, конечно, она никогда не определяет переменную с именем temp. Важность этого становится ясна, когда старое значение переменной содержит ссылки на другие переменные. Рассмотрим этот распространенный пример:

CFLAGS = $(includes) -O
…
CFLAGS += -pg # enable profiling

Первая строка определяет переменную CFLAGS со ссылкой на другую переменную, includes. (CFLAGS используется правилами компиляции C; см. Каталог встроенных правил.) Использование ‘=’ для определения делает CFLAGS рекурсивно-расширяемой переменной, что означает, что ‘$(includes) -O’ не расширяется, когда make обрабатывает определение CFLAGS. Таким образом, includes не обязательно должна быть определена для того, чтобы ее значение вступило в силу. Она должна быть определена только до любой ссылки на CFLAGS. Если бы мы попытались добавить к значению CFLAGS без использования ‘+=’, мы могли бы сделать это так:

CFLAGS := $(CFLAGS) -pg # enable profiling

Это довольно близко, но не совсем то, что мы хотим. Использование ‘:=’ переопределяет CFLAGS как просто-расширяемую переменную; это означает, что make расширяет текст ‘$(CFLAGS) -pg’ перед установкой переменной. Если includes еще не определена, мы получим ‘ -O -pg’, и последующее определение includes не повлияет. И наоборот, используя ‘+=’, мы устанавливаем CFLAGS в нерасширенное значение ‘$(includes) -O -pg’. Таким образом, мы сохраняем ссылку на includes, поэтому, если эта переменная будет определена в любой момент позже, ссылка, такая как ‘$(CFLAGS)’, по-прежнему использует ее значение.

Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/make/manual/html_node/Appending.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API