如何让bazel遍历目标的依赖图?

问题描述 投票:0回答:1

我一直在使用 BCR 中的 https://github.com/TendTo/rules_doxygen/tree/main 来生成文档。我正在尝试弄清楚如何让 bazel 遍历目标的依赖关系图,以便我可以提取所有标头的列表以提供给 doxygen 作为文档。 到目前为止,只有当我在一个 glob 中指定所有内容时,我才能让 doxygen 工作 - 但这种情况假设所有内容都位于一个地方。 我想要这样的东西:

cc_binary MAIN - main.cpp
    |
cc_library  A  - A.cpp, A.hpp
    |
cc_library  B  - B.cpp, B.hpp
    |
cc_library  C  - C.cpp, C.hpp

现在 - 像这样的东西有效:

doxygen(
    name = "doxygen",   # Name of the rule, can be anything
    srcs = glob(["A/*.hpp", "B/*.hpp", "C/*.hpp"]),
    project_brief = "Example project for doxygen",  # Brief description of the project
    project_name = "base",                          # Name of the project
    configurations = [                              # Additional configurations to add to the Doxyfile
        "GENERATE_HTML = YES",                      # They are the same as the Doxyfile options,
        "GENERATE_LATEX = NO",                      # and will override the default values
        "EXTRACT_ALL = YES",
    ],
    tags = ["manual"]  # Tags to add to the target. This way the target won't run unless explicitly called
)

但是我应该能够将其包装起来,这样我就可以做类似的事情:

my_doxygen(
    name = "my_cool_docs",
    deps = [":main"]   ( or maybe in a docs folder "//:main" )
)

bazel build //:my_cool_docs or bazel build //docs:my_cool_docs

让它遍历 main 的 deps,保留文件列表,然后在后台提供给 doxygen。

到目前为止,我已经弄清楚如何使用方面在 BUILD 文件内的所有 cc_library 和 cc_binary 文件上进行此操作:

load("//:cc_srcs.bzl", "CcSrcs", "cc_srcs_aspect")

def _gather_src_files_impl(ctx):
    srcs = []
    hdrs = []

    for dep in ctx.attr.deps:
        srcs.extend(dep[CcSrcs].srcs.to_list())
        hdrs.extend(dep[CcInfo].compilation_context.direct_headers)

    hdrs = [h for h in hdrs if h.is_source]

    src_list = srcs + hdrs
    info = [DefaultInfo(files=depset(src_list))]
    return info

_gather_src_files = rule(
    implementation = _gather_src_files_impl,
    fragments = ["cpp"],
    attrs = {
        "deps": attr.label_list(providers = [CcInfo], aspects = [cc_srcs_aspect]),

    },
    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
)

def gather_src_files(name = "gather_src_files"):
    rule_types = [rule["kind"] for rule in native.existing_rules().values()]
    if "_gather_src_files" in rule_types:
        fail("rule already defined")

    deps = []
    for rule_name, rule in native.existing_rules().items():
        print(rule_name + ":" + rule["kind"])
        if rule["kind"] in ["cc_binary", "cc_library"]:
            deps.append(rule_name)

    _gather_src_files(
        name = name,
        deps = deps
    )

cc_srcs.bazel

CcSrcs = provider(
    fields = {
        "srcs": "depset of top-level cpp sources",
        "package": "the package root",
    },
)

def extract_cc_files(target, ctx):
    srcs_target_list = getattr(ctx.rule.attr, "srcs", [])
    srcs_file_list = [f for t in srcs_target_list for f in t.files.to_list()]
    return srcs_file_list

def extract_cc_srcs(target, ctx):
    return [s for s in extract_cc_files(target, ctx) if s.extension in ["c", "cc", "cpp", "cxx", "c++", "C"]]

def _cc_srcs_aspect_impl(target, ctx):
    srcs = []
    if CcInfo in target: srcs = extract_cc_srcs(target, ctx)

    # Get the root name: either ws root for external repos, or package for internal repos
    root_name = ctx.label.workspace_root
    if not root_name: root_name = ctx.label.package

    return [CcSrcs(
        srcs = depset(srcs, order = "topological"),
        package = depset([root_name]),
    )]

cc_srcs_aspect = aspect(
    implementation = _cc_srcs_aspect_impl,
)

但是我无法弄清楚如何访问/遍历给定目标的依赖关系图 - 而且我什至不确定此时要在 Bazel 文档中查找哪些术语。

有什么想法吗? 谢谢!

c++ bazel doxygen
1个回答
0
投票

仔细查看示例后 - 我发现我需要做的就是添加:

FileCountInfo = provider(
    fields = {
        'count' : 'number of files',
        'srcs'  : 'depset of files' <-----
    }
)

def _file_count_aspect_impl(target, ctx):
    count = 0
    srcs = []
    # Make sure the rule has a srcs attribute.
    print("Fudge")
    if hasattr(ctx.rule.attr, 'srcs'):
        # Iterate through the sources counting files
        for src in ctx.rule.attr.srcs:
            for f in src.files.to_list():
                if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
                    count = count + 1
                    srcs.append(f)  <-----------
    # Get the counts from our dependencies.
    for dep in ctx.rule.attr.deps:
        count = count + dep[FileCountInfo].count
        a = dep[FileCountInfo].srcs
        srcs.extend(dep[FileCountInfo].srcs.to_list()) <----------
    return [FileCountInfo(count = count, srcs=depset(srcs))] <--------
    enter code here

在这和我已经拥有的之间 - 我认为我有一个稍微更坚实的基础。

这是一个过程,我认为 Bazel 还没有遇到尚未通过另一层间接解决的问题。

© www.soinside.com 2019 - 2024. All rights reserved.