From bd93454e58163a124bc58461d5897c324cc84413 Mon Sep 17 00:00:00 2001 From: "F.Tibor" Date: Tue, 14 Apr 2026 10:55:51 +0200 Subject: [PATCH 1/3] WIP 1st iteration --- MODULE.bazel | 14 ++++++++++++++ src/codechecker.bzl | 16 ++++++++++++++-- src/codechecker_script.py | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 8612e105..20b7bacb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,3 +40,17 @@ codechecker_extension = use_extension( "module_register_default_codechecker", ) use_repo(codechecker_extension, "default_codechecker_tools") + +# Last version to support bazel 6 +bazel_dep(name = "toolchains_llvm", version = "0.10.3") + +# Configure and register the toolchain. +llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") +llvm.toolchain( + llvm_version = "16.0.0", +) + +use_repo(llvm, "llvm_toolchain") +use_repo(llvm, "llvm_toolchain_llvm") + +register_toolchains("@llvm_toolchain//:all") diff --git a/src/codechecker.bzl b/src/codechecker.bzl index 505532d0..659a46a5 100644 --- a/src/codechecker.bzl +++ b/src/codechecker.bzl @@ -40,6 +40,8 @@ load( "per_file.bzl", "per_file_test", ) +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") + def get_platform_alias(platform): """ @@ -97,6 +99,16 @@ def _codechecker_impl(ctx): config_file, codechecker_env = get_config_file(ctx) + cc_toolchain = find_cpp_toolchain(ctx) + clang_executable = cc_toolchain.compiler_executable + if hasattr(clang_executable, "dirname"): + wrapper_bin_dir = clang_executable.dirname + else: + wrapper_bin_dir = "/".join(clang_executable.split("/")[:-1]) + real_llvm_bin_dir = wrapper_bin_dir.replace("llvm_toolchain", "llvm_toolchain_llvm") + + codechecker_env += ";PATH={}:{}".format(real_llvm_bin_dir, wrapper_bin_dir) + codechecker_files = ctx.actions.declare_directory(ctx.label.name + "/codechecker-files") ctx.actions.expand_template( template = ctx.file._codechecker_script_template, @@ -205,7 +217,7 @@ codechecker = rule( "codechecker_skipfile": "%{name}/codechecker_skipfile.cfg", "compile_commands": "%{name}/compile_commands.json", }, - toolchains = [python_toolchain_type()], + toolchains = [python_toolchain_type(),"@bazel_tools//tools/cpp:toolchain_type"], ) def _codechecker_test_impl(ctx): @@ -300,7 +312,7 @@ _codechecker_test = rule( "codechecker_test_script": "%{name}/codechecker_test_script.py", "compile_commands": "%{name}/compile_commands.json", }, - toolchains = [python_toolchain_type()], + toolchains = [python_toolchain_type(),"@bazel_tools//tools/cpp:toolchain_type"], test = True, ) diff --git a/src/codechecker_script.py b/src/codechecker_script.py index ce63f26b..4a87f20f 100644 --- a/src/codechecker_script.py +++ b/src/codechecker_script.py @@ -198,6 +198,8 @@ def analyze(): # This can be removed once codechecker 6.16.0 is used. # command += " --keep-gcc-intrin" logging.info("Running CodeChecker analyze...") + output = execute(f"{CODECHECKER_PATH} analyzers", env=env) + logging.info("Output:\n\n%s\n", output) output = execute(command, env=env) logging.info("Output:\n\n%s\n", output) if output.find("- Failed to analyze") != -1: From 2df5f68df5a54e43877ee2e1deed12d53556ac26 Mon Sep 17 00:00:00 2001 From: "F.Tibor" Date: Mon, 4 May 2026 11:41:09 +0200 Subject: [PATCH 2/3] Add way for users to provide their llvm_toolchain for the rule --- MODULE.bazel | 4 ++-- src/codechecker.bzl | 31 ++++++++++++++++--------------- src/codechecker_script.py | 2 ++ test/unit/legacy/BUILD | 1 + 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 20b7bacb..3820ebb4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -41,8 +41,8 @@ codechecker_extension = use_extension( ) use_repo(codechecker_extension, "default_codechecker_tools") -# Last version to support bazel 6 -bazel_dep(name = "toolchains_llvm", version = "0.10.3") + +bazel_dep(name = "toolchains_llvm", version = "1.7.0") # Configure and register the toolchain. llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") diff --git a/src/codechecker.bzl b/src/codechecker.bzl index 659a46a5..a3ec6110 100644 --- a/src/codechecker.bzl +++ b/src/codechecker.bzl @@ -40,8 +40,6 @@ load( "per_file.bzl", "per_file_test", ) -load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") - def get_platform_alias(platform): """ @@ -99,16 +97,6 @@ def _codechecker_impl(ctx): config_file, codechecker_env = get_config_file(ctx) - cc_toolchain = find_cpp_toolchain(ctx) - clang_executable = cc_toolchain.compiler_executable - if hasattr(clang_executable, "dirname"): - wrapper_bin_dir = clang_executable.dirname - else: - wrapper_bin_dir = "/".join(clang_executable.split("/")[:-1]) - real_llvm_bin_dir = wrapper_bin_dir.replace("llvm_toolchain", "llvm_toolchain_llvm") - - codechecker_env += ";PATH={}:{}".format(real_llvm_bin_dir, wrapper_bin_dir) - codechecker_files = ctx.actions.declare_directory(ctx.label.name + "/codechecker-files") ctx.actions.expand_template( template = ctx.file._codechecker_script_template, @@ -128,6 +116,11 @@ def _codechecker_impl(ctx): }, ) + llvm_bin_dir = "" + if ctx.files.llvm_toolchain: + # @llvm_toolchain_llvm//:bin is a file-group + llvm_bin_dir = ctx.files.llvm_toolchain[0].dirname + ctx.actions.run( inputs = depset( [ @@ -142,7 +135,7 @@ def _codechecker_impl(ctx): ctx.outputs.codechecker_log, ], executable = ctx.outputs.codechecker_script, - arguments = [], + arguments = [llvm_bin_dir], # executable = python_path(ctx), # arguments = [ctx.outputs.codechecker_script.path], mnemonic = "CodeChecker", @@ -188,6 +181,10 @@ codechecker = rule( default = None, doc = "CodeChecker configuration", ), + "llvm_toolchain": attr.label( + default = None, + doc = "If the llvm_toolchain is obtained through bazel, provide the PATH to its bin directory here (e.g. @llvm_toolchain_llvm//:bin)", + ), "skip": attr.string_list( default = [], doc = "List of skip/ignore file rules. " + @@ -217,7 +214,7 @@ codechecker = rule( "codechecker_skipfile": "%{name}/codechecker_skipfile.cfg", "compile_commands": "%{name}/compile_commands.json", }, - toolchains = [python_toolchain_type(),"@bazel_tools//tools/cpp:toolchain_type"], + toolchains = [python_toolchain_type()], ) def _codechecker_test_impl(ctx): @@ -273,6 +270,10 @@ _codechecker_test = rule( cfg = platforms_transition, doc = "CodeChecker configuration", ), + "llvm_toolchain": attr.label( + default = None, + doc = "If the llvm_toolchain is obtained through bazel, provide the PATH to its bin directory here (e.g. @llvm_toolchain_llvm//:bin)", + ), "platform": attr.string( default = "", #"@platforms//os:linux", doc = "Platform to build for", @@ -312,7 +313,7 @@ _codechecker_test = rule( "codechecker_test_script": "%{name}/codechecker_test_script.py", "compile_commands": "%{name}/compile_commands.json", }, - toolchains = [python_toolchain_type(),"@bazel_tools//tools/cpp:toolchain_type"], + toolchains = [python_toolchain_type()], test = True, ) diff --git a/src/codechecker_script.py b/src/codechecker_script.py index 4a87f20f..275935c3 100644 --- a/src/codechecker_script.py +++ b/src/codechecker_script.py @@ -186,6 +186,8 @@ def analyze(): env.update(codechecker_env) if "PATH" not in env: env["PATH"] = "/bin" # NOTE: this is workaround for CodeChecker 6.24.4 + if sys.argv[1] != "": + env["PATH"] = os.path.abspath(sys.argv[1]) + os.pathsep + env["PATH"] logging.debug("env: %s", str(env)) output = execute(f"{CODECHECKER_PATH} analyzers --details", env=env) diff --git a/test/unit/legacy/BUILD b/test/unit/legacy/BUILD index ac0c9ef2..0b75b713 100644 --- a/test/unit/legacy/BUILD +++ b/test/unit/legacy/BUILD @@ -132,6 +132,7 @@ codechecker_test( targets = [ "test_pass", ], + llvm_toolchain = "@llvm_toolchain_llvm//:bin", ) # This codechecker_test example supposed to fail showing findings report From 7b923c5269c1c35d7d92b488ea9d4d04320d5ab7 Mon Sep 17 00:00:00 2001 From: "F.Tibor" Date: Tue, 5 May 2026 09:50:53 +0200 Subject: [PATCH 3/3] Use llvm_toolchain for every codechecker action --- MODULE.bazel | 12 ++++++++---- src/codechecker.bzl | 15 ++++++--------- test/unit/legacy/BUILD | 1 - 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 3820ebb4..f9def28e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -47,10 +47,14 @@ bazel_dep(name = "toolchains_llvm", version = "1.7.0") # Configure and register the toolchain. llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") llvm.toolchain( - llvm_version = "16.0.0", + name = "llvm_toolchain", + llvm_version = "20.1.4", + extra_llvm_distributions = { + "LLVM-20.1.4-Linux-ARM64.tar.xz": "4de80a332eecb06bf55097fd3280e1c69ed80f222e5bdd556221a6ceee02721a", + "LLVM-20.1.4-Linux-X64.tar.xz": "113b54c397adb2039fa45e38dc8107b9ec5a0baead3a3bac8ccfbb65b2340caa", + "LLVM-20.1.4-macOS-ARM64.tar.xz": "debb43b7b364c5cf864260d84ba1b201d49b6460fe84b76eaa65688dfadf19d2", + "clang+llvm-20.1.4-x86_64-pc-windows-msvc.tar.xz": "2b12ac1a0689e29a38a7c98c409cbfa83f390aea30c60b7a06e4ed73f82d2457", + }, ) -use_repo(llvm, "llvm_toolchain") use_repo(llvm, "llvm_toolchain_llvm") - -register_toolchains("@llvm_toolchain//:all") diff --git a/src/codechecker.bzl b/src/codechecker.bzl index a3ec6110..f20b8f3b 100644 --- a/src/codechecker.bzl +++ b/src/codechecker.bzl @@ -116,10 +116,7 @@ def _codechecker_impl(ctx): }, ) - llvm_bin_dir = "" - if ctx.files.llvm_toolchain: - # @llvm_toolchain_llvm//:bin is a file-group - llvm_bin_dir = ctx.files.llvm_toolchain[0].dirname + llvm_bin_dir = ctx.files._llvm_toolchain[0].dirname ctx.actions.run( inputs = depset( @@ -128,7 +125,7 @@ def _codechecker_impl(ctx): ctx.outputs.codechecker_commands, ctx.outputs.codechecker_skipfile, config_file, - ] + source_files, + ] + source_files + ctx.files._llvm_toolchain, ), outputs = [ codechecker_files, @@ -181,8 +178,8 @@ codechecker = rule( default = None, doc = "CodeChecker configuration", ), - "llvm_toolchain": attr.label( - default = None, + "_llvm_toolchain": attr.label( + default = "@llvm_toolchain_llvm//:bin", doc = "If the llvm_toolchain is obtained through bazel, provide the PATH to its bin directory here (e.g. @llvm_toolchain_llvm//:bin)", ), "skip": attr.string_list( @@ -270,8 +267,8 @@ _codechecker_test = rule( cfg = platforms_transition, doc = "CodeChecker configuration", ), - "llvm_toolchain": attr.label( - default = None, + "_llvm_toolchain": attr.label( + default = "@llvm_toolchain_llvm//:bin", doc = "If the llvm_toolchain is obtained through bazel, provide the PATH to its bin directory here (e.g. @llvm_toolchain_llvm//:bin)", ), "platform": attr.string( diff --git a/test/unit/legacy/BUILD b/test/unit/legacy/BUILD index 0b75b713..ac0c9ef2 100644 --- a/test/unit/legacy/BUILD +++ b/test/unit/legacy/BUILD @@ -132,7 +132,6 @@ codechecker_test( targets = [ "test_pass", ], - llvm_toolchain = "@llvm_toolchain_llvm//:bin", ) # This codechecker_test example supposed to fail showing findings report