- Использование
- Предопределённые переменные
- Предопределённые переменные genrule
- Предопределённые переменные путей к исходникам/выходам
- Пользовательские переменные
Переменные «Make» — это специальный класс расширяемых строковых переменных, доступных атрибутам, помеченным как «Подлежащие подстановке переменных Make».
Их можно использовать, например, для вставки специфических путей инструментальной цепочки в пользовательские действия сборки.
Bazel предоставляет как предопределённые переменные, доступные всем целям, так и пользовательские переменные, которые определяются в зависимых целях и доступны только целям, зависящим от них.
Термин «Make» — исторический: синтаксис и семантика этих переменных изначально предназначались для соответствия GNU Make.
Использование
Атрибуты, помеченные как «Подлежащие подстановке переменных Make», могут ссылаться на переменную Make FOO следующим образом:
my_attr = "prefix $(FOO) suffix"
Другими словами, любая подстрока, соответствующая $(FOO), расширяется до значения FOO. Если это значение "bar", окончательная строка становится:
my_attr = "prefix bar suffix"
Если FOO не соответствует переменной, известной потребляющей цели, Bazel выдаёт ошибку.
Переменные Make с именами, не являющимися символами, такими как @, также могут быть упомянуты, используя только знак доллара без скобок. Например:
my_attr = "prefix $@ suffix"
Чтобы записать $ как строковую литерал (т.е. предотвратить расширение переменной), запишите $$.
Предопределённые переменные
Предопределённые переменные Make могут быть использованы любым атрибутом, помеченным как «Подлежащий подстановке переменных Make», в любой цели.
Чтобы увидеть список этих переменных и их значений для данного набора параметров сборки, выполните
bazel info --show_make_env [build options]
и обратите внимание на верхние строки вывода заглавными буквами.
Пример предопределённых переменных.
Переменные параметров инструментальной цепочки
-
COMPILATION_MODE:fastbuild,dbg, илиopt. (подробнее)
Переменные путей
-
BINDIR: Основание сгенерированного двоичного дерева для архитектуры целевой системы.Обратите внимание, что может использоваться другое дерево для программ, запускаемых во время сборки на хост-архитектуре, чтобы поддерживать кросс-компиляцию.
Если вы хотите запустить инструмент изнутри
genrule, рекомендуемый способ получить его путь —$(execpath toolname), где toolname должен быть перечислен в атрибутеgenruleвtools. -
GENDIR: Основание сгенерированного дерева кода для архитектуры целевой системы.
Переменные архитектуры машины
-
TARGET_CPU: Процессор архитектуры целевой системы, напримерk8.
Предопределённые переменные genrule
Следующие переменные доступны специально для атрибута genrule и обычно важны для работы этого атрибута.
Пример предопределённых переменных genrule.
-
OUTS: Списокgenrule'souts. Если у вас только один выходной файл, вы также можете использовать$@. -
SRCS: Списокgenrule'ssrcs(или, точнее: имена путей к файлам, соответствующим меткам в спискеsrcs). Если у вас только один исходный файл, вы также можете использовать$<. -
<:SRCS, если это единственный файл. Иначе вызывает ошибку сборки. -
@:OUTS, если это единственный файл. Иначе вызывает ошибку сборки. -
RULEDIR: Каталог вывода цели, то есть каталог, соответствующий имени пакета, содержащего цель в деревеgenfilesилиbin. Для//my/pkg:my_genruleон всегда заканчивается наmy/pkg, даже если выходные файлы//my/pkg:my_genruleнаходятся в подкаталогах. -
@D: Каталог вывода. Если outs содержит одну запись, то это каталог, содержащий этот файл. Если несколько, это корневой каталог пакета в деревеgenfiles, даже если все выходные файлы находятся в одном подкаталоге!Примечание: Используйте
RULEDIRвместо@D, так как уRULEDIRболее простая семантика и он ведёт себя одинаково независимо от количества выходных файлов.Если genrule необходимо сгенерировать временные промежуточные файлы (возможно, в результате использования другого инструмента, например, компилятора), он должен попытаться записать их в
@D(хотя/tmpтакже будет доступен) и удалить их перед завершением.Особенно избегайте записи в каталоги, содержащие входные данные. Они могут находиться на файловой системе только для чтения. Даже если нет, это испортит дерево исходников.
Предопределённые переменные путей к исходникам/выходам
Предопределённые переменные execpath, execpaths, rootpath, rootpaths, location, и locations принимают параметры меток (например, $(execpath
//foo:bar)) и подставляют пути к файлам, обозначенные этой меткой.
Для исходных файлов это путь относительно корня вашего рабочего пространства. Для файлов, являющихся результатом правил, это путь вывода файла (см. объяснение выходных файлов ниже).
Пример предопределённых переменных путей.
-
execpath: Обозначает путь в execroot, где Bazel выполняет действия сборки.В приведенном выше примере Bazel выполняет все действия сборки в каталоге, связанном с символической ссылкой
bazel-myprojectв корне вашего рабочего пространства. Исходный файлempty.sourceсвязан по путиbazel-myproject/testapp/empty.source. Таким образом, его путь exec (подпуть под корнем) —testapp/empty.source. Это путь, который могут использовать действия сборки, чтобы найти файл.Выходные файлы подготавливаются аналогично, но также предваряются подпутем
bazel-out/cpu-compilation_mode/bin(или для выходов инструментов:bazel-out/cpu-opt-exec-hash/bin). В приведенном выше примере//testapp:app— инструмент, поскольку он присутствует в атрибутеshow_app_output'stools. Поэтому его выходной файлappзаписывается вbazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app. Таким образом, его путь exec —bazel-out/cpu-opt-exec-hash/bin/testapp/app. Эта дополнительная префиксация позволяет собирать одну и ту же цель для, например, двух разных процессоров в одной сборке, не перезаписывая результаты.Передаваемая метка этой переменной должна представлять ровно один файл. Для меток, представляющих исходные файлы, это автоматически выполняется. Для меток, представляющих правила, правило должно генерировать ровно один выход. Если это ложно или метка неправильна, сборка прерывается с ошибкой.
-
rootpath: Обозначает путь, который сгенерированный двоичный файл может использовать для поиска зависимости во время выполнения относительно подкаталога его каталога runfiles, соответствующего главному репозиторию. Примечание: Это работает только, если--enable_runfilesвключено, что по умолчанию не так на Windows. Используйтеrlocationpathдля кросс-платформенной поддержки.Это аналогично
execpath, но удаляет описанные выше префиксы конфигурации. В примере выше это означает, чтоempty.sourceиappиспользуют чисто относительные пути рабочего пространства:testapp/empty.sourceиtestapp/app.Путь
rootpathфайла в внешнем репозиторииrepoначнется с../repo/, за которым последует путь, относящийся к репозиторию.Это имеет те же требования «только один выходной файл», что и
execpath. -
rlocationpath: Путь, который сгенерированный двоичный файл может передать функцииRlocationбиблиотеки runfiles для поиска зависимости во время выполнения, либо в каталоге runfiles (если доступен), либо с помощью файла манифеста runfiles.Это похоже на
rootpath, поскольку оно не содержит префиксов конфигурации, но отличается тем, что всегда начинается с имени репозитория. В примере выше это означает, чтоempty.sourceиappприводят к следующим путям:myproject/testapp/empty.sourceиmyproject/testapp/app.Путь
rlocationpathфайла в внешнем репозиторииrepoначнется сrepo/, за которым последует путь, относящийся к репозиторию.Передача этого пути двоичному файлу и разрешение его до пути к файловой системе с помощью библиотек runfiles является предпочтительным подходом к поиску зависимостей во время выполнения. По сравнению с
rootpath, он имеет преимущество в том, что работает на всех платформах, даже если каталог runfiles недоступен.Это имеет те же требования «только один выходной файл», что и
execpath. -
location: Синонимexecpathилиrootpath, в зависимости от расширяемого атрибута. Это поведение пре-Starlark, унаследованное от старого кода, и его не рекомендуют использовать, если вы не точно не знаете, для чего оно применяется в конкретном правиле. Подробности см. в #2475.
execpaths, rootpaths, rlocationpaths, и locations — множественные варианты execpath, rootpath, rlocationpath, и location, соответственно. Они поддерживают метки, генерирующие несколько выходов, в котором случае каждый выход перечисляется через пробел. Правила с нулевыми результатами и неправильные метки вызывают ошибки сборки.
Все ссылающиеся метки должны присутствовать в srcs, выходных файлах или deps потребляющей цели. Иначе сборка завершается с ошибкой. Цели C++ также могут ссылаться на метки в data.
Метки не обязательно должны быть в канонической форме: foo, :foo и //somepkg:foo подойдут.
Пользовательские переменные
Пользовательские переменные Make могут быть использованы любым атрибутом, помеченным как «Подлежащий подстановке переменных Make», но только в тех целях, которые зависят от других целей, которые определяют эти переменные.