Добавление текста к переменным
Часто бывает полезно добавить текст к значению уже определенной переменной. Это делается с помощью строки, содержащей ‘+=’, например:
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