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..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 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..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,