Toolchain не загружает инструмент
Привет, я пытаюсь настроить набор инструментов для проекта Fn. Подход заключается в том, чтобы создать набор инструментов для каждого двоичного файла, доступного в GitHub, а затем теоретически использовать его в правиле.
У меня есть общий пакет, который имеет доступные двоичные файлы:
default_version = "0.5.44"
os_list = [
"linux",
"mac",
"windows"
]
def get_bin_name(os):
return "fn_cli_%s_bin" % os
Часть загрузки выглядит так:
load(":common.bzl", "get_bin_name", "os_list", "default_version")
_url = "https://github.com/fnproject/cli/releases/download/{version}/{file}"
_os_to_file = {
"linux" : "fn_linux",
"mac" : "fn_mac",
"windows" : "fn.exe",
}
def _fn_binary(os):
name = get_bin_name(os)
file = _os_to_file.get(os)
url = _url.format(
file = file,
version = default_version
)
native.http_file(
name = name,
urls = [url],
executable = True
)
def fn_binaries():
"""
Installs the hermetic binary for Fn.
"""
for os in os_list:
_fn_binary(os)
Затем я настроил цепочку инструментов следующим образом:
load(":common.bzl", "get_bin_name", "os_list")
_toolchain_type = "toolchain_type"
FnInfo = provider(
doc = "Information about the Fn Framework CLI.",
fields = {
"bin" : "The Fn Framework binary."
}
)
def _fn_cli_toolchain(ctx):
toolchain_info = platform_common.ToolchainInfo(
fn_info = FnInfo(
bin = ctx.attr.bin
)
)
return [toolchain_info]
fn_toolchain = rule(
implementation = _fn_cli_toolchain,
attrs = {
"bin" : attr.label(mandatory = True)
}
)
def _add_toolchain(os):
toolchain_name = "fn_cli_%s" % os
native_toolchain_name = "fn_cli_%s_toolchain" % os
bin_name = get_bin_name(os)
compatibility = ["@bazel_tools//platforms:%s" % os]
fn_toolchain(
name = toolchain_name,
bin = ":%s" % bin_name,
visibility = ["//visibility:public"]
)
native.toolchain(
name = native_toolchain_name,
toolchain = ":%s" % toolchain_name,
toolchain_type = ":%s" % _toolchain_type,
target_compatible_with = compatibility
)
def setup_toolchains():
"""
Macro te set up the toolchains for the different platforms
"""
native.toolchain_type(name = _toolchain_type)
for os in os_list:
_add_toolchain(os)
def fn_register():
"""
Registers the Fn toolchains.
"""
path = "//tools/bazel_rules/fn/internal/cli:fn_cli_%s_toolchain"
for os in os_list:
native.register_toolchains(path % os)
В моем файле BUILD я вызываю setup_toolchains:
load(":toolchain.bzl", "setup_toolchains")
setup_toolchains()
С этой настройкой у меня есть правило, которое выглядит так:
_toolchain = "//tools/bazel_rules/fn/cli:toolchain_type"
def _fn(ctx):
print("HEY")
bin = ctx.toolchains[_toolchain].fn_info.bin
print(bin)
# TEST RULE
fn = rule(
implementation = _fn,
toolchains = [_toolchain]
)
Workpace:
workspace(name = "basicwindow")
load("//tools/bazel_rules/fn:defs.bzl", "fn_binaries", "fn_register")
fn_binaries()
fn_register()
Когда я запрашиваю различные двоичные файлы с bazel query //tools/bazel_rules/fn/internal/cli:fn_cli_linux_bin
они там, но звонят bazel build //...
приводит к ошибке, которая жалуется на:
ERROR: /Users/marcguilera/Code/Marc/basicwindow/tools/bazel_rules/fn/internal/cli/BUILD.bazel:2:1: in bin attribute of fn_toolchain rule //tools/bazel_rules/fn/internal/cli:fn_cli_windows: rule '//tools/bazel_rules/fn/internal/cli:fn_cli_windows_bin' does not exist. Since this rule was created by the macro 'setup_toolchains', the error might have been caused by the macro implementation in /Users/marcguilera/Code/Marc/basicwindow/tools/bazel_rules/fn/internal/cli/toolchain.bzl:35:15
ERROR: Analysis of target '//tools/bazel_rules/fn/internal/cli:fn_cli_windows' failed; build aborted: Analysis of target '//tools/bazel_rules/fn/internal/cli:fn_cli_windows' failed; build aborted
INFO: Elapsed time: 0.079s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured)
Я пытался следовать учебному пособию по инструментарию в документации, но не могу заставить его работать. Другая интересная вещь заключается в том, что я на самом деле использую Mac, поэтому совместимость набора инструментов, похоже, также неверна.
Я использую этот набор инструментов в репо, поэтому пути могут быть разными, но вот репо, содержащее только материал fn для удобства чтения.
1 ответ
Две вещи:
Во-первых, я подозреваю, что это ваша настоящая проблема: https://github.com/bazelbuild/bazel/issues/6828 Суть проблемы заключается в том, что цель toolchain_type находится во внешнем репозитории, к ней всегда нужно обращаться по полному имени, а не по локальному имени.
Второе немного более фундаментально: у вас есть много макросов Starlark, которые генерируют другие цели, и их очень трудно прочитать. На самом деле было бы намного проще удалить много макросов, таких как _fn_binary, fn_binaries и _add_toolchains. Просто установите setup_toolchains напрямую, чтобы создать native.toolchain
цели, и есть макрос репозитория, который вызывает http_archive
трижды объявить три разных набора двоичных файлов. Это сделает код намного легче для чтения и, следовательно, легче для отладки.
Для отладки цепочек инструментов я выполняю два шага: во-первых, я проверяю, что репозитории инструментов существуют и могут быть доступны напрямую, а затем я проверяю регистрацию и разрешение цепочки инструментов.
Пройдя несколько уровней глубиной, похоже, что вы звоните http_archive
, назвав новый репозиторий @linux
и загрузка определенного двоичного файла. Это не то, как работает http_archive: он ожидает получить zip-файл (или файл tar.gz), распаковать его и найти рабочее пространство и хотя бы один файл BUILD внутри.
Мои предложения: упростите ваши макросы, четко определите внешние репозитории, а затем изучите с помощью разрешения цепочки инструментов, чтобы выбрать правильный.
Я рад помочь ответить на дополнительные вопросы по мере необходимости.