File
Blob: build/cc_ast_dump.bzl
| 1 | """ |
| 2 | Dump the AST of a given C++ source file |
| 3 | |
| 4 | Based loosely on https://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_compile/my_c_compile.bzl |
| 5 | """ |
| 6 | |
| 7 | load("@rules_cc//cc:action_names.bzl", "CPP_COMPILE_ACTION_NAME") |
| 8 | load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cpp_toolchain", "use_cc_toolchain") |
| 9 | load("@rules_cc//cc/common:cc_common.bzl", "cc_common") |
| 10 | load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") |
| 11 | |
| 12 | def _cc_ast_dump_impl(ctx): |
| 13 | cc_toolchain = find_cpp_toolchain(ctx) |
| 14 | |
| 15 | feature_configuration = cc_common.configure_features( |
| 16 | ctx = ctx, |
| 17 | cc_toolchain = cc_toolchain, |
| 18 | requested_features = ctx.features, |
| 19 | unsupported_features = ctx.disabled_features, |
| 20 | ) |
| 21 | |
| 22 | cc_info = cc_common.merge_cc_infos(direct_cc_infos = [dep[CcInfo] for dep in ctx.attr.deps]) |
| 23 | |
| 24 | variables = cc_common.create_compile_variables( |
| 25 | cc_toolchain = cc_toolchain, |
| 26 | feature_configuration = feature_configuration, |
| 27 | source_file = ctx.file.src.path, |
| 28 | output_file = None, |
| 29 | # clang 19 complains about '-c' being unused |
| 30 | user_compile_flags = ["-Wno-unused-command-line-argument", "-Xclang", "-ast-dump=json", "-fsyntax-only"] + ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts, |
| 31 | include_directories = cc_info.compilation_context.includes, |
| 32 | quote_include_directories = cc_info.compilation_context.quote_includes, |
| 33 | # we need to pass external_includes, but there is no equivalent parameter in |
| 34 | # create_compile_variables – pass alongside system_includes. |
| 35 | system_include_directories = depset(transitive = [cc_info.compilation_context.system_includes, cc_info.compilation_context.external_includes]), |
| 36 | framework_include_directories = cc_info.compilation_context.framework_includes, |
| 37 | preprocessor_defines = cc_info.compilation_context.defines, |
| 38 | ) |
| 39 | |
| 40 | arguments = cc_common.get_memory_inefficient_command_line(feature_configuration = feature_configuration, action_name = CPP_COMPILE_ACTION_NAME, variables = variables) |
| 41 | executable = cc_common.get_tool_for_action(feature_configuration = feature_configuration, action_name = CPP_COMPILE_ACTION_NAME) |
| 42 | inputs = depset(direct = [ctx.file.src], transitive = [cc_toolchain.all_files] + [cc_info.compilation_context.headers]) |
| 43 | env = cc_common.get_environment_variables(feature_configuration = feature_configuration, action_name = CPP_COMPILE_ACTION_NAME, variables = variables) |
| 44 | |
| 45 | # Enable pipefail so that the action fails when there are e.g. missing include errors, otherwise |
| 46 | # we'd just continue despite the error and end up with an incomplete AST. |
| 47 | command = " ".join(["set -euo pipefail;"] + [executable] + arguments + ["|", "gzip", "-3", "-", ">", ctx.outputs.out.path]) |
| 48 | |
| 49 | # run_shell until https://github.com/bazelbuild/bazel/issues/5511 is fixed |
| 50 | ctx.actions.run_shell( |
| 51 | outputs = [ctx.outputs.out], |
| 52 | inputs = inputs, |
| 53 | command = command, |
| 54 | env = env, |
| 55 | ) |
| 56 | |
| 57 | cc_ast_dump = rule( |
| 58 | implementation = _cc_ast_dump_impl, |
| 59 | attrs = { |
| 60 | "src": attr.label(mandatory = True, allow_single_file = True), |
| 61 | "out": attr.output(mandatory = True), |
| 62 | "deps": attr.label_list(providers = [CcInfo]), |
| 63 | }, |
| 64 | toolchains = use_cc_toolchain(), # copybara-use-repo-external-label |
| 65 | fragments = ["cpp"], |
| 66 | ) |