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

Bazel中如何获取跨包生成文件thing.h的所在目录?

解决方法

方法一:用cc_library封装生成的头文件(推荐)

这是Bazel官方推荐的方式,通过cc_library统一管理头文件的依赖关系与include路径,无需手动调整编译选项。

  1. 修改//foo/bar/baz/BUILD,将genrule生成的头文件封装进cc_library,并通过strip_include_prefix调整引用路径:
genrule(
    name = "thing_gen",
    outs = ["thing.h"],
    # 替换为你的实际头文件生成命令
    cmd = "your_generation_command > $@",
)

cc_library(
    name = "thing",
    hdrs = [":thing_gen"],
    # 去掉当前包路径前缀,让代码可直接用"thing.h"引用
    strip_include_prefix = ".",
    # 根据需要设置可见性,允许consumer包访问
    visibility = ["//path/to/consumer/package:__pkg__"],
)
  1. 在consumer包的BUILD文件中,直接依赖上述cc_library即可,无需手动添加头文件到srcs或修改copts:
cc_binary(
    name = "consumer",
    srcs = ["consumer.cc"],
    deps = ["//foo/bar/baz:thing"],
)

Bazel会自动将包含thing.h的目录加入编译include路径,代码里的#include "thing.h"就能正常解析。

方法二:生成到子目录配合cc_library

如果需要归类多个生成的头文件,可以让genrule输出到子目录,再通过cc_library暴露:

  1. 修改//foo/bar/baz/BUILD:
genrule(
    name = "thing_gen",
    # 将头文件生成到include子目录下
    outs = ["include/thing.h"],
    cmd = "your_generation_command > $@",
)

cc_library(
    name = "thing",
    hdrs = [":thing_gen"],
    # 去掉include前缀,实现直接引用"thing.h"
    strip_include_prefix = "include",
    visibility = ["//path/to/consumer/package:__pkg__"],
)
  1. consumer包的配置与方法一一致,直接依赖//foo/bar/baz:thing即可。

方法三:手动传递头文件目录(不推荐)

若不想用cc_library封装,可通过辅助genrule获取头文件目录后传递给copts:

  1. 在consumer包的BUILD文件中添加辅助genrule:
genrule(
    name = "get_thing_h_dir",
    outs = ["thing_h_dir.txt"],
    srcs = ["//foo/bar/baz:thing.h"],
    cmd = "dirname $(rootpath //foo/bar/baz:thing.h) > $@",
)

cc_binary(
    name = "consumer",
    srcs = ["consumer.cc"],
    deps = ["//foo/bar/baz:thing"],
    # 读取辅助规则生成的目录路径,加入include路径
    copts = ["-I@$(location :get_thing_h_dir)"],
)

该方法需额外维护辅助规则,仅作为临时替代方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:37:28