Spec-Zone.ru › GNU Make

Вычисленные имена переменных

Вычисленные имена переменных — это продвинутая концепция, очень полезная в более сложных программах makefile. В простых ситуациях их можно не учитывать, но они могут быть чрезвычайно полезными.

Переменные могут быть упомянуты внутри имени переменной. Это называется вычисляемым именем переменной или вложенной ссылкой на переменную. Например,

x = y
y = z
a := $($(x))

определяет a как ‘z’: ‘$(x)’ внутри ‘$($(x))’ расширяется до ‘y’, поэтому ‘$($(x))’ расширяется до ‘$(y)’, которое, в свою очередь, расширяется до ‘z’. Здесь имя переменной для ссылки не указано явно; оно вычисляется путем расширения ‘$(x)’. Ссылка ‘$(x)’ здесь вложена во внешнюю ссылку на переменную.

Предыдущий пример показывает две уровня вложенности, но возможно любое количество уровней. Например, вот три уровня:

x = y
y = z
z = u
a := $($($(x)))

Здесь внутреннее ‘$(x)’ расширяется до ‘y’, поэтому ‘$($(x))’ расширяется до ‘$(y)’, которое, в свою очередь, расширяется до ‘z’; теперь у нас есть ‘$(z)’, которое становится ‘u’.

Ссылки на рекурсивно расширенные переменные внутри имени переменной повторно расширяются обычным способом. Например:

x = $(y)
y = z
z = Hello
a := $($(x))

определяет a как ‘Hello’: ‘$($(x))’ становится ‘$($(y))’, которая становится ‘$(z)’, которая становится ‘Hello’.

Вложенные ссылки на переменные также могут содержать изменённые ссылки и вызовы функций (см. Функции для преобразования текста), как и любая другая ссылка. Например, используя функцию subst (см. Функции для подстановки и анализа строк):

x = variable1
variable2 := Hello
y = $(subst 1,2,$(x))
z = y
a := $($($(z)))

в конечном итоге определяет a как ‘Hello’. Сомневаюсь, что кто-то когда-либо захочет написать такую ​​сложную вложенную ссылку, но она работает: ‘$($($(z)))’ расширяется до ‘$($(y))’, которая становится ‘$($(subst 1,2,$(x)))’. Это получает значение ‘variable1’ из x и изменяет его заменой на ‘variable2’, так что вся строка становится ‘$(variable2)’, простой ссылкой на переменную, значение которой ‘Hello’.

Вычисляемое имя переменной необязательно должно состоять только из одной ссылки на переменную. Оно может содержать несколько ссылок на переменные, а также некоторую неизменяемую текстовую часть. Например,

a_dirs := dira dirb
1_dirs := dir1 dir2
a_files := filea fileb
1_files := file1 file2
ifeq "$(use_a)" "yes"
a1 := a
else
a1 := 1
endif
ifeq "$(use_dirs)" "yes"
df := dirs
else
df := files
endif

dirs := $($(a1)_$(df))

даст dirs то же значение, что и a_dirs, 1_dirs, a_files или 1_files, в зависимости от настроек use_a и use_dirs.

Вычисляемые имена переменных также могут использоваться в ссылках на подстановку:

a_objects := a.o b.o c.o
1_objects := 1.o 2.o 3.o

sources := $($(a1)_objects:.o=.c)

определяет sources как ‘a.c b.c c.c’ или ‘1.c 2.c 3.c’, в зависимости от значения a1.

Единственное ограничение на использование вложенных ссылок на переменные заключается в том, что они не могут указывать часть имени вызываемой функции. Это связано с тем, что проверка распознавания имени функции выполняется до расширения вложенных ссылок. Например,

ifdef do_sort
func := sort
else
func := strip
endif
bar := a d b g q c
foo := $($(func) $(bar))

пытается присвоить ‘foo’ значение переменной ‘sort a d b g q c’ или ‘strip a d b g q c’, а не присвоить ‘a d b g q c’ в качестве аргумента либо функции sort, либо функции strip. Это ограничение может быть снято в будущем, если это будет признано хорошей идеей.

Вы также можете использовать вычисляемые имена переменных в левой части присваивания переменной или в директиве define, как в:

dir = foo
$(dir)_sources := $(wildcard $(dir)/*.c)
define $(dir)_print =
lpr $($(dir)_sources)
endef

Этот пример определяет переменные ‘dir’, ‘foo_sources’ и ‘foo_print’.

Обратите внимание, что вложенные ссылки на переменные сильно отличаются от рекурсивно расширенных переменных (см. Два типа переменных), хотя оба используются вместе сложными способами при программировании makefile.

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/Computed-Names.html

Spec-Zone.ru

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