#bazel #bazel-rules
#bazel #bazel-правила
Вопрос:
Редактировать: приведенный ниже пример действительно сработал, я неверно истолковал вывод, который дал мне компилятор. Ответ все еще может быть полезен для некоторых.
Есть ли способ для действия в правиле сгенерировать файл, который используется более поздним действием в том же правиле?
Например.:
def _example_rule_impl(ctx):
thefile = ctx.actions.declare_file("required_file.json")
ctx.actions.write(
output = thefile,
content = "CONTENT",
)
args = ctx.actions.args()
args.add("--config", thefile)
ctx.actions.run(
inputs = ctx.files.srcs ctx.files.deps [thefile],
outputs = outs,
arguments = [args],
progress_message = "Compiling...",
executable = ctx.executable._compiler,
)
Основная проблема с этим, по-видимому, заключается в том, что все выходные данные действия, похоже, записываются в bazel-out, но для выполнения действия требуется, чтобы сгенерированный файл был записан рядом с файлами srcs и deps в execroot, чтобы он работал. Есть ли способ записать действие в execroot или это неправильный подход?
Ответ №1:
Действия, использующие выходные данные других действий в качестве входных данных, — это очень типичная вещь, и в основном она должна работать так, как вы ее настроили. Bazel заботится об обработке входных и выходных файлов, например, в Linux с использованием большого количества символических ссылок, монтируя вещи в изолированные ячейки, загружая и загружая файлы для удаленного выполнения и т.д.
См. https://docs.bazel.build/versions/main/output_directories.html
Кроме того, относительно этой строки:
inputs = ctx.files.srcs ctx.files.deps [thefile],
В зависимости от того, что вам нужно сделать, вы можете захотеть использовать depsets по соображениям производительности. См.
https://docs.bazel.build/versions/main/skylark/depsets.html и, в частности, в конце https://docs.bazel.build/versions/main/skylark/depsets.html#performance
Комментарии:
1. Спасибо! Оказалось, что это работало все время, и я просто неверно истолковал ошибку, которую выдал мне компилятор. Что касается depsets: я использовал один, но избавился от него, пытаясь найти проблему. Однако я не уверен, правильно ли я его использовал. Я бы просто поместил все файлы в один файл? входные данные = depset(ctx.files.srcs ctx.files.deps [thefile])? Или мне создать depset для каждого из них и добавить их к транзитивным зависимостям друг друга?
2. Это зависит от того, как структурированы ваши правила. Depsets в основном предназначены для предотвращения квадратичного использования памяти / конкатенации в структурах данных между целями. Например, foo(name=»a», deps= [«b»]) foo(name=»b», deps = [«c»]) foo(name= «c», deps = [«d»]) без depsets может привести к [a, b, c, d], [b, c, d], [c, d], [d], если foo использует списки. Однако, если вы не объединяете подобные элементы по «слоям» графика построения, для
inputs
этого вам не обязательно нужны depsets.