Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions src/per_file.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ for each translation unit.
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("@codechecker_bazel//src:tools.bzl", "warning", "source_attr")
load(
"@codechecker_bazel//src:codechecker_config.bzl",
"get_config_file"
)

def _run_code_checker(
ctx,
src,
arguments,
label,
options,
config_file,
env_vars,
compile_commands_json,
compilation_context,
sources_and_headers):
Expand All @@ -43,11 +49,11 @@ def _run_code_checker(
codechecker_log = ctx.actions.declare_file(codechecker_log_file_name)

if "--ctu" in options:
inputs = [compile_commands_json] + sources_and_headers
inputs = [compile_commands_json, config_file] + sources_and_headers
else:
# NOTE: we collect only headers, so CTU may not work!
headers = depset([src], transitive = [compilation_context.headers])
inputs = depset([compile_commands_json, src], transitive = [headers])
inputs = depset([compile_commands_json, config_file, src], transitive = [headers])

outputs = [clang_tidy_plist, clangsa_plist, codechecker_log]

Expand Down Expand Up @@ -277,7 +283,7 @@ def _collect_all_sources_and_headers(ctx):
sources_and_headers = all_files + headers.to_list()
return sources_and_headers

def _create_wrapper_script(ctx, options, compile_commands_json):
def _create_wrapper_script(ctx, options, compile_commands_json, config_file):
options_str = ""
for item in options:
options_str += item + " "
Expand All @@ -289,6 +295,7 @@ def _create_wrapper_script(ctx, options, compile_commands_json):
"{PythonPath}": ctx.attr._python_runtime[PyRuntimeInfo].interpreter_path,
"{compile_commands_json}": compile_commands_json.path,
"{codechecker_args}": options_str,
"{config_file}": config_file.path,
},
)

Expand All @@ -297,7 +304,8 @@ def _per_file_impl(ctx):
sources_and_headers = _collect_all_sources_and_headers(ctx)
options = ctx.attr.default_options + ctx.attr.options
all_files = [compile_commands_json]
_create_wrapper_script(ctx, options, compile_commands_json)
config_file, env_vars = get_config_file(ctx)
_create_wrapper_script(ctx, options, compile_commands_json, config_file)
for target in ctx.attr.targets:
if not CcInfo in target:
continue
Expand All @@ -314,6 +322,8 @@ def _per_file_impl(ctx):
args,
ctx.attr.name,
options,
config_file,
env_vars,
compile_commands_json,
compilation_context,
sources_and_headers,
Expand Down Expand Up @@ -363,13 +373,18 @@ per_file_test = rule(
],
doc = "List of compilable targets which should be checked.",
),
"config": attr.label(
default = None,
doc = "CodeChecker configuration",
),
"_per_file_script_template": attr.label(
default = ":per_file_script.py",
allow_single_file = True,
),
"_python_runtime": attr.label(
default = "@default_python_tools//:py3_runtime",
),

},
outputs = {
"test_script": "%{name}/test_script.sh",
Expand All @@ -382,12 +397,16 @@ per_file_test = rule(
def code_checker_test(
name,
targets,
config = None,
options = [],
tags = [],
**kwargs
):
per_file_test(
name = name,
options = options,
targets = targets,
config = config,
tags = tags,
**kwargs
)
19 changes: 9 additions & 10 deletions src/per_file_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
COMPILE_COMMANDS_JSON: str = "{compile_commands_json}"
COMPILE_COMMANDS_ABSOLUTE: str = f"{COMPILE_COMMANDS_JSON}.abs"
CODECHECKER_ARGS: str = "{codechecker_args}"
CONFIG_FILE: str = "{config_file}"


def parse_args():
Expand Down Expand Up @@ -82,10 +83,15 @@ def _run_codechecker() -> None:
"""
Runs CodeChecker analyze
"""
log(
f"CodeChecker command: CodeChecker analyze {CODECHECKER_ARGS} \
{COMPILE_COMMANDS_ABSOLUTE} --output={DATA_DIR} --file=*/{FILE_PATH}\n"
codechecker_cmd: list[str] = (
["CodeChecker", "analyze"]
+ CODECHECKER_ARGS.split()
+ ["--output=" + DATA_DIR] # type: ignore
+ ["--file=*/" + FILE_PATH] # type: ignore
+ ["--config", CONFIG_FILE]
+ [COMPILE_COMMANDS_ABSOLUTE]
)
log(f"CodeChecker command: {' '.join(codechecker_cmd)}\n")
log("===-----------------------------------------------------===\n")
log(" CodeChecker error log \n")
log("===-----------------------------------------------------===\n")
Expand All @@ -99,13 +105,6 @@ def _run_codechecker() -> None:
)
log(result.stdout)

codechecker_cmd: list[str] = (
["CodeChecker", "analyze"]
+ CODECHECKER_ARGS.split()
+ ["--output=" + DATA_DIR] # type: ignore
+ ["--file=*/" + FILE_PATH] # type: ignore
+ [COMPILE_COMMANDS_ABSOLUTE]
)

try:
with open(LOG_FILE, "a") as log_file: # type: ignore
Expand Down
6 changes: 2 additions & 4 deletions test/unit/config/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ codechecker_test(

codechecker_test(
name = "per_file_test_json",
#config = "config_json", #TODO: uncomment
# complains that per_file doesn't have a config attribute
config = "config_json",
targets = [
"test_zero",
],
Expand All @@ -101,8 +100,7 @@ codechecker_test(

codechecker_test(
name = "per_file_test_yaml",
#config = "config_yaml", #TODO: uncomment
# complains that per_file doesn't have a config attribute
config = "config_yaml",
targets = [
"test_zero",
],
Expand Down
12 changes: 4 additions & 8 deletions test/unit/config/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,31 +95,27 @@ def test_per_file_test_json(self):
"bazel test //test/unit/config:per_file_test_json"
)
# Should not find the division by zero bug
self.assertEqual(ret, 3) # TODO: Change to 0
# since CodeChecker won't find the division by zero bug
self.assertEqual(ret, 0)
copied_config = os.path.join(
self.BAZEL_BIN_DIR, # type: ignore
"per_file_test_json",
"config.json"
)
self.assertFalse(os.path.exists(copied_config)) # TODO: Set to True
# Before the patch config files aren't supported in per_file
self.assertTrue(os.path.exists(copied_config))

def test_per_file_test_yaml(self):
"""Test: bazel test //test/unit/config:per_file_test_yaml"""
ret, _, _ = self.run_command(
"bazel test //test/unit/config:per_file_test_yaml"
)
# Should not find the division by zero bug
self.assertEqual(ret, 3) # TODO: Change to 0
# since CodeChecker won't find the division by zero bug
self.assertEqual(ret, 0)
copied_config = os.path.join(
self.BAZEL_BIN_DIR, # type: ignore
"per_file_test_yaml",
"config.yaml"
)
self.assertFalse(os.path.exists(copied_config)) # TODO: Set to True
# Before the patch config files aren't supported in per_file
self.assertTrue(os.path.exists(copied_config))


if __name__ == "__main__":
Expand Down