From b005c270e52a3692242380c202a78e18a7f5352c Mon Sep 17 00:00:00 2001 From: "F.Tibor" Date: Thu, 13 Aug 2026 07:46:55 +0200 Subject: [PATCH 1/3] Create fake path for codechecker --- src/codechecker.bzl | 9 +++++- src/codechecker_toolchain.bzl | 52 +++++++++++++++++++++++++++++++---- src/per_file.bzl | 17 +++++++++--- src/tools.bzl | 28 ++++++++++++++++++- 4 files changed, 95 insertions(+), 11 deletions(-) diff --git a/src/codechecker.bzl b/src/codechecker.bzl index 0f3d4dec..3cb1a9d3 100644 --- a/src/codechecker.bzl +++ b/src/codechecker.bzl @@ -96,6 +96,8 @@ def _codechecker_impl(ctx): info = ctx.attr.toolchain[platform_common.ToolchainInfo].codecheckerinfo else: info = ctx.toolchains["//:toolchain_type"].codecheckerinfo + py_toolchain = ctx.toolchains["@rules_python//python:toolchain_type"] + py_interpreter_dir = py_toolchain.py3_runtime.interpreter.dirname codechecker_files = ctx.actions.declare_directory(ctx.label.name + "/codechecker-files") codechecker_script = ctx.attr._codechecker_script[DefaultInfo].files_to_run @@ -122,11 +124,14 @@ def _codechecker_impl(ctx): ] + source_files ctx.actions.run( - inputs = depset(input_files), + inputs = depset(input_files, transitive = [py_toolchain.py3_runtime.files]), tools = [info.runfiles, codechecker_script], outputs = [codechecker_files, ctx.outputs.codechecker_log], executable = codechecker_script, arguments = [arguments], + env = { + "PATH": info.fake_path.dirname + ":" + py_interpreter_dir, + }, mnemonic = "CodeChecker", progress_message = "CodeChecker %s" % str(ctx.label), # use_default_shell_env = True, @@ -202,6 +207,7 @@ codechecker = rule( }, toolchains = [ "//:toolchain_type", + "@rules_python//python:toolchain_type", ], ) @@ -314,6 +320,7 @@ _codechecker_test = rule( }, toolchains = [ "//:toolchain_type", + "@rules_python//python:toolchain_type", ], test = True, ) diff --git a/src/codechecker_toolchain.bzl b/src/codechecker_toolchain.bzl index f8da745b..e8dc7f8d 100644 --- a/src/codechecker_toolchain.bzl +++ b/src/codechecker_toolchain.bzl @@ -8,19 +8,39 @@ CodeCheckerInfo = provider( "clang_tidy": "clang-tidy executable", "clangsa": "Clang executable", "codechecker": "CodeChecker executable", - "runfiles": "Depset of files needed to run the tools: the three executables " + - "plus their transitive data_runfiles. Pass to `tools` in " + - "ctx.actions.run and include in test runfiles.", + "fake_path": "A File in the fake PATH directory. Use .dirname to get the directory path.", + "runfiles": "Depset of files needed to run the tools: the three executables, " + + "fake PATH contents, plus their transitive data_runfiles. Pass to " + + "`tools` in ctx.actions.run and include in test runfiles.", }, ) def _codechecker_toolchain_impl(ctx): + fake_path_dir = "fake_path" + uname = ctx.actions.declare_file(fake_path_dir + "/uname") + ctx.actions.symlink( + output = uname, + target_file = ctx.executable.uname, + ) + dirname = ctx.actions.declare_file(fake_path_dir + "/dirname") + ctx.actions.symlink( + output = dirname, + target_file = ctx.executable.dirname, + ) + openssl = ctx.actions.declare_file(fake_path_dir + "/openssl") + ctx.actions.symlink( + output = openssl, + target_file = ctx.executable.openssl, + ) + + fake_path_files = [uname, dirname, openssl] + runfiles = depset( direct = [ ctx.executable.codechecker, ctx.executable.clangsa, ctx.executable.clang_tidy, - ], + ] + fake_path_files, transitive = [ # We also collect files necessary for these programs to run. # Those files should be declared with `data = [...]` @@ -35,10 +55,14 @@ def _codechecker_toolchain_impl(ctx): codechecker = ctx.executable.codechecker, clang_tidy = ctx.executable.clang_tidy, clangsa = ctx.executable.clangsa, + fake_path = dirname, runfiles = runfiles, ), ) - return [toolchain_info] + return [ + toolchain_info, + DefaultInfo(files = depset(fake_path_files)), + ] codechecker_toolchain = rule( implementation = _codechecker_toolchain_impl, @@ -61,5 +85,23 @@ codechecker_toolchain = rule( executable = True, cfg = "exec", ), + "dirname": attr.label( + default = "@default_codechecker_tools//:dirname", + doc = "Executable target for dirname", + executable = True, + cfg = "exec", + ), + "openssl": attr.label( + default = "@default_codechecker_tools//:openssl", + doc = "Executable target for openssl", + executable = True, + cfg = "exec", + ), + "uname": attr.label( + default = "@default_codechecker_tools//:uname", + doc = "Executable target for uname", + executable = True, + cfg = "exec", + ), }, ) diff --git a/src/per_file.bzl b/src/per_file.bzl index d33b85dd..08b08b0f 100644 --- a/src/per_file.bzl +++ b/src/per_file.bzl @@ -70,12 +70,15 @@ def _run_code_checker( codechecker_metadata = ctx.actions.declare_file(codechecker_metadata_file_name) + py_toolchain = ctx.toolchains["@rules_python//python:toolchain_type"] + py_interpreter_dir = py_toolchain.py3_runtime.interpreter.dirname + if "--ctu" in options: - inputs = [ + inputs = depset([ compile_commands_json, config_file, config, - ] + sources_and_headers + ] + sources_and_headers, transitive = [py_toolchain.py3_runtime.files]) else: # NOTE: we collect only headers, so CTU may not work! headers = depset(transitive = target[SourceFilesInfo].headers.to_list()) @@ -84,7 +87,7 @@ def _run_code_checker( config_file, src, config, - ], transitive = [headers]) + ], transitive = [headers, py_toolchain.py3_runtime.files]) outputs = [ clang_tidy_plist, @@ -134,6 +137,9 @@ def _run_code_checker( "--analyzer_executables", analyzer_executables, ], + env = { + "PATH": info.fake_path.dirname + ":" + py_interpreter_dir, + }, mnemonic = "CodeChecker", progress_message = "CodeChecker analyze {}".format(src.short_path), ) @@ -307,5 +313,8 @@ per_file_test = rule( "test_script": "%{name}/test_script.sh", }, test = True, - toolchains = ["//:toolchain_type"], + toolchains = [ + "//:toolchain_type", + "@rules_python//python:toolchain_type", + ], ) diff --git a/src/tools.bzl b/src/tools.bzl index 99a2ea63..acd44125 100644 --- a/src/tools.bzl +++ b/src/tools.bzl @@ -27,7 +27,15 @@ def _codechecker_local_repository_impl(repository_ctx): clang_tidy_bin_path = repository_ctx.which("clang-tidy") if not clang_tidy_bin_path: fail("ERROR! Clang-tidy is not detected") - + uname_path = repository_ctx.which("uname") + if not uname_path: + fail("ERROR! uname is not detected") + openssl_path = repository_ctx.which("openssl") + if not openssl_path: + fail("ERROR! Openssl is not detected") + dirname_path = repository_ctx.which("dirname") + if not dirname_path: + fail("ERROR! dirname is not detected") defs = "CODECHECKER_BIN_PATH = '{}'\n".format(codechecker_bin_path) defs += "CLANG_BIN_PATH = '{}'\n".format(clang_bin_path) defs += "CLANG_TIDY_BIN_PATH = '{}'\n".format(clang_tidy_bin_path) @@ -41,6 +49,9 @@ def _codechecker_local_repository_impl(repository_ctx): repository_ctx.symlink(codechecker_bin_path, "codechecker_bin") repository_ctx.symlink(clang_bin_path, "clang_bin") repository_ctx.symlink(clang_tidy_bin_path, "clang_tidy_bin") + repository_ctx.symlink(uname_path, "uname_bin") + repository_ctx.symlink(dirname_path, "dirname_bin") + repository_ctx.symlink(openssl_path, "openssl_bin") repository_ctx.file( repository_ctx.path("BUILD"), @@ -59,6 +70,21 @@ filegroup( name = "clang_tidy", srcs = ["clang_tidy_bin"], visibility = ["//visibility:public"], +) +filegroup( + name = "uname", + srcs = ["uname_bin"], + visibility = ["//visibility:public"], +) +filegroup( + name = "dirname", + srcs = ["dirname_bin"], + visibility = ["//visibility:public"], +) +filegroup( + name = "openssl", + srcs = ["openssl_bin"], + visibility = ["//visibility:public"], ) """, executable = False, From 55942db4efe2d258034b10f76fc8d8996cc4b173 Mon Sep 17 00:00:00 2001 From: "F.Tibor" Date: Thu, 13 Aug 2026 08:48:07 +0200 Subject: [PATCH 2/3] Remove openssl (its optional) --- src/codechecker_toolchain.bzl | 13 +------------ src/tools.bzl | 9 --------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/codechecker_toolchain.bzl b/src/codechecker_toolchain.bzl index e8dc7f8d..91cd3f08 100644 --- a/src/codechecker_toolchain.bzl +++ b/src/codechecker_toolchain.bzl @@ -27,13 +27,8 @@ def _codechecker_toolchain_impl(ctx): output = dirname, target_file = ctx.executable.dirname, ) - openssl = ctx.actions.declare_file(fake_path_dir + "/openssl") - ctx.actions.symlink( - output = openssl, - target_file = ctx.executable.openssl, - ) - fake_path_files = [uname, dirname, openssl] + fake_path_files = [uname, dirname] runfiles = depset( direct = [ @@ -91,12 +86,6 @@ codechecker_toolchain = rule( executable = True, cfg = "exec", ), - "openssl": attr.label( - default = "@default_codechecker_tools//:openssl", - doc = "Executable target for openssl", - executable = True, - cfg = "exec", - ), "uname": attr.label( default = "@default_codechecker_tools//:uname", doc = "Executable target for uname", diff --git a/src/tools.bzl b/src/tools.bzl index acd44125..0838c4ad 100644 --- a/src/tools.bzl +++ b/src/tools.bzl @@ -30,9 +30,6 @@ def _codechecker_local_repository_impl(repository_ctx): uname_path = repository_ctx.which("uname") if not uname_path: fail("ERROR! uname is not detected") - openssl_path = repository_ctx.which("openssl") - if not openssl_path: - fail("ERROR! Openssl is not detected") dirname_path = repository_ctx.which("dirname") if not dirname_path: fail("ERROR! dirname is not detected") @@ -51,7 +48,6 @@ def _codechecker_local_repository_impl(repository_ctx): repository_ctx.symlink(clang_tidy_bin_path, "clang_tidy_bin") repository_ctx.symlink(uname_path, "uname_bin") repository_ctx.symlink(dirname_path, "dirname_bin") - repository_ctx.symlink(openssl_path, "openssl_bin") repository_ctx.file( repository_ctx.path("BUILD"), @@ -80,11 +76,6 @@ filegroup( name = "dirname", srcs = ["dirname_bin"], visibility = ["//visibility:public"], -) -filegroup( - name = "openssl", - srcs = ["openssl_bin"], - visibility = ["//visibility:public"], ) """, executable = False, From 089989490ed75cfa715d118a4e89b9c40ebe6109 Mon Sep 17 00:00:00 2001 From: "F.Tibor" Date: Thu, 13 Aug 2026 08:51:34 +0200 Subject: [PATCH 3/3] Remove uname (its optional) --- src/codechecker_toolchain.bzl | 13 +------------ src/tools.bzl | 9 --------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/codechecker_toolchain.bzl b/src/codechecker_toolchain.bzl index 91cd3f08..269c7f3c 100644 --- a/src/codechecker_toolchain.bzl +++ b/src/codechecker_toolchain.bzl @@ -17,18 +17,13 @@ CodeCheckerInfo = provider( def _codechecker_toolchain_impl(ctx): fake_path_dir = "fake_path" - uname = ctx.actions.declare_file(fake_path_dir + "/uname") - ctx.actions.symlink( - output = uname, - target_file = ctx.executable.uname, - ) dirname = ctx.actions.declare_file(fake_path_dir + "/dirname") ctx.actions.symlink( output = dirname, target_file = ctx.executable.dirname, ) - fake_path_files = [uname, dirname] + fake_path_files = [dirname] runfiles = depset( direct = [ @@ -86,11 +81,5 @@ codechecker_toolchain = rule( executable = True, cfg = "exec", ), - "uname": attr.label( - default = "@default_codechecker_tools//:uname", - doc = "Executable target for uname", - executable = True, - cfg = "exec", - ), }, ) diff --git a/src/tools.bzl b/src/tools.bzl index 0838c4ad..8822f4bc 100644 --- a/src/tools.bzl +++ b/src/tools.bzl @@ -27,9 +27,6 @@ def _codechecker_local_repository_impl(repository_ctx): clang_tidy_bin_path = repository_ctx.which("clang-tidy") if not clang_tidy_bin_path: fail("ERROR! Clang-tidy is not detected") - uname_path = repository_ctx.which("uname") - if not uname_path: - fail("ERROR! uname is not detected") dirname_path = repository_ctx.which("dirname") if not dirname_path: fail("ERROR! dirname is not detected") @@ -46,7 +43,6 @@ def _codechecker_local_repository_impl(repository_ctx): repository_ctx.symlink(codechecker_bin_path, "codechecker_bin") repository_ctx.symlink(clang_bin_path, "clang_bin") repository_ctx.symlink(clang_tidy_bin_path, "clang_tidy_bin") - repository_ctx.symlink(uname_path, "uname_bin") repository_ctx.symlink(dirname_path, "dirname_bin") repository_ctx.file( @@ -67,11 +63,6 @@ filegroup( srcs = ["clang_tidy_bin"], visibility = ["//visibility:public"], ) -filegroup( - name = "uname", - srcs = ["uname_bin"], - visibility = ["//visibility:public"], -) filegroup( name = "dirname", srcs = ["dirname_bin"],