首页 > 解决方案 > 修改自定义 C++ Bazel 规则中的包含路径

问题描述

我正在构建一些自定义 C++ Bazel 规则,并且我需要添加对修改 C++ 标头的包含路径的支持,就像cc_library可以使用strip_include_prefix.

我的自定义规则是ctx.actions.run这样实现的:

custom_cc_library = rule(
  _impl,
  attrs = {
    ...
    "hdrs": attr.label_list(allow_files = [".h"]),
    "strip_include_prefix": attr.string(),
    ...
  },
)

然后在_impl我调用以下函数重写hdrs

def _strip_prefix(ctx, hdrs, prefix):
    stripped = []
    for hdr in hdrs:
        stripped = hdr
        if file.path.startswith(strip_prefix):
            stripped_file = ctx.actions.declare_file(file.path[len(strip_prefix):])
            ctx.actions.run_shell(
                command = "mkdir -p {dest} && cp {src} {dest};".format(src=hdr.path, dest=stripped.path),
                inputs = [hdr],
                outputs = [stripped],
            )
        stripped.append(stripped_file)
    return stripped

这是行不通的,因为 Bazel 不会将文件复制到其包目录之外,而且感觉实现这一点的方法完全错误。

修改依赖项的 C++ 头目录以实现与cc_library参数相同的功能的最佳方法是什么strip_include_prefix

标签: c++includebazelbazel-rules

解决方案


您可以在包中的目录中创建所需的标题布局,然后通过create_compilation_outputs.includes. 这基本上就是 cc_library 实现归结为的内容。

cc_library 实现命名它_virtual_includes,并使用getUniqueDirectoryArtifact它创建它,它是 Java 代码中的帮助器,以“在规则唯一的目录中”创建它。我使用"_%s_virtual_includes" % ctx.label.name类似从 Starlark 获得类似功能的东西,并暗示它是其他规则应避免依赖的私有实现细节。


推荐阅读