From fb981b2b099ddbc17213b655f97b92e7af457e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20Umann?= Date: Tue, 24 Oct 2023 15:04:37 +0200 Subject: [PATCH] [analyzer] Add support the CC_ANALYZER_BIN env var This environmental variable can be used the specify the absolute path of an analyzer. Similar to #4041, but this is the only solution we can realistically get though the door. --- .../analyzers/analyzer_types.py | 5 ++- analyzer/codechecker_analyzer/arg.py | 17 ++++++++ analyzer/codechecker_analyzer/cmd/analyze.py | 42 ++++++++++++++++++- docs/analyzer/user_guide.md | 10 +++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py index 30fa93ad5b..e28134b791 100644 --- a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py +++ b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py @@ -190,7 +190,10 @@ def check_supported_analyzers(analyzers): check_env) if error: failed_analyzers.add((analyzer_name, - f"Incompatible version: {error}")) + f"Incompatible version: {error} " + "Maybe try setting an absolute path to " + "a different analyzer binary via the " + "env variable CC_ANALYZER_BIN?")) available_analyzer = False if not analyzer_bin or \ diff --git a/analyzer/codechecker_analyzer/arg.py b/analyzer/codechecker_analyzer/arg.py index afdc664dcc..6d49cecabf 100644 --- a/analyzer/codechecker_analyzer/arg.py +++ b/analyzer/codechecker_analyzer/arg.py @@ -18,6 +18,8 @@ 'AnalyzerConfig', ["analyzer", "option", "value"]) CheckerConfig = collections.namedtuple( "CheckerConfig", ["analyzer", "checker", "option", "value"]) +AnalyzerBinary = collections.namedtuple( + "AnalyzerBinary", ["analyzer", "path"]) class OrderedCheckersAction(argparse.Action): @@ -133,3 +135,18 @@ def checker_config(arg: str) -> CheckerConfig: return CheckerConfig( m.group("analyzer"), m.group("checker"), m.group("option"), m.group("value")) + + +def analyzer_binary(arg: str) -> AnalyzerBinary: + """ + This function can be used at "type" argument of argparse.add_argument(). + It checks the format of --analyzer_binary flag: : + """ + m = re.match(r"(?P.+):(?P.+)", arg) + + if not m: + raise argparse.ArgumentTypeError( + f"Analyzer binary in wrong format: {arg}, should be " + ":") + + return AnalyzerBinary(m.group("analyzer"), m.group("path")) diff --git a/analyzer/codechecker_analyzer/cmd/analyze.py b/analyzer/codechecker_analyzer/cmd/analyze.py index dd3fe1f8fe..3ea27ecb63 100644 --- a/analyzer/codechecker_analyzer/cmd/analyze.py +++ b/analyzer/codechecker_analyzer/cmd/analyze.py @@ -27,7 +27,7 @@ from codechecker_analyzer.analyzers import analyzer_types, clangsa from codechecker_analyzer.arg import \ OrderedCheckersAction, OrderedConfigAction, existing_abspath, \ - analyzer_config, checker_config + analyzer_config, checker_config, analyzer_binary from codechecker_analyzer.buildlog import log_parser from codechecker_common import arg, logger, cmd_config @@ -44,6 +44,11 @@ epilog_env_var = f""" CC_ANALYZERS_FROM_PATH Set to `yes` or `1` to enforce taking the analyzers from the `PATH` instead of the given binaries. + CC_ANALYZER_BIN Set the absolute paths of an analyzer binaries. + Overrides other means of CodeChecker getting hold of + binary. + Format: CC_ANALYZER_BIN=':/path/to/bin1; + :/path/to/bin2' CC_CLANGSA_PLUGIN_DIR If the CC_ANALYZERS_FROM_PATH environment variable is set you can configure the plugin directory of the Clang Static Analyzer by using this environment @@ -899,6 +904,40 @@ def __get_result_source_files(metadata): return result_src_files +def __parse_CC_ANALYZER_BIN(): + context = analyzer_context.get_context() + if 'CC_ANALYZER_BIN' in context.analyzer_env: + had_error = False + for value in context.analyzer_env['CC_ANALYZER_BIN'].split(';'): + try: + analyzer_name, path = analyzer_binary(value) + except argparse.ArgumentTypeError as e: + LOG.error(e) + had_error = True + continue + + if analyzer_name not in analyzer_types.supported_analyzers: + LOG.error(f"Unsupported analyzer_name name '{analyzer_name}' " + "given to CC_ANALYZER_BIN!") + had_error = True + if not os.path.isfile(path): + LOG.error(f"'{path}' is not a path to an analyzer binary " + "given to CC_ANALYZER_BIN!") + had_error = True + + if had_error: + continue + + LOG.info(f"Using '{path}' for analyzer '{analyzer_name}'") + context.analyzer_binaries[analyzer_name] = path + + if had_error: + LOG.info("The value of CC_ANALYZER_BIN should be in the format of " + "CC_ANALYZER_BIN=':/path/to/bin1;" + ":/path/to/bin2'") + sys.exit(1) + + def main(args): """ Perform analysis on the given inputs. Possible inputs are a compilation @@ -981,6 +1020,7 @@ def main(args): ctu_or_stats_enabled = True context = analyzer_context.get_context() + __parse_CC_ANALYZER_BIN() # Number of all the compilation commands in the parsed log files, # logged by the logger. diff --git a/docs/analyzer/user_guide.md b/docs/analyzer/user_guide.md index ca48db0c28..8c59b088f0 100644 --- a/docs/analyzer/user_guide.md +++ b/docs/analyzer/user_guide.md @@ -499,6 +499,11 @@ Environment variables for 'CodeChecker analyze' command: CC_ANALYZERS_FROM_PATH Set to `yes` or `1` to enforce taking the analyzers from the `PATH` instead of the given binaries. + CC_ANALYZER_BIN Set the absolute paths of an analyzer binaries. + Overrides other means of CodeChecker getting hold of + binary. + Format: CC_ANALYZER_BIN=':/path/to/bin1; + :/path/to/bin2' CC_CLANGSA_PLUGIN_DIR If the CC_ANALYZERS_FROM_PATH environment variable is set you can configure the plugin directory of the Clang Static Analyzer by using this environment @@ -1031,6 +1036,11 @@ Environment variables CC_ANALYZERS_FROM_PATH Set to `yes` or `1` to enforce taking the analyzers from the `PATH` instead of the given binaries. + CC_ANALYZER_BIN Set the absolute paths of an analyzer binaries. + Overrides other means of CodeChecker getting hold of + binary. + Format: CC_ANALYZER_BIN=':/path/to/bin1; + :/path/to/bin2' CC_CLANGSA_PLUGIN_DIR If the CC_ANALYZERS_FROM_PATH environment variable is set you can configure the plugin directory of the Clang Static Analyzer by using this environment