diff --git a/src/per_file.bzl b/src/per_file.bzl index 67d51538..7b187910 100644 --- a/src/per_file.bzl +++ b/src/per_file.bzl @@ -20,6 +20,10 @@ 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, @@ -27,6 +31,8 @@ def _run_code_checker( arguments, label, options, + config_file, + env_vars, compile_commands_json, compilation_context, sources_and_headers): @@ -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] @@ -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 + " " @@ -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, }, ) @@ -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 @@ -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, @@ -363,6 +373,10 @@ 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, @@ -370,6 +384,7 @@ per_file_test = rule( "_python_runtime": attr.label( default = "@default_python_tools//:py3_runtime", ), + }, outputs = { "test_script": "%{name}/test_script.sh", @@ -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 ) diff --git a/src/per_file_script.py b/src/per_file_script.py index 46bd13b4..47bdafb4 100644 --- a/src/per_file_script.py +++ b/src/per_file_script.py @@ -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(): @@ -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") @@ -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 diff --git a/test/unit/config/BUILD b/test/unit/config/BUILD index 2447abda..b2b8493e 100644 --- a/test/unit/config/BUILD +++ b/test/unit/config/BUILD @@ -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", ], @@ -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", ], diff --git a/test/unit/config/test_config.py b/test/unit/config/test_config.py index 145bcf59..72acd4a5 100644 --- a/test/unit/config/test_config.py +++ b/test/unit/config/test_config.py @@ -95,15 +95,13 @@ 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""" @@ -111,15 +109,13 @@ def test_per_file_test_yaml(self): "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__":