diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index 4f32c045a5..363621180f 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -266,6 +266,42 @@ def analyzer_binary(cls): return analyzer_context.get_context() \ .analyzer_binaries[cls.ANALYZER_NAME] + @classmethod + def analyzer_base_cmd(cls) -> List[str]: + return [cls.analyzer_binary()] + \ + ["-load=" + f for f in cls.analyzer_plugins()] + + @classmethod + def analyzer_plugins(cls) -> List[str]: + """ + Return the list of .so file paths which contain checker plugins to + Clang-Tidy. + """ + if env.is_analyzer_from_path(): + clangtidy_plugin_dir = env.get_clangtidy_plugin_dir() + if not clangtidy_plugin_dir: + return [] + + # If the CC_ANALYZERS_FROM_PATH and CC_CLANGTIDY_PLUGIN_DIR + # environment variables are set we will use this value as the + # plugin directory. + plugin_dir = clangtidy_plugin_dir + + else: + base_plugin_dir = analyzer_context.get_context().checker_plugin + if not base_plugin_dir: + return [] + + plugin_dir = os.path.join(base_plugin_dir, "clangtidy") + + if not os.path.isdir(plugin_dir): + return [] + + return [os.path.join(plugin_dir, f) + for f in os.listdir(plugin_dir) + if os.path.isfile(os.path.join(plugin_dir, f)) + and f.endswith(".so")] + @classmethod def get_binary_version(cls) -> Optional[Version]: if not cls.analyzer_binary(): @@ -311,7 +347,7 @@ def get_analyzer_checkers(cls): environ = context.get_env_for_bin(cls.analyzer_binary()) result = subprocess.check_output( - [cls.analyzer_binary(), "-list-checks", "-checks=*"], + cls.analyzer_base_cmd() + ["-list-checks", "-checks=*"], env=environ, universal_newlines=True, encoding="utf-8", @@ -340,7 +376,7 @@ def get_checker_config(cls) -> List[analyzer_base.CheckerConfig]: """ try: help_page = subprocess.check_output( - [cls.analyzer_binary(), "-dump-config", "-checks=*"], + cls.analyzer_base_cmd() + ["-dump-config", "-checks=*"], env=analyzer_context.get_context() .get_env_for_bin(cls.analyzer_binary()), universal_newlines=True, @@ -365,7 +401,7 @@ def get_analyzer_config(cls) -> List[analyzer_base.AnalyzerConfig]: try: result = subprocess.check_output( - [cls.analyzer_binary(), "-dump-config", "-checks=*"], + cls.analyzer_base_cmd() + ["-dump-config", "-checks=*"], env=analyzer_context.get_context() .get_env_for_bin(cls.analyzer_binary()), universal_newlines=True, @@ -494,7 +530,7 @@ def construct_analyzer_cmd(self, result_handler): try: config = self.config_handler - analyzer_cmd = [ClangTidy.analyzer_binary()] + analyzer_cmd = ClangTidy.analyzer_base_cmd() checks, compiler_warnings = self.get_checker_list(config) diff --git a/analyzer/codechecker_analyzer/cli/analyze.py b/analyzer/codechecker_analyzer/cli/analyze.py index 7daae8ffad..3a8bf7a5a3 100644 --- a/analyzer/codechecker_analyzer/cli/analyze.py +++ b/analyzer/codechecker_analyzer/cli/analyze.py @@ -53,6 +53,9 @@ is set you can configure the plugin directory of the Clang Static Analyzer by using this environment variable. + CC_CLANGTIDY_PLUGIN_DIR If the CC_ANALYZERS_FROM_PATH environment variable + is set you can configure the plugin directory of + Clang-Tidy by using this environment variable. """ EPILOG_ISSUE_HASHES = """ diff --git a/analyzer/codechecker_analyzer/env.py b/analyzer/codechecker_analyzer/env.py index 09b02ae647..16015cac17 100644 --- a/analyzer/codechecker_analyzer/env.py +++ b/analyzer/codechecker_analyzer/env.py @@ -212,3 +212,8 @@ def is_analyzer_from_path(): def get_clangsa_plugin_dir(): """ Return the value of the CC_CLANGSA_PLUGIN_DIR environment variable. """ return os.environ.get('CC_CLANGSA_PLUGIN_DIR') + + +def get_clangtidy_plugin_dir(): + """ Return the value of the CC_CLANGTIDY_PLUGIN_DIR environment variable. """ + return os.environ.get('CC_CLANGTIDY_PLUGIN_DIR') diff --git a/docs/analyzer/user_guide.md b/docs/analyzer/user_guide.md index 24aea2ba7a..f8f32d68ef 100644 --- a/docs/analyzer/user_guide.md +++ b/docs/analyzer/user_guide.md @@ -571,6 +571,9 @@ Environment variables for 'CodeChecker analyze' command: is set you can configure the plugin directory of the Clang Static Analyzer by using this environment variable. + CC_CLANGTIDY_PLUGIN_DIR If the CC_ANALYZERS_FROM_PATH environment variable + is set you can configure the plugin directory of + Clang-Tidy by using this environment variable. Environment variables for 'CodeChecker parse' command: @@ -1150,6 +1153,9 @@ Environment variables is set you can configure the plugin directory of the Clang Static Analyzer by using this environment variable. + CC_CLANGTIDY_PLUGIN_DIR If the CC_ANALYZERS_FROM_PATH environment variable + is set you can configure the plugin directory of + Clang-Tidy by using this environment variable. ``` @@ -2570,7 +2576,8 @@ You can set the `CC_ANALYZERS_FROM_PATH` environment variable before running a CodeChecker command to `yes` or `1` to enforce taking the analyzers from the `PATH` instead of the given binaries. If this option is set you can also configure the plugin directory of the Clang Static Analyzer by using the -`CC_CLANGSA_PLUGIN_DIR` environment variable. +`CC_CLANGSA_PLUGIN_DIR` environment variable and of Clang-Tidy by using the +`CC_CLANGTIDY_PLUGIN_DIR` environment variable. Make sure that the required include paths are at the right place! Clang based tools search by default for diff --git a/docs/package_layout.md b/docs/package_layout.md index 8c85598cbd..3066528b1f 100644 --- a/docs/package_layout.md +++ b/docs/package_layout.md @@ -28,7 +28,8 @@ You can set the `CC_ANALYZERS_FROM_PATH` environment variable before running a CodeChecker command to `yes` or `1` to enforce taking the analyzers from the `PATH` instead of the given binaries. If this option is set you can also configure the plugin directory of the Clang Static Analyzer by using the -`CC_CLANGSA_PLUGIN_DIR` environment variable. +`CC_CLANGSA_PLUGIN_DIR` environment variable and of Clang-Tidy by using the +`CC_CLANGTIDY_PLUGIN_DIR` environment variable. ### Replacer section This section is a key-value component. The key is `clang-apply-replacements`