Просто расширяемые переменные присваивания
Чтобы избежать проблем и неудобств с рекурсивно расширяемыми переменными, существует другой вариант: просто расширяемые переменные.
Просто расширяемые переменные определяются строками с использованием ‘:=’ или ‘::=’ (см. Настройка переменных). Обе формы эквивалентны в GNU make; однако только форма ‘::=’ описана в стандарте POSIX (поддержка ‘::=’ добавлена в стандарт POSIX для выпуска POSIX 8).
Значение просто расширяемой переменной сканируется один раз, расширяя любые ссылки на другие переменные и функции, когда переменная определена. После завершения этого расширения значение переменной больше никогда не расширяется: при использовании переменной значение копируется дословно как расширение. Если значение содержало ссылки на переменные, результат расширения будет содержать их значения на момент определения этой переменной. Поэтому,
x := foo y := $(x) bar x := later
эквивалентно
y := foo bar x := later
Вот несколько более сложный пример, иллюстрирующий использование ‘:=’ в сочетании с функцией shell. (См. Функция shell.) Этот пример также демонстрирует использование переменной MAKELEVEL, которая изменяется при передаче с уровня на уровень. (См. Передача переменных подпроцессу make, для получения информации о MAKELEVEL.)
ifeq (0,${MAKELEVEL})
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif
Преимущество такого использования ‘:=’ заключается в том, что типичный рецепт «переход в каталог» выглядит так:
${subdirs}:
${MAKE} -C $@ all
Просто расширяемые переменные обычно делают программирование makefile более предсказуемым, поскольку они работают как переменные в большинстве языков программирования. Они позволяют переопределять переменную, используя ее собственное значение (или ее значение, обработанное каким-либо из функций расширения) и использовать функции расширения намного эффективнее (см. Функции для преобразования текста).
Вы также можете использовать их для ввода контролируемого начального пробела в значения переменных. Пробельные символы, стоящие в начале, удаляются из входных данных перед заменой ссылок на переменные и вызова функций; это означает, что вы можете включать начальные пробелы в значение переменной, защищая их с помощью ссылок на переменные, как в этом примере:
nullstring := space := $(nullstring) # end of the line
Здесь значение переменной space составляет ровно один пробел. Комментарий ‘# конец строки’ включен только для ясности. Поскольку конечные пробельные символы не удаляются из значений переменных, просто пробел в конце строки имел бы тот же эффект (но был бы довольно трудно читаемым). Если вы помещаете пробелы в конце значения переменной, рекомендуется помещать такой комментарий в конце строки, чтобы сделать свой замысел понятным. И наоборот, если вы не хотите никаких пробельных символов в конце значения переменной, вы должны помнить, что не следует помещать случайный комментарий в конце строки после каких-либо пробелов, например, так:
dir := /foo/bar # directory to put the frobs in
Здесь значение переменной dir составляет ‘/foo/bar ’ (с четырьмя конечными пробелами), что, вероятно, не было намерением. (Представьте что-то вроде ‘$(dir)/file’ с этим определением!)
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/Simple-Assignment.html