如何在Bazel中集成C/C++分析工具? [英] How to integrate C/C++ analysis tooling in Bazel?

查看:0
本文介绍了如何在Bazel中集成C/C++分析工具?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代码分析工具,我想为每个cc_库(和cc_二进制,在问题的其余部分默默暗示)运行。该工具具有CLI接口:

  • 工具项目文件
    • 编译器细节,如字体大小、内置、宏等。
    • 要分析的文件
      • 文件路径、包含、定义
    • 要(不)应用的规则
  • 要添加到项目的文件
  • 用于将文件与生成数据同步的选项
    • JSON编译数据库
    • 分析生成日志
  • 分析生成分析报告

我一直在研究如何将其集成到Bazel中,以便自动更新要分析的文件以及相关的包含和定义,并正确缓存所有分析结果。生成JSON编译数据库(使用第三方lib)或解析构建日志都需要单独运行和更新源代码树。对于此问题,我认为这是我试图删除的解决方法。

到目前为止,我尝试的是使用aspects,向任何库添加分析方面。其总体思想是有一个包含库不变配置的基本项目文件,附加cc_库文件进行分析,最后触发分析生成报告。但我在执行上遇到了麻烦,我甚至不确定这是否可能。

到目前为止,这是我的方面实现,尝试迭代cc_Library属性和目标编译上下文:

def _print_aspect_impl(target, ctx):
    # Make sure the rule has a srcs attribute
    if hasattr(ctx.rule.attr, 'srcs'):
        # Iterate through the files
        for src in ctx.rule.attr.srcs:
            for f in src.files.to_list():
                if f.path.endswith(".c"):
                    print("file: ")
                    print(f.path)
                    print("includes: ")
                    print(target[CcInfo].compilation_context.includes)
                    print("quote_includes: ")
                    print(target[CcInfo].compilation_context.quote_includes)
                    print("system_includes: ")
                    print(target[CcInfo].compilation_context.system_includes)
                    print("define: " + define)
                    print(ctx.rule.attr.defines)
                    print("local_defines: ")
                    print(ctx.rule.attr.local_defines)
                    print("") # empty line to separate file prints
    return []

我搞不懂的是如何在编译库时使用所有的包含和定义:

  • 来自依赖的库,递归
    • 复制、定义、包含
  • 从工具链
    • 功能,CXX_BUILTIN_INCLUDE_DIRECTORIES

问题:

  • 如何获取丢失的标志,继续演示技术?
  • 我可以以某种方式检索编译操作命令字符串吗?
    • 使用构建日志API追加到分析项目
  • 完全有其他解决方案吗?
    • 也许可以用cc_toolchain代替aspects...

推荐答案

方面是实现这一点的正确工具。您要查找的信息包含在方面可以访问的cc_*规则的providersfragmentstoolchains中。具体地说,CcInfo具有特定于目标的片段,cpp片段具有从命令行标志配置的片段,而CcToolchainInfo具有来自工具链的部分。

CcInfo in target告诉您当前目标是否具有该提供程序,target[CcInfo]访问该提供程序。

Rules_ccmy_c_compile example通常是我根据CcInfo提取完整的编译器命令的地方。类似这样的操作应该从以下方面起作用:

load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME")
load("@rules_cc//cc:toolchain_utils.bzl", "find_cpp_toolchain")

[in the impl]:
    cc_toolchain = find_cpp_toolchain(ctx)
    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = ctx.disabled_features,
    )
    c_compiler_path = cc_common.get_tool_for_action(
        feature_configuration = feature_configuration,
        action_name = C_COMPILE_ACTION_NAME,
    )

[in the loop]
    c_compile_variables = cc_common.create_compile_variables(
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts,
        source_file = src.path,
    )
    command_line = cc_common.get_memory_inefficient_command_line(
        feature_configuration = feature_configuration,
        action_name = C_COMPILE_ACTION_NAME,
        variables = c_compile_variables,
    )
    env = cc_common.get_environment_variables(
        feature_configuration = feature_configuration,
        action_name = C_COMPILE_ACTION_NAME,
        variables = c_compile_variables,
    )

该示例仅处理C文件(不处理C++),您必须更改操作名称以及它适当地使用片段的哪些部分。

您必须将toolchains = ["@bazel_tools//tools/cpp:toolchain_type"]fragments = ["cpp"]添加到aspect调用中才能使用它们。另请参阅find_cc_toolchain.bzl中关于_cc_toolchain属性的注释(如果您使用的是旧工具链解析)。

来自规则和工具链的信息已经结构化。根据您的分析工具的需要,直接提取它可能比生成完整的命令行更有意义。如果您想要直接查看,大多数提供程序、片段和工具链都有很好的文档记录。

您可以将required_providers = [CcInfo]传递给aspect,以将传播限制到包含它的规则,具体取决于您希望如何管理方面的传播。

Integrating with C++ Rules文档页面还包含一些详细信息。

这篇关于如何在Bazel中集成C/C++分析工具?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆