From 7b0ff1385242c77542a3027831bd268fb0ac3659 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Wed, 30 Apr 2025 22:34:53 +0000 Subject: [PATCH] Add resource_dir override If you vendor clang-tidy in a hermetic toolchain, it likely cannot find the builtin headers path. To solve this you have to pass `-resource-dir` to the correct path. This is similar to the new gcc option but with a different flag. --- BUILD | 11 +++++++++++ README.md | 22 ++++++++++++++++++++++ clang_tidy/clang_tidy.bzl | 11 ++++++++++- clang_tidy/clang_tidy_test.bzl | 13 ++++++++++++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index fa7ebc8..5933602 100644 --- a/BUILD +++ b/BUILD @@ -44,3 +44,14 @@ label_flag( build_setting_default = ":clang_tidy_gcc_install_dir_default", visibility = ["//visibility:public"], ) + +filegroup( + name = "clang_tidy_resource_dir_default", + srcs = [], +) + +label_flag( + name = "clang_tidy_resource_dir", + build_setting_default = ":clang_tidy_resource_dir_default", + visibility = ["//visibility:public"], +) diff --git a/README.md b/README.md index 0203d31..548efaf 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,28 @@ build:clang-tidy --@bazel_clang_tidy//:clang_tidy_gcc_install_dir=@gcc-linux-x86 build:clang-tidy --@bazel_clang_tidy//:clang_tidy_additional_deps=@gcc-linux-x86_64//:toolchain_root ``` +### use with a vendored clang-tidy + +In the case you vendor clang-tidy, potentially alongside clang itself, +it's possible clang-tidy cannot automatically find the `-resource-dir` +path to the builtin headers. In this case, you can use skylib's +`directory` rule to create a target to the clang resource directory. + +```bzl +load("@bazel_skylib//rules/directory:directory.bzl", "directory") + +directory( + name = "resource_dir", + srcs = glob(["lib/clang/*/include/**"]), + visibility = ["//visibility:public"], +) +``` + +Then pass the `resource_dir` with a flag in your `.bazelrc`: + +``` +build:clang-tidy --@bazel_clang_tidy//:clang_tidy_resource_dir=//path/to:resource_dir +``` ## Features diff --git a/clang_tidy/clang_tidy.bzl b/clang_tidy/clang_tidy.bzl index cd1b461..87035fb 100644 --- a/clang_tidy/clang_tidy.bzl +++ b/clang_tidy/clang_tidy.bzl @@ -6,6 +6,7 @@ def _run_tidy( wrapper, exe, gcc_install_dir, + resource_dir, additional_deps, config, flags, @@ -24,7 +25,7 @@ def _run_tidy( inputs = depset( direct = direct_inputs, - transitive = [additional_files, cc_toolchain.all_files], + transitive = [additional_files, cc_toolchain.all_files, resource_dir.files], ) args = ctx.actions.args() @@ -58,6 +59,11 @@ def _run_tidy( for dir in gcc_install_dir.files.to_list(): args.add("--gcc-install-dir=%s" % dir.path) + resource_dir_files = resource_dir.files.to_list() + if resource_dir_files: + directory = resource_dir_files[0].path.split("/include/")[0] + args.add("-resource-dir", directory) + ctx.actions.run( inputs = inputs, outputs = [outfile], @@ -214,6 +220,7 @@ def _clang_tidy_aspect_impl(target, ctx): wrapper = ctx.attr._clang_tidy_wrapper.files_to_run exe = ctx.attr._clang_tidy_executable gcc_install_dir = ctx.attr._clang_tidy_gcc_install_dir + resource_dir = ctx.attr._clang_tidy_resource_dir additional_deps = ctx.attr._clang_tidy_additional_deps config = ctx.attr._clang_tidy_config.files.to_list()[0] @@ -239,6 +246,7 @@ def _clang_tidy_aspect_impl(target, ctx): wrapper, exe, gcc_install_dir, + resource_dir, additional_deps, config, c_flags if is_c_translation_unit(src, ctx.rule.attr.tags) else cxx_flags, @@ -263,6 +271,7 @@ clang_tidy_aspect = aspect( "_clang_tidy_wrapper": attr.label(default = Label("//clang_tidy:clang_tidy")), "_clang_tidy_executable": attr.label(default = Label("//:clang_tidy_executable")), "_clang_tidy_gcc_install_dir": attr.label(default = Label("//:clang_tidy_gcc_install_dir")), + "_clang_tidy_resource_dir": attr.label(default = Label("//:clang_tidy_resource_dir")), "_clang_tidy_additional_deps": attr.label(default = Label("//:clang_tidy_additional_deps")), "_clang_tidy_config": attr.label(default = Label("//:clang_tidy_config")), }, diff --git a/clang_tidy/clang_tidy_test.bzl b/clang_tidy/clang_tidy_test.bzl index 6d1d438..439e80a 100644 --- a/clang_tidy/clang_tidy_test.bzl +++ b/clang_tidy/clang_tidy_test.bzl @@ -40,6 +40,11 @@ def _clang_tidy_rule_impl(ctx): rule_conlyopts = _get_copts_attr(ctx, "conlyopts") rule_cxxopts = _get_copts_attr(ctx, "cxxopts") + files = ctx.attr.clang_tidy_resource_dir.files.to_list() + if files: + directory = files[0].path.split("/include/")[0] + ccinfo_copts.extend(["-resource-dir", directory]) + c_flags = safe_flags(toolchain_flags(ctx, ACTION_NAMES.c_compile) + rule_copts + rule_conlyopts) + ["-xc"] cxx_flags = safe_flags(toolchain_flags(ctx, ACTION_NAMES.cpp_compile) + rule_copts + rule_cxxopts) + ["-xc++"] @@ -95,7 +100,12 @@ fi ctx.files.srcs + ctx.files.hdrs + ctx.files.data, transitive_files = depset( [ctx.file.clang_tidy_config], - transitive = [additional_files, find_cpp_toolchain(ctx).all_files, ctx.attr.clang_tidy_additional_deps.files], + transitive = [ + additional_files, + find_cpp_toolchain(ctx).all_files, + ctx.attr.clang_tidy_additional_deps.files, + ctx.attr.clang_tidy_resource_dir.files, + ], ), ) .merge(clang_tidy[DefaultInfo].default_runfiles), @@ -110,6 +120,7 @@ clang_tidy_test = rule( "deps": attr.label_list(providers = [CcInfo]), "clang_tidy_executable": attr.label(default = Label("//:clang_tidy_executable")), "clang_tidy_additional_deps": attr.label(default = Label("//:clang_tidy_additional_deps")), + "clang_tidy_resource_dir": attr.label(default = Label("//:clang_tidy_resource_dir")), "clang_tidy_config": attr.label( default = Label("//:clang_tidy_config"), allow_single_file = True,