嗨,我正在为Fn项目建立一个工具链。这种方法是在GitHub中为每个二进制文件设置一个工具链,然后理论上在规则中使用它。在
我有一个包含可用二进制文件的通用包:
default_version = "0.5.44"
os_list = [
"linux",
"mac",
"windows"
]
def get_bin_name(os):
return "fn_cli_%s_bin" % os
下载部分如下所示:
^{pr2}$然后我将工具链设置为:
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)
在我的构建文件中,我将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]
)
工作空间:
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,所以工具链的兼容性似乎也是错误的。在
我在一个repo中使用了这个工具链,所以路径是不同的,但是为了便于阅读,here's一个只包含fn内容的repo。在
两件事:
第一,我怀疑这是你真正的问题:https://github.com/bazelbuild/bazel/issues/6828 问题的核心是,如果工具链类型目标位于外部存储库中,则它始终需要通过完全限定名引用,而不是使用本地限定名。在
第二个是更基本的:这里有很多Starlark宏在生成其他目标,而且很难读懂。实际上,删除许多宏会简单得多,例如_fn_binary、fn_binary和_add_toolchains。只需让setup\u工具链直接创建所需的
native.toolchain
目标,并有一个repository宏,它调用http_archive
三次来声明三组不同的二进制文件。这将使代码更易于阅读,从而更易于调试。在对于调试工具链,我遵循两个步骤:首先,我验证工具存储库是否存在并且可以直接访问,然后检查工具链注册和解析。在
在深入几个层次之后,看起来您在调用
http_archive
,命名新的存储库@linux
,并下载一个特定的二进制文件。这不是http_archive的工作方式:它期望获取一个zip文件(或者焦油gz文件),提取该文件,并在其中找到一个工作区和至少一个构建文件。在我的建议是:简化宏,明确定义外部存储库,然后探索使用工具链解析来选择正确的存储库。在
我很乐意根据需要回答更多问题。在
相关问题 更多 >
编程相关推荐