You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Bazel aspect中获取cc_*规则的所有头文件依赖(含工具链头文件)

Bazel Aspect获取C/C++完整头文件及工具链头文件的实现方案

你可以通过两种稳定途径获取编译阶段一致的所有头文件,无需手动解析bazel-bin下的.d文件:

方案1:直接提取工具链内置头文件

C++工具链的内置头文件可以通过CcToolchainInfo直接获取:

  1. 首先在aspect定义中声明工具链依赖:
your_analysis_aspect = aspect(
    attrs = {
        "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
    },
    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
    # 其余aspect配置保持不变
)
  1. 在aspect实现函数中读取工具链头文件:
def _aspect_impl(target, ctx):
    cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]
    # 获取工具链所有关联文件,筛选出头文件即可
    toolchain_headers = [
        f for f in cc_toolchain.all_files.to_list()
        if f.extension in ["h", "hh", "hpp", "hxx", "inc"]
    ]

方案2:从编译动作获取完整依赖集合(推荐)

如果需要和编译阶段完全一致的全量头文件(包含srcs、hdrs、所有依赖头文件、工具链头文件),直接读取C++编译动作的输入列表即可,Bazel已经提前解析好所有依赖:

  1. 遍历目标的动作,找到CppCompile类型的编译动作:
def _aspect_impl(target, ctx):
    cpp_compile_actions = [
        action for action in target.actions
        if action.mnemonic == "CppCompile"
    ]
    all_headers = []
    for action in cpp_compile_actions:
        # 该属性包含编译动作依赖的所有输入文件,和.d文件列出的依赖完全一致
        all_headers += action.inputs.to_list()

    # 去重处理(可选)
    all_headers = list(dict.fromkeys(all_headers))
  1. 让所有头文件进入aspect运行沙箱:
    你只需要在创建自定义分析动作时,将上述获取的头文件列表传入inputs参数,Bazel就会自动把这些文件放到沙箱中供分析工具使用:
ctx.actions.run(
    outputs = [your_analysis_output],
    # 传入所有头文件依赖 + 你的分析工具本身
    inputs = all_headers + [ctx.executable._your_analysis_tool],
    executable = ctx.executable._your_analysis_tool,
    arguments = [
        # 传入你需要的分析参数
    ],
    # 其余动作配置保持不变
)

如果你确实需要获取.d文件本身做自定义解析,可以从CppCompile动作的输出列表中筛选后缀为.d的文件即可,无需到bazel-bin目录手动查找。


内容的提问来源于stack exchange,提问作者Andreas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 15:45:05