diff --git a/src/codechecker.bzl b/src/codechecker.bzl index 5a10e22a..86e4e557 100644 --- a/src/codechecker.bzl +++ b/src/codechecker.bzl @@ -93,6 +93,8 @@ def _codechecker_impl(ctx): config_file, codechecker_env = get_config_file(ctx) 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") @@ -122,6 +124,7 @@ def _codechecker_impl(ctx): ctx.outputs.codechecker_skipfile, config_file, ] + source_files, + transitive = [py_toolchain.py3_runtime.files], ), tools = [ info.runfiles, @@ -133,6 +136,9 @@ def _codechecker_impl(ctx): ], executable = codechecker_script, arguments = [cmd_args], + env = { + "PATH": info.fake_path.dirname + ":" + py_interpreter_dir, + }, mnemonic = "CodeChecker", progress_message = "CodeChecker %s" % str(ctx.label), # use_default_shell_env = True, @@ -207,6 +213,7 @@ codechecker = rule( }, toolchains = [ "//:toolchain_type", + "@rules_python//python:toolchain_type", ], ) @@ -323,6 +330,7 @@ _codechecker_test = rule( }, toolchains = [ "//:toolchain_type", + "@rules_python//python:toolchain_type", ], test = True, ) diff --git a/src/codechecker_script.py b/src/codechecker_script.py index e3637bd0..1ce8dc4d 100644 --- a/src/codechecker_script.py +++ b/src/codechecker_script.py @@ -251,8 +251,6 @@ def analyze(cfg): if env_list: codechecker_env = dict(item.split("=", 1) for item in env_list) env.update(codechecker_env) - if "PATH" not in env: - env["PATH"] = "/bin" # NOTE: this is workaround for CodeChecker 6.24.4 env["CC_ANALYZER_BIN"] = generate_analyzer_executables(cfg) logging.debug("env: %s", str(env)) diff --git a/src/codechecker_toolchain.bzl b/src/codechecker_toolchain.bzl index f8da745b..269c7f3c 100644 --- a/src/codechecker_toolchain.bzl +++ b/src/codechecker_toolchain.bzl @@ -8,19 +8,29 @@ 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" + dirname = ctx.actions.declare_file(fake_path_dir + "/dirname") + ctx.actions.symlink( + output = dirname, + target_file = ctx.executable.dirname, + ) + + fake_path_files = [dirname] + 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 +45,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 +75,11 @@ codechecker_toolchain = rule( executable = True, cfg = "exec", ), + "dirname": attr.label( + default = "@default_codechecker_tools//:dirname", + doc = "Executable target for dirname", + executable = True, + cfg = "exec", + ), }, ) diff --git a/src/per_file.bzl b/src/per_file.bzl index 6743545d..81c5eccb 100644 --- a/src/per_file.bzl +++ b/src/per_file.bzl @@ -65,12 +65,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()) @@ -79,7 +82,7 @@ def _run_code_checker( config_file, src, config, - ], transitive = [headers]) + ], transitive = [headers, py_toolchain.py3_runtime.files]) outputs = [ clang_tidy_plist, @@ -118,8 +121,10 @@ def _run_code_checker( analyzer_output_paths, analyzer_executables, ], + env = { + "PATH": info.fake_path.dirname + ":" + py_interpreter_dir, + }, mnemonic = "CodeChecker", - use_default_shell_env = True, progress_message = "CodeChecker analyze {}".format(src.short_path), ) return outputs @@ -283,5 +288,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..8822f4bc 100644 --- a/src/tools.bzl +++ b/src/tools.bzl @@ -27,7 +27,9 @@ 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") - + 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 +43,7 @@ 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(dirname_path, "dirname_bin") repository_ctx.file( repository_ctx.path("BUILD"), @@ -59,6 +62,11 @@ filegroup( name = "clang_tidy", srcs = ["clang_tidy_bin"], visibility = ["//visibility:public"], +) +filegroup( + name = "dirname", + srcs = ["dirname_bin"], + visibility = ["//visibility:public"], ) """, executable = False,