A macro - это обычная функция Starlark, которая оборачивает (и расширяет до) правила.
def my_macro(name = ..., ...):
native.cc_library(...)
android_library(...)
native.genrule(...)
Думайте о макросах как о способе объединения и группировки нескольких правил, что позволяетвы можете направить вывод одних правил на вход других. На этом уровне вы не думаете о том, как реализовано правило, а о том, с какими типами входов и выходов они связаны.
С другой стороны, правило объявление выполняется с помощью функции rule()
. cc_library
, android_library
и genrule
- все это правила. Реализация rule абстрагируется в обычной функции, которая принимает один параметр для контекста правила (ctx
).
my_rule = rule(
attrs = { ... },
implementation = _my_rule_impl,
)
def _my_rule_impl(ctx):
outfile = ctx.actions.declare_file(...)
ctx.actions.run(...)
return [DefaultInfo(files = depset([outfile]))]
Думайте о действиях как о способе объединения и группировки нескольких командных строк, который работает на уровне отдельных файлов и запускает исполняемые файлы для их преобразования (ctx.actions.run
с exectuable
, args
, inputs
и outputs
аргументы). В рамках реализации правила вы можете извлекать информацию из атрибутов правила (ctx.attr
) или из зависимостей через поставщиков (например, ctx.attr.deps[0][DefaultInfo].files
)
Обратите внимание, что правила можно вызывать только в файлах BUILD, но не в файлах WORKSPACE.
@
- это обозначение для пространства имен репозитория. @bazel_gazelle
- это внешний репозиторий, извлекаемый в WORKSPACE по правилу (не обычное правило)обычно http_archive
или git_repository
. Это правило хранилища также может быть вызвано из макроса, например my_macro
выше или build_tools_deps
в вашем примере.
native.<rule name>
означает, что правило реализовано на Java в Bazel и встроено в двоичный файл, ине в Старларке.