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

如何在自定义Bazel规则中正确引入编译依赖的头文件?

问题

我想要创建一个Bazel规则,该规则接收.yaml文件,利用其中信息生成源码,将其编译并归档为类似cc_library的静态库,且可被cc_rules依赖。我可以创建生成源码的规则并将其封装在cc_library宏中,但希望避免生成源码的目标与宏创建的目标使用不同名称。参考官方示例编写规则时,在引入依赖时遇到问题。假设我的规则中有deps属性,如何在编译命令中正确引入这些依赖?以下代码片段中的include_directories参数不正确,请问如何引入构建文件中deps属性指定的目标相关的所有头文件?

cpp_compile_variables = cc_common.create_compile_variables(
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        user_compile_flags = ctx.fragments.cpp.copts,
        source_file = type_publisher.path,
        output_file = type_publisher_object_file.path,
        include_directories = [dep.attrs.hdrs for dep in ctx.files.deps]
    )   
解决方案

直接从ctx.files.deps提取头文件路径的方式是错误的,因为它无法收集deps目标的头文件目录、传递依赖的头文件等信息。正确做法是通过Bazel的编译上下文(compile context)统一处理依赖的头文件与编译参数:

  • 聚合依赖的编译上下文
    使用cc_common.merge_compile_contexts合并所有deps目标的编译上下文,自动处理传递依赖的头文件、宏定义、包含目录等内容:

    compile_contexts = [dep[CcInfo].compile_context for dep in ctx.attr.deps]
    merged_compile_context = cc_common.merge_compile_contexts(
        compile_contexts = compile_contexts,
    )
    
  • 提取正确的包含目录
    从合并后的编译上下文中获取所有需要的包含目录,包括用户头目录和系统头目录:

    include_dirs = merged_compile_context.includes + merged_compile_context.system_includes
    
  • 修正编译变量初始化
    将include_directories参数替换为上述正确的目录列表,同时可以把依赖的宏定义合并到编译参数中:

    # 合并依赖的宏定义到编译参数
    compile_defines = merged_compile_context.defines
    user_compile_flags = ctx.fragments.cpp.copts + ["-D{}".format(def) for def in compile_defines]
    
    cpp_compile_variables = cc_common.create_compile_variables(
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        user_compile_flags = user_compile_flags,
        source_file = type_publisher.path,
        output_file = type_publisher_object_file.path,
        include_directories = include_dirs
    )
    
  • 生成完整编译命令
    后续使用cc_common.get_memory_inefficient_command_line生成编译命令时,这些包含目录会自动被转换为-I或-isystem参数,无需手动拼接。

另外要确保规则的deps属性类型设置为attr.label_list(providers=[CcInfo]),这样才能正确获取每个依赖的CcInfo提供者。

内容的提问来源于stack exchange,提问作者Emile Papillon-Corbeil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:49:53