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

Bazel中SWIG规则的可选输出文件处理方案咨询

解决Bazel规则中SWIG条件生成.h文件的问题

问题核心

  • SWIG是否生成.h头文件,完全取决于.i接口文件是否启用了directors特性
  • 固定声明输出.h会导致未生成时报错;移除h_out配置后,生成的.h又无法被native.cc_binary的依赖系统识别,编译时找不到文件
  • 尝试生成虚拟.h会触发动作冲突,不可行

单规则下的最优解决思路

1. 动态检测directors特性,按需声明输出文件

在规则实现里读取.i文件内容,判断是否包含directors相关指令,动态决定是否将.h加入输出列表:

def _has_directors(ctx):
    content = ctx.file.source.read()
    # 检查SWIG directors相关的指令格式
    return "%feature(directors)" in content or "%director" in content

def _py_swig_gen_impl(ctx):
    # 声明固定输出的.cc文件
    swig_cc_out = ctx.actions.declare_file(f"{ctx.label.name}_wrap.cc")
    outputs = [swig_cc_out]
    swig_h_out = None

    if _has_directors(ctx):
        # 按需声明.h输出文件
        swig_h_out = ctx.actions.declare_file(f"{ctx.label.name}_wrap.h")
        outputs.append(swig_h_out)

    # 构建SWIG命令参数
    args = ctx.actions.args()
    args.add("-python", "-c++")
    args.add("-o", swig_cc_out.path)
    if swig_h_out:
        args.add("-oh", swig_h_out.path)
        # 显式开启directors特性(如果.i里没写全局feature)
        args.add("-features", "directors")
    # 添加必要的头文件包含路径
    for inc in ctx.attr.hdrs:
        args.add("-I", inc.dirname)

    ctx.actions.run(
        inputs = [ctx.file.source] + ctx.files.hdrs,
        outputs = outputs,
        executable = ctx.executable.swig,
        arguments = [args, ctx.file.source.path],
    )

    # 生成CcInfo,把.h文件传递给下游C++目标
    compilation_context = cc_common.create_compilation_context(
        headers = depset([swig_h_out]) if swig_h_out else depset()
    )

    return [
        DefaultInfo(files = depset(outputs)),
        CcInfo(compilation_context = compilation_context),
    ]

2. 用CcInfo传递头文件依赖

通过CcInfo将生成的.h文件注入到Bazel的依赖系统中,下游的cc_binary或cc_library依赖该规则时,会自动获取头文件路径,无需手动用glob捕获。

3. 规则定义调整

去掉固定的h_out输出声明,改为动态生成:

py_swig_gen = rule(
    implementation = _py_swig_gen_impl,
    attrs = {
        "source": attr.label(allow_single_file = [".i"]),
        "hdrs": attr.label_list(allow_files = [".h"], mandatory = False),
        "swig": attr.label(
            executable = True,
            cfg = "exec",
            default = Label("@swig//:swig"),
        ),
    },
    # 只声明固定的.cc输出,.h按需生成
    outputs = {
        "swig_cc_out": "%{name}_wrap.cc",
    },
)

效果验证

  • 当.i文件启用directors时,规则会生成.cc和.h,下游C++目标能正常找到头文件
  • 未启用directors时,仅生成.cc,不会出现输出文件缺失的报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:09:21