Skip to content

Commit

Permalink
[analyzer] Add support the CC_ANALYZER_BIN env var
Browse files Browse the repository at this point in the history
This environmental variable can be used the specify the absolute path of
an analyzer. Similar to Ericsson#4041, but this is the only solution we can
realistically get though the door.
  • Loading branch information
Szelethus committed Oct 26, 2023
1 parent 3999910 commit 44c61cf
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 2 deletions.
5 changes: 4 additions & 1 deletion analyzer/codechecker_analyzer/analyzers/analyzer_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ def check_supported_analyzers(analyzers):
error = analyzer.is_binary_version_incompatible(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 \
Expand Down
17 changes: 17 additions & 0 deletions analyzer/codechecker_analyzer/arg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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: <analyzer>:<path>
"""
m = re.match(r"(?P<analyzer>.+):(?P<path>.+)", arg)

if not m:
raise argparse.ArgumentTypeError(
f"Analyzer binary in wrong format: {arg}, should be "
"<analyzer>:</path/to/bin/>")

return AnalyzerBinary(m.group("analyzer"), m.group("path"))
42 changes: 41 additions & 1 deletion analyzer/codechecker_analyzer/cmd/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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='<analyzer1>:/path/to/bin1;
<analyzer2>:/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
Expand Down Expand Up @@ -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='<analyzer1>:/path/to/bin1;"
"<analyzer2>:/path/to/bin2'")
sys.exit(1)


def main(args):
"""
Perform analysis on the given inputs. Possible inputs are a compilation
Expand Down Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions docs/analyzer/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -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='<analyzer1>:/path/to/bin1;
<analyzer2>:/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
Expand Down Expand Up @@ -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='<analyzer1>:/path/to/bin1;
<analyzer2>:/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
Expand Down

0 comments on commit 44c61cf

Please sign in to comment.