- Использование
- Предопределённые переменные
- Предопределённые переменные 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'stools. -
GENDIR: Основание сгенерированного дерева кода для архитектуры цели.
Переменные архитектуры машины
-
TARGET_CPU: Процессор архитектуры цели, например,k8.
Предопределённые переменные genrule
Следующие переменные специально доступны для атрибута genrule's cmd и, как правило, важны для корректной работы этого атрибута.
Пример предопределённых переменных 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. Таким образом, его путь исполнения (подпуть под корнем) —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. Путь исполнения, следовательно,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, rlocationpaths, и location, соответственно. Они поддерживают метки, порождающие несколько выходов, в котором каждый выход отображается через пробел. Правила с нулевым выводом и неправильные метки вызывают ошибки сборки.
Все ссылающиеся метки должны появляться в srcs цели, файлах вывода или deps. В противном случае сборка завершается с ошибкой. Цели C++ также могут ссылаться на метки в data.
Метки не обязательно должны быть в канонической форме: foo, :foo и //somepkg:foo — всё нормально.
Пользовательские переменные
Пользовательские переменные "Make" могут быть использованы любым атрибутом, помеченным как «Подлежащие замене переменными "Make"», но только в целях, которые зависят от других целей, определяющих эти переменные.