如何在Starlark规则中添加并访问自定义工具链的tool_path
解决自定义CC工具链中添加并访问自定义tool_path的问题
核心思路
CcToolchainInfo是Bazel内置的工具链信息结构体,仅包含预设的编译工具相关属性,无法直接扩展自定义字段。要添加并访问自定义的tclsh.exe路径,需通过自定义Provider承载额外信息,再结合工具链规则暴露该Provider供下游规则调用。
具体实现步骤
1. 定义自定义Provider
在你的toolchain_config.bzl中,先定义一个自定义Provider,用来存放需要的工具路径:
# 自定义Provider,承载额外工具路径信息 CustomToolPathsInfo = provider( fields = { "tclsh_path": "Path to tclsh.exe", }, )
2. 在工具链配置中生成自定义Provider实例
在生成CcToolchainConfigInfo的同时,创建自定义Provider实例并传入tclsh.exe的路径:
def _my_cc_toolchain_config_impl(ctx): # 原有生成CcToolchainConfigInfo的逻辑 toolchain_config = cc_common.create_cc_toolchain_config_info( ctx = ctx, # 其他配置项... tool_paths = { # 保留原有tool_path配置,这里的tool_paths仅用于CcToolchainConfigInfo预设工具 "tclsh": ctx.attr.tclsh_path, }, ) # 创建自定义Provider实例 custom_tool_paths_info = CustomToolPathsInfo( tclsh_path = ctx.attr.tclsh_path, ) return [toolchain_config, custom_tool_paths_info] my_cc_toolchain_config = rule( implementation = _my_cc_toolchain_config_impl, attrs = { # 新增属性接收tclsh.exe路径 "tclsh_path": attr.string(mandatory = True), # 其他属性... }, provides = [CcToolchainConfigInfo, CustomToolPathsInfo], )
3. 在工具链规则中关联自定义Provider
工具链规则(如my_cc_toolchain)需依赖上述配置规则,并确保返回的工具链包含自定义Provider:
def _my_cc_toolchain_impl(ctx): toolchain_info = cc_common.create_cc_toolchain( ctx = ctx, toolchain_config = ctx.attr.toolchain_config, # 其他工具链配置... ) # 传递自定义Provider return [ toolchain_info, ctx.attr.toolchain_config[CustomToolPathsInfo], ] my_cc_toolchain = rule( implementation = _my_cc_toolchain_impl, attrs = { "toolchain_config": attr.label(providers = [CcToolchainConfigInfo, CustomToolPathsInfo]), # 其他属性... }, provides = [CcToolchainInfo, CustomToolPathsInfo], toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", )
4. 在自定义Starlark规则中访问自定义tool_path
在规则实现里,除了用find_cc_toolchain()获取内置工具链信息,还可通过ctx.toolchains获取自定义Provider:
def _my_custom_rule_impl(ctx): # 获取内置CC工具链信息 cc_toolchain = find_cc_toolchain(ctx) # 获取自定义工具路径 custom_tool_paths = ctx.toolchains["@bazel_tools//tools/cpp:toolchain_type"][CustomToolPathsInfo] tclsh_exe = custom_tool_paths.tclsh_path # 使用tclsh.exe执行操作示例 ctx.actions.run( executable = tclsh_exe, arguments = ["your_script.tcl"], # 其他配置... ) my_custom_rule = rule( implementation = _my_custom_rule_impl, attrs = { # 规则属性... }, toolchains = [ "@bazel_tools//tools/cpp:toolchain_type", ], fragments = ["cpp"], )
关键注意点
- 自定义Provider需在工具链传递链中正确暴露:从配置规则到工具链规则,再到下游规则的
toolchains声明。 - 若工具链类型与Bazel默认CC工具链类型一致,可直接通过该类型获取自定义Provider,无需额外定义新类型。
内容的提问来源于stack exchange,提问作者Eric Stoces
相关产品推荐
相关产品推荐

