Spec-Zone.ru › Bazel 6.3

"Make" Переменные

  • Использование
  • Предопределённые переменные
  • Предопределённые переменные 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's tools.

  • GENDIR: Основание сгенерированного дерева кода для архитектуры целевой системы.

Переменные архитектуры компьютера

  • TARGET_CPU: Процессор целевой архитектуры, например, k8.

Предопределённые переменные genrule

Следующие переменные доступны специально для атрибута genrule's cmd и, как правило, важны для работы этого атрибута.

Пример предопределённых переменных genrule.

  • OUTS: Список genrule's outs. Если у вас только один выходной файл, вы также можете использовать $@.
  • SRCS: Список genrule's srcs (или точнее: имена путей файлов, соответствующие меткам в списке 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's tools. Таким образом, его выходной файл 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, соответственно. Они поддерживают метки, генерирующие несколько выходных данных, в которых каждый вывод перечисляется, разделенный пробелом. Правила с нулевыми результатами и неверные метки приводят к ошибкам сборки.

Все ссылки должны быть в файлах, зависящих от целевой задачи, выходных или входных данных. В противном случае сборка завершится с ошибкой. C++-цели могут также ссылаться на метки в data.

Метки не обязательно должны быть в каноническом формате: foo, :foo и //somepkg:foo все приемлемы.

Пользовательские переменные

Пользовательские переменные "Make" могут ссылаться на любой помеченный как «Подлежащий подстановке переменных "Make"» атрибут, но только в тех целях, которые зависят от других целей, которые определяют эти переменные.

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

Переменные цепочки инструментов C++

Следующие переменные определены в правилах цепочки инструментов C++ и доступны любому правилу, которое устанавливает toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"] (или "@bazel_tools//tools/cpp:current_cc_host_toolchain" для эквивалента цепочки инструментов хоста). Некоторые правила, такие как java_binary, неявно включают цепочку инструментов C++ в своё определение. Они автоматически наследуют эти переменные.

Встроенные правила C++ намного сложнее, чем просто "запустить компилятор на нём". Для поддержки разнообразных режимов компиляции, таких как *SAN, ThinLTO, с модулями/без модулей и тщательно оптимизированных библиотек одновременно с быстрыми тестами на нескольких платформах, встроенные правила прилагают значительные усилия для обеспечения корректного задания входных и выходных данных, а также флагов командной строки для каждого из потенциально нескольких внутренне сгенерированных действий.

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

  • ABI: Версия ABI C++.
  • AR: Команда "ar" из crosstool.
  • C_COMPILER: Идентификатор компилятора C/C++, например, llvm.
  • CC: Команда компилятора C и C++.

    Мы настоятельно рекомендуем всегда использовать CC_FLAGS в сочетании с CC. Использование без них на свой страх и риск.

  • CC_FLAGS: Минимальный набор флагов для компилятора C/C++, пригодный для использования genrules. В частности, он содержит флаги для выбора правильной архитектуры, если CC поддерживает несколько архитектур.
  • NM: Команда "nm" из crosstool.
  • OBJCOPY: Команда objcopy из того же набора, что и компилятор C/C++.
  • STRIP: Команда strip из того же набора, что и компилятор C/C++.

Переменные цепочки инструментов Java

Следующие переменные определены в правилах цепочки инструментов Java и доступны любому правилу, которое устанавливает toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"] (или "@bazel_tools//tools/jdk:current_host_java_runtime" для эквивалента цепочки инструментов хоста).

Большинство инструментов в JDK не следует использовать напрямую. Встроенные правила Java используют намного более сложные подходы к компиляции и упаковке Java, чем могут выразить инструменты верхнего уровня, такие как интерфейсные JAR-файлы, интерфейсные JAR-файлы заголовков и высокооптимизированные реализации упаковки и слияния JAR-файлов.

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

  • JAVA: Команда "java" (виртуальная машина Java). Избегайте её использования, используйте правило java_binary вместо этого, если это возможно. Может быть относительным путём. Если вам необходимо изменить директорию перед вызовом java, вы должны сохранить рабочую директорию перед её изменением.
  • JAVABASE: Базовая директория, содержащая утилиты Java. Может быть относительным путём. Она будет содержать поддиректорию "bin".

Переменные, определённые в Starlark

Авторы правил и цепочек инструментов могут определять полностью настраиваемые переменные, возвращая поставщик TemplateVariableInfo. Любые правила, зависящие от этих переменных через атрибут toolchains, могут затем считывать их значения:

См. пример переменных, определённых в Starlark.

За исключением случаев, когда указано иное, содержимое этой страницы лицензировано по лицензии Creative Commons Attribution 4.0, а примеры кода лицензированы по лицензии Apache 2.0. Подробности см. в Политиках сайта Google для разработчиков. Java — зарегистрированная торговая марка Oracle и/или её дочерних компаний.

Последнее обновление 2023-07-25 UTC.

Licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License.
https://bazel.build/versions/6.3.0/reference/be/make-variables

Spec-Zone.ru

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