From c513c78e04e218fe0852177cfe2c385a08d9c2f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 04:16:51 +0000 Subject: [PATCH 1/6] Bump webpack from 5.91.0 to 5.94.0 in /web/server/vue-cli Bumps [webpack](https://github.com/webpack/webpack) from 5.91.0 to 5.94.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.91.0...v5.94.0) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- web/server/vue-cli/package-lock.json | 72 ++++++++++------------------ web/server/vue-cli/package.json | 2 +- 2 files changed, 26 insertions(+), 48 deletions(-) diff --git a/web/server/vue-cli/package-lock.json b/web/server/vue-cli/package-lock.json index d908b8c278..56acd84f72 100644 --- a/web/server/vue-cli/package-lock.json +++ b/web/server/vue-cli/package-lock.json @@ -64,7 +64,7 @@ "vue-style-loader": "^4.1.3", "vue-template-compiler": "^2.6.14", "vuetify-loader": "^1.7.3", - "webpack": "^5.76.0", + "webpack": "^5.94.0", "webpack-cli": "^4.9.1", "webpack-dev-server": "^4.7.3", "webpack-merge": "^5.8.0" @@ -3161,16 +3161,6 @@ "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -3795,10 +3785,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -6380,9 +6370,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -16407,21 +16397,20 @@ } }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -19616,16 +19605,6 @@ "@types/json-schema": "*" } }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -20182,10 +20161,10 @@ "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "requires": {} }, @@ -22061,9 +22040,9 @@ } }, "enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -29517,21 +29496,20 @@ } }, "webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "requires": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", diff --git a/web/server/vue-cli/package.json b/web/server/vue-cli/package.json index 2239777668..719f039497 100644 --- a/web/server/vue-cli/package.json +++ b/web/server/vue-cli/package.json @@ -82,7 +82,7 @@ "vue-style-loader": "^4.1.3", "vue-template-compiler": "^2.6.14", "vuetify-loader": "^1.7.3", - "webpack": "^5.76.0", + "webpack": "^5.94.0", "webpack-cli": "^4.9.1", "webpack-dev-server": "^4.7.3", "webpack-merge": "^5.8.0" From 1ddcad01b6860227dde96ab12da148886679bf13 Mon Sep 17 00:00:00 2001 From: Daniel Krupp Date: Thu, 5 Sep 2024 18:06:42 +0200 Subject: [PATCH 2/6] Environment initialization for binaries CodeChecker calls various binaries during analysis: clang, clang-tidy, clang-extdef-mapping etc. If the binary is delivered within the CodeChecker package, LD_LIBRARY_PATH needs to be extended with it. Otherwise the environment of the caller shell should be used for excuting binaries. --- analyzer/codechecker_analyzer/analyzer.py | 2 +- .../codechecker_analyzer/analyzer_context.py | 50 +++++++++++++------ .../analyzers/analyzer_base.py | 23 ++++----- .../analyzers/analyzer_types.py | 12 ++--- .../analyzers/clangsa/analyzer.py | 14 ++++-- .../analyzers/clangsa/ctu_manager.py | 3 +- .../analyzers/clangsa/version.py | 2 +- .../analyzers/clangtidy/analyzer.py | 12 +++-- .../analyzers/cppcheck/analyzer.py | 8 +-- .../analyzers/gcc/analyzer.py | 8 +-- .../codechecker_analyzer/cmd/analyzers.py | 3 +- analyzer/codechecker_analyzer/cmd/fixit.py | 6 ++- analyzer/codechecker_analyzer/host_check.py | 21 +++++--- analyzer/tests/unit/test_env_var.py | 7 ++- 14 files changed, 102 insertions(+), 69 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzer.py b/analyzer/codechecker_analyzer/analyzer.py index 20b40d06c1..878f10be29 100644 --- a/analyzer/codechecker_analyzer/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzer.py @@ -247,7 +247,7 @@ def perform_analysis(args, skip_handlers, rs_handler: ReviewStatusHandler, enabled_checkers[analyzer].append(check) version = analyzer_types.supported_analyzers[analyzer] \ - .get_binary_version(context.get_analyzer_env(analyzer)) + .get_binary_version() metadata_info['analyzer_statistics']['version'] = version metadata_tool['analyzers'][analyzer] = metadata_info diff --git a/analyzer/codechecker_analyzer/analyzer_context.py b/analyzer/codechecker_analyzer/analyzer_context.py index 337f9c1f75..16babf7b89 100644 --- a/analyzer/codechecker_analyzer/analyzer_context.py +++ b/analyzer/codechecker_analyzer/analyzer_context.py @@ -21,6 +21,7 @@ from codechecker_common.checker_labels import CheckerLabels from codechecker_common.singleton import Singleton from codechecker_common.util import load_json +from pathlib import Path from . import env @@ -62,8 +63,13 @@ def __init__(self): self.__package_build_date = None self.__package_git_hash = None self.__analyzers = {} - self.__analyzer_envs = {} + + # CodeChecker's current runtime environment self.__cc_env = None + # cc_env extended with packaged LD_LIBRARY_PATH for packaged binaries + self.__package_env = None + # Original caller environment of CodeChecker for external binaries + self.__original_env = None self.logger_lib_dir_path = os.path.join( self._data_files_dir_path, 'ld_logger', 'lib') @@ -155,6 +161,9 @@ def __init_env(self): self.env_vars['cc_logger_compiles']) self.ld_preload = os.environ.get(self.env_vars['ld_preload']) self.ld_lib_path = self.env_vars['env_ld_lib_path'] + self.__original_env = env.get_original_env() + self.__package_env = env.extend(self.path_env_extra, + self.ld_lib_path_extra) def __set_version(self): """ @@ -186,6 +195,29 @@ def __set_version(self): logger.DEBUG_ANALYZER): self.__package_git_tag = package_git_dirtytag + def get_env_for_bin(self, binary): + """ + binary must be a binary with full path + + Returns the correct environment for binaries called by CodeChecker. + For binaries packaged with CodeChecker the LD_LIBRARY path is extended. + For non-packaged binaries, the original calling environment + is returned. + """ + bin_path = Path(binary).resolve() + if not bin_path.exists(): + LOG.error("Binary %s not found", binary) + return None + + codechecker_dir = Path(self._data_files_dir_path) + + if str(bin_path).startswith(str(codechecker_dir)): + LOG.debug("Package env is returned for %s", bin_path) + return self.__package_env + else: + LOG.debug("Original env is returned for %s", bin_path) + return self.__original_env + def __populate_analyzers(self): """ Set analyzer binaries for each registered analyzers. """ cc_env = None @@ -198,9 +230,8 @@ def __populate_analyzers(self): compiler_binaries = self.pckg_layout.get('analyzers') for name, value in compiler_binaries.items(): if name in env_var_bin: - # For non-packaged analyzers the original env is set. + # env_var_bin has priority over package config and PATH self.__analyzers[name] = env_var_bin[name] - self.__analyzer_envs[name] = env.get_original_env() continue if analyzer_from_path: @@ -210,10 +241,6 @@ def __populate_analyzers(self): # Check if it is a package relative path. self.__analyzers[name] = os.path.join( self._data_files_dir_path, value) - # For packaged analyzers the ld_library path - # must be extended with the packed libs. - self.__analyzer_envs[name] =\ - env.extend(self.path_env_extra, self.ld_lib_path_extra) else: env_path = cc_env['PATH'] if cc_env else None compiler_binary = which(cmd=value, path=env_path) @@ -224,17 +251,12 @@ def __populate_analyzers(self): continue self.__analyzers[name] = os.path.realpath(compiler_binary) - # For non-packaged analyzers the original env is set. - self.__analyzer_envs[name] = env.get_original_env() # If the compiler binary is a simlink to ccache, use the # original compiler binary. if self.__analyzers[name].endswith("/ccache"): self.__analyzers[name] = compiler_binary - def get_analyzer_env(self, analyzer_name): - return self.__analyzer_envs.get(analyzer_name) - def __populate_replacer(self): """ Set clang-apply-replacements tool. """ replacer_binary = self.pckg_layout.get('clang-apply-replacements') @@ -243,12 +265,8 @@ def __populate_replacer(self): # Check if it is a package relative path. self.__replacer = os.path.join(self._data_files_dir_path, replacer_binary) - self.__analyzer_envs['clang-apply-replacements'] =\ - env.extend(self.path_env_extra, self.ld_lib_path_extra) else: self.__replacer = which(replacer_binary) - self.__analyzer_envs['clang-apply-replacements'] =\ - env.get_original_env() @property def version(self): diff --git a/analyzer/codechecker_analyzer/analyzers/analyzer_base.py b/analyzer/codechecker_analyzer/analyzers/analyzer_base.py index f9c02cbe26..a510db4634 100644 --- a/analyzer/codechecker_analyzer/analyzers/analyzer_base.py +++ b/analyzer/codechecker_analyzer/analyzers/analyzer_base.py @@ -58,7 +58,7 @@ def resolve_missing_binary(cls, configured_binary, environ): @classmethod @abstractmethod - def get_binary_version(cls, environ, details=False) -> str: + def get_binary_version(cls, details=False) -> str: """ Return the version number of the binary that CodeChecker found, even if its incompatible. If details is true, additional version information @@ -68,7 +68,7 @@ def get_binary_version(cls, environ, details=False) -> str: raise NotImplementedError("Subclasses should implement this!") @classmethod - def is_binary_version_incompatible(cls, environ) -> Optional[str]: + def is_binary_version_incompatible(cls) -> Optional[str]: """ CodeChecker can only execute certain versions of analyzers. Returns a error object (an optional string). If the return value is @@ -102,7 +102,7 @@ def construct_result_handler(self, buildaction, report_output, """ raise NotImplementedError("Subclasses should implement this!") - def analyze(self, analyzer_cmd, res_handler, proc_callback=None, env=None): + def analyze(self, analyzer_cmd, res_handler, proc_callback=None): """ Run the analyzer. """ @@ -111,17 +111,12 @@ def analyze(self, analyzer_cmd, res_handler, proc_callback=None, env=None): LOG.debug_analyzer('\n%s', ' '.join([shlex.quote(x) for x in analyzer_cmd])) - if env is None: - env = analyzer_context.get_context()\ - .get_analyzer_env(self.ANALYZER_NAME) - res_handler.analyzer_cmd = analyzer_cmd try: ret_code, stdout, stderr \ = SourceAnalyzer.run_proc(analyzer_cmd, res_handler.buildaction.directory, - proc_callback, - env) + proc_callback) res_handler.analyzer_returncode = ret_code res_handler.analyzer_stdout = stdout res_handler.analyzer_stderr = stderr @@ -145,7 +140,7 @@ def post_analyze(self, result_handler): """ @staticmethod - def run_proc(command, cwd=None, proc_callback=None, env=None): + def run_proc(command, cwd=None, proc_callback=None): """ Just run the given command and return the return code and the stdout and stderr outputs of the process. @@ -161,11 +156,11 @@ def signal_handler(signum, _): signal.signal(signal.SIGINT, signal_handler) - if env is None: - env = analyzer_context.get_context().cc_env + env = analyzer_context.get_context().get_env_for_bin(command[0]) - LOG.debug_analyzer('\nENV:\n') - LOG.debug_analyzer(env) + LOG.debug('\nexecuting:%s\n', command) + LOG.debug('\nENV:\n') + LOG.debug(env) proc = subprocess.Popen( command, diff --git a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py index 22e588b9ad..a8bbfc93a3 100644 --- a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py +++ b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py @@ -105,8 +105,8 @@ def is_ignore_conflict_supported(): stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=context - .get_analyzer_env( - os.path.basename(context.replacer_binary)), + .get_env_for_bin( + context.replacer_binary), encoding="utf-8", errors="ignore") out, _ = proc.communicate() return '--ignore-insert-conflict' in out @@ -159,7 +159,6 @@ def check_supported_analyzers(analyzers): """ context = analyzer_context.get_context() - check_env = context.cc_env analyzer_binaries = context.analyzer_binaries @@ -182,7 +181,8 @@ def check_supported_analyzers(analyzers): elif not os.path.isabs(analyzer_bin): # If the analyzer is not in an absolute path, try to find it... found_bin = supported_analyzers[analyzer_name].\ - resolve_missing_binary(analyzer_bin, check_env) + resolve_missing_binary(analyzer_bin, + context.get_env_for_bin(analyzer_bin)) # found_bin is an absolute path, an executable in one of the # PATH folders. @@ -201,7 +201,7 @@ def check_supported_analyzers(analyzers): # Check version compatibility of the analyzer binary. if analyzer_bin: analyzer = supported_analyzers[analyzer_name] - error = analyzer.is_binary_version_incompatible(check_env) + error = analyzer.is_binary_version_incompatible() if error: failed_analyzers.add((analyzer_name, f"Incompatible version: {error} " @@ -211,7 +211,7 @@ def check_supported_analyzers(analyzers): available_analyzer = False if not analyzer_bin or \ - not host_check.check_analyzer(analyzer_bin, check_env): + not host_check.check_analyzer(analyzer_bin): # Analyzers unavailable under absolute paths are deliberately a # configuration problem. failed_analyzers.add((analyzer_name, diff --git a/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py index c4d2201228..d31a1ce40c 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py @@ -52,7 +52,7 @@ def parse_clang_help_page( command, stderr=subprocess.STDOUT, env=analyzer_context.get_context() - .get_analyzer_env(ClangSA.ANALYZER_NAME), + .get_env_for_bin(command[0]), universal_newlines=True, encoding="utf-8", errors="ignore") @@ -172,8 +172,11 @@ def __add_plugin_load_flags(cls, analyzer_cmd: List[str]): analyzer_cmd.extend(["-load", plugin]) @classmethod - def get_binary_version(cls, environ, details=False) -> str: + def get_binary_version(cls, details=False) -> str: # No need to LOG here, we will emit a warning later anyway. + + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) if not cls.analyzer_binary(): return None @@ -209,7 +212,7 @@ def ctu_capability(cls): cls.__ctu_autodetection = CTUAutodetection( cls.analyzer_binary(), analyzer_context.get_context() - .get_analyzer_env(ClangSA.ANALYZER_NAME)) + .get_env_for_bin(cls.analyzer_binary())) return cls.__ctu_autodetection @@ -587,7 +590,7 @@ def resolve_missing_binary(cls, configured_binary, environ): return clang @classmethod - def is_binary_version_incompatible(cls, environ): + def is_binary_version_incompatible(cls): """ We support pretty much every ClangSA version. """ @@ -609,7 +612,8 @@ def construct_result_handler(self, buildaction, report_output, def construct_config_handler(cls, args): context = analyzer_context.get_context() - environ = context.get_analyzer_env(ClangSA.ANALYZER_NAME) + environ = context.get_env_for_bin( + cls.analyzer_binary()) handler = config_handler.ClangSAConfigHandler(environ) diff --git a/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_manager.py b/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_manager.py index 77caae42d9..8002aba2cd 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_manager.py +++ b/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_manager.py @@ -126,11 +126,10 @@ def generate_ast(triple_arch, action, source, config): os.makedirs(ast_dir) except OSError: pass - cmdstr = ' '.join(cmd) LOG.debug_analyzer("Generating AST using '%s'", cmdstr) ret_code, _, err = \ - analyzer_base.SourceAnalyzer.run_proc(cmd, action.directory) + analyzer_base.SourceAnalyzer.run_proc(cmd, action.directory, None) if ret_code != 0: LOG.error("Error generating AST.\n\ncommand:\n\n%s\n\nstderr:\n\n%s", diff --git a/analyzer/codechecker_analyzer/analyzers/clangsa/version.py b/analyzer/codechecker_analyzer/analyzers/clangsa/version.py index 4403f947a0..1b72f2c876 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangsa/version.py +++ b/analyzer/codechecker_analyzer/analyzers/clangsa/version.py @@ -77,7 +77,7 @@ def get(clang_binary): """ compiler_version = subprocess.check_output( [clang_binary, '--version'], - env=analyzer_context.get_context().get_analyzer_env("clangsa"), + env=analyzer_context.get_context().get_env_for_bin(clang_binary), encoding="utf-8", errors="ignore") version_parser = ClangVersionInfoParser(clang_binary) diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index 796b850f22..e6ebac9d25 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -236,8 +236,10 @@ def analyzer_binary(cls): .analyzer_binaries[cls.ANALYZER_NAME] @classmethod - def get_binary_version(cls, environ, details=False) -> str: + def get_binary_version(cls, details=False) -> str: # No need to LOG here, we will emit a warning later anyway. + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) if not cls.analyzer_binary(): return None @@ -271,7 +273,7 @@ def get_analyzer_checkers(cls): return cls.__analyzer_checkers environ = analyzer_context\ - .get_context().get_analyzer_env(cls.ANALYZER_NAME) + .get_context().get_env_for_bin(cls.analyzer_binary()) result = subprocess.check_output( [cls.analyzer_binary(), "-list-checks", "-checks=*"], env=environ, @@ -299,7 +301,7 @@ def get_checker_config(cls): result = subprocess.check_output( [cls.analyzer_binary(), "-dump-config", "-checks=*"], env=analyzer_context.get_context() - .get_analyzer_env(cls.ANALYZER_NAME), + .get_env_for_bin(cls.analyzer_binary()), universal_newlines=True, encoding="utf-8", errors="ignore") @@ -316,7 +318,7 @@ def get_analyzer_config(cls): result = subprocess.check_output( [cls.analyzer_binary(), "-dump-config", "-checks=*"], env=analyzer_context.get_context() - .get_analyzer_env(cls.ANALYZER_NAME), + .get_env_for_bin(cls.analyzer_binary()), universal_newlines=True, encoding="utf-8", errors="ignore") @@ -567,7 +569,7 @@ def resolve_missing_binary(cls, configured_binary, environ): return clangtidy @classmethod - def is_binary_version_incompatible(cls, environ): + def is_binary_version_incompatible(cls): """ We support pretty much every Clang-Tidy version. """ diff --git a/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py b/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py index e775becaab..12db634ef9 100644 --- a/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py @@ -82,9 +82,11 @@ def analyzer_binary(cls): .analyzer_binaries[cls.ANALYZER_NAME] @classmethod - def get_binary_version(cls, environ, details=False) -> str: + def get_binary_version(cls, details=False) -> str: """ Get analyzer version information. """ # No need to LOG here, we will emit a warning later anyway. + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) if not cls.analyzer_binary(): return None version = [cls.analyzer_binary(), '--version'] @@ -324,11 +326,11 @@ def resolve_missing_binary(cls, configured_binary, environ): return cppcheck @classmethod - def is_binary_version_incompatible(cls, environ): + def is_binary_version_incompatible(cls): """ Check the version compatibility of the given analyzer binary. """ - analyzer_version = cls.get_binary_version(environ) + analyzer_version = cls.get_binary_version() # The analyzer version should be above 1.80 because '--plist-output' # argument was introduced in this release. diff --git a/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py b/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py index 965d84a739..6ed3b15352 100644 --- a/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py @@ -149,10 +149,12 @@ def resolve_missing_binary(cls, configured_binary, environ): # TODO @classmethod - def get_binary_version(cls, environ, details=False) -> str: + def get_binary_version(cls, details=False) -> str: """ Return the analyzer version. """ + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) # No need to LOG here, we will emit a warning later anyway. if not cls.analyzer_binary(): return None @@ -174,11 +176,11 @@ def get_binary_version(cls, environ, details=False) -> str: return None @classmethod - def is_binary_version_incompatible(cls, environ): + def is_binary_version_incompatible(cls): """ Check the version compatibility of the given analyzer binary. """ - analyzer_version = cls.get_binary_version(environ) + analyzer_version = cls.get_binary_version() if analyzer_version is None: return "GCC binary is too old to support -dumpfullversion." diff --git a/analyzer/codechecker_analyzer/cmd/analyzers.py b/analyzer/codechecker_analyzer/cmd/analyzers.py index 4f296187b7..26d0ddba3b 100644 --- a/analyzer/codechecker_analyzer/cmd/analyzers.py +++ b/analyzer/codechecker_analyzer/cmd/analyzers.py @@ -186,8 +186,7 @@ def uglify(text): rows = [] for analyzer_name, analyzer_class in \ analyzer_types.supported_analyzers.items(): - check_env = context.get_analyzer_env(analyzer_name) - version = analyzer_class.get_binary_version(check_env) + version = analyzer_class.get_binary_version() if not version: version = 'NOT FOUND' diff --git a/analyzer/codechecker_analyzer/cmd/fixit.py b/analyzer/codechecker_analyzer/cmd/fixit.py index 33bcd3d020..9ed9d45b8e 100644 --- a/analyzer/codechecker_analyzer/cmd/fixit.py +++ b/analyzer/codechecker_analyzer/cmd/fixit.py @@ -285,10 +285,14 @@ def apply_process(out_dir): """ Execute clang-apply-replacements binary. """ + context = analyzer_context.get_context() + replacer_env = context.get_env_for_bin( + analyzer_context.get_context().replacer_binary) subprocess.Popen([ analyzer_context.get_context().replacer_binary, *ignore_flag, - out_dir]).communicate() + out_dir], + env=replacer_env).communicate() not_existing_files = set() existing_files = set() diff --git a/analyzer/codechecker_analyzer/host_check.py b/analyzer/codechecker_analyzer/host_check.py index 494818d742..4456f908c4 100644 --- a/analyzer/codechecker_analyzer/host_check.py +++ b/analyzer/codechecker_analyzer/host_check.py @@ -21,24 +21,28 @@ LOG = get_logger('analyzer') -def check_analyzer(compiler_bin, env): +def check_analyzer(compiler_bin): """ Simple check if clang is available. """ clang_version_cmd = [compiler_bin, '--version'] LOG.debug_analyzer(' '.join(clang_version_cmd)) + environ = analyzer_context.get_context().get_env_for_bin( + compiler_bin) try: - res = subprocess.call( + proc = subprocess.Popen( clang_version_cmd, - env=env, + env=environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", errors="ignore") - if not res: + out, err = proc.communicate() + if not proc.returncode: return True - - LOG.debug_analyzer('Failed to run: "%s"', ' '.join(clang_version_cmd)) + LOG.error('Failed to run: "%s"', ' '.join(clang_version_cmd)) + LOG.error('stdout: %s', out) + LOG.error('stderr: %s', err) return False except OSError as oerr: @@ -53,13 +57,14 @@ def has_analyzer_config_option(clang_bin, config_option_name): cmd = [clang_bin, "-cc1", "-analyzer-config-help"] LOG.debug('run: "%s"', ' '.join(cmd)) + context = analyzer_context.get_context() try: proc = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - env=analyzer_context.get_context().get_analyzer_env("clangsa"), + env=context.get_env_for_bin(clang_bin), encoding="utf-8", errors="ignore") out, err = proc.communicate() LOG.debug("stdout:\n%s", out) @@ -92,7 +97,7 @@ def has_analyzer_option(clang_bin, feature): cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - env=analyzer_context.get_context().get_analyzer_env("clangsa"), + env=analyzer_context.get_context().get_env_for_bin(clang_bin), encoding="utf-8", errors="ignore") out, err = proc.communicate() LOG.debug("stdout:\n%s", out) diff --git a/analyzer/tests/unit/test_env_var.py b/analyzer/tests/unit/test_env_var.py index 6531c1a330..ebf24c4477 100644 --- a/analyzer/tests/unit/test_env_var.py +++ b/analyzer/tests/unit/test_env_var.py @@ -139,17 +139,20 @@ def test_cc_analyzer_internal_env(self): lcfg_dict = context._Context__get_package_layout() context._data_files_dir_path = data_files_dir context.pckg_layout = lcfg_dict['runtime'] + context._Context__init_env() context._Context__populate_analyzers() # clang-19 is part of the codechecker package # so the internal package lib should be in the ld_library_path - clang_env = context.get_analyzer_env("clangsa") + clang_env = context.get_env_for_bin( + context.analyzer_binaries["clangsa"]) env_txt = str(clang_env) self.assertTrue(env_txt.find("internal_package_lib") != -1) # clang-tidy is not part of the codechecker package # so internal package lib should not be in the ld_library_path - clang_env = context.get_analyzer_env("clang-tidy") + clang_env = context.get_env_for_bin( + context.analyzer_binaries["clang-tidy"]) env_txt = str(clang_env) self.assertTrue(env_txt.find("internal_package_lib") == -1) From 469a14ef0da797e282fa2cf7b4a8077349aee2fe Mon Sep 17 00:00:00 2001 From: Daniel Krupp Date: Wed, 11 Sep 2024 07:39:59 +0200 Subject: [PATCH 3/6] Don't query binary version if analyzer binary is not found Don't print missing analyzer warning unless the analyzer list is explicitly provided --- analyzer/codechecker_analyzer/analyzer.py | 3 ++- analyzer/codechecker_analyzer/analyzers/analyzer_types.py | 2 +- .../codechecker_analyzer/analyzers/clangtidy/analyzer.py | 4 ++-- analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py | 4 ++-- analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py | 4 ++-- analyzer/codechecker_analyzer/cmd/checkers.py | 5 ++++- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzer.py b/analyzer/codechecker_analyzer/analyzer.py index 878f10be29..9b83037315 100644 --- a/analyzer/codechecker_analyzer/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzer.py @@ -355,7 +355,8 @@ def perform_analysis(args, skip_handlers, rs_handler: ReviewStatusHandler, end_time = time.time() LOG.info("Analysis length: %s sec.", end_time - start_time) - analyzer_types.print_unsupported_analyzers(errored) + if args.analyzers: + analyzer_types.print_unsupported_analyzers(errored) metadata_tool['timestamps'] = {'begin': start_time, 'end': end_time} diff --git a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py index a8bbfc93a3..130288c728 100644 --- a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py +++ b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py @@ -115,7 +115,7 @@ def is_ignore_conflict_supported(): def print_unsupported_analyzers(errored): """ Print error messages which occured during analyzer detection. """ for analyzer_binary, reason in errored: - LOG.warning("Analyzer '%s' is enabled but CodeChecker is failed to " + LOG.warning("Analyzer '%s' is enabled but CodeChecker failed to " "execute analysis with it: '%s'. Please check your " "'PATH' environment variable and the " "'config/package_layout.json' file!", diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index e6ebac9d25..a6a6e17da6 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -237,11 +237,11 @@ def analyzer_binary(cls): @classmethod def get_binary_version(cls, details=False) -> str: + if not cls.analyzer_binary(): + return None # No need to LOG here, we will emit a warning later anyway. environ = analyzer_context.get_context().get_env_for_bin( cls.analyzer_binary()) - if not cls.analyzer_binary(): - return None version = [cls.analyzer_binary(), '--version'] try: diff --git a/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py b/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py index 12db634ef9..efd4c2eef9 100644 --- a/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py @@ -85,10 +85,10 @@ def analyzer_binary(cls): def get_binary_version(cls, details=False) -> str: """ Get analyzer version information. """ # No need to LOG here, we will emit a warning later anyway. - environ = analyzer_context.get_context().get_env_for_bin( - cls.analyzer_binary()) if not cls.analyzer_binary(): return None + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) version = [cls.analyzer_binary(), '--version'] try: output = subprocess.check_output(version, diff --git a/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py b/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py index 6ed3b15352..505194353f 100644 --- a/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py @@ -153,11 +153,11 @@ def get_binary_version(cls, details=False) -> str: """ Return the analyzer version. """ - environ = analyzer_context.get_context().get_env_for_bin( - cls.analyzer_binary()) # No need to LOG here, we will emit a warning later anyway. if not cls.analyzer_binary(): return None + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) if details: version = [cls.analyzer_binary(), '--version'] else: diff --git a/analyzer/codechecker_analyzer/cmd/checkers.py b/analyzer/codechecker_analyzer/cmd/checkers.py index 0ca603e48b..c567870497 100644 --- a/analyzer/codechecker_analyzer/cmd/checkers.py +++ b/analyzer/codechecker_analyzer/cmd/checkers.py @@ -555,7 +555,10 @@ def __print_checker_config(args: argparse.Namespace): if rows: print(twodim.to_str(args.output_format, header, rows)) - analyzer_types.print_unsupported_analyzers(errored) + # Don't print this warning unless the analyzer list is + # given by the user. + if args.analyzers: + analyzer_types.print_unsupported_analyzers(errored) if analyzer_failures: LOG.error("Failed to get checker configuration options for '%s' " From 8c5a8cffcb7bdac1e7c9c39809277e480ff78975 Mon Sep 17 00:00:00 2001 From: bruntib Date: Thu, 12 Sep 2024 13:05:29 +0200 Subject: [PATCH 4/6] [fix] Forwarding --ctu-ast-mode to analyze command --- analyzer/codechecker_analyzer/cmd/check.py | 1 + 1 file changed, 1 insertion(+) diff --git a/analyzer/codechecker_analyzer/cmd/check.py b/analyzer/codechecker_analyzer/cmd/check.py index c9fe820501..e654755f8f 100644 --- a/analyzer/codechecker_analyzer/cmd/check.py +++ b/analyzer/codechecker_analyzer/cmd/check.py @@ -892,6 +892,7 @@ def __update_if_key_exists(source, target, key): 'capture_analysis_output', 'generate_reproducer', 'config_file', + 'ctu_ast_mode', 'ctu_phases', 'ctu_reanalyze_on_failure', 'stats_output', From c3d344e777a6803d1fdcbfbca2b09f7221a0206b Mon Sep 17 00:00:00 2001 From: Daniel Krupp Date: Thu, 12 Sep 2024 17:59:29 +0200 Subject: [PATCH 5/6] Configuring the env for some additional tools --- .../analyzers/clangsa/ctu_autodetection.py | 11 ++++++----- .../analyzers/clangtidy/analyzer.py | 8 ++++++-- .../analyzers/cppcheck/analyzer.py | 7 +++++-- .../codechecker_analyzer/analyzers/gcc/analyzer.py | 8 +++++++- analyzer/codechecker_analyzer/cmd/analyzers.py | 8 ++++++-- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_autodetection.py b/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_autodetection.py index dacf46fa90..d418b45419 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_autodetection.py +++ b/analyzer/codechecker_analyzer/analyzers/clangsa/ctu_autodetection.py @@ -13,6 +13,7 @@ import subprocess from codechecker_common.logger import get_logger +from codechecker_analyzer import analyzer_context from codechecker_analyzer import host_check from codechecker_analyzer.analyzers.clangsa import version @@ -75,7 +76,7 @@ def ctu_mapping(clang_version_info): return None, None -def invoke_binary_checked(binary_path, args=None, environ=None): +def invoke_binary_checked(binary_path, args=None): """ Invoke the binary with the specified args, and return the output if the command finished running with zero exit code. Return False otherwise. @@ -91,6 +92,7 @@ def invoke_binary_checked(binary_path, args=None, environ=None): args = args or [] invocation = [binary_path] invocation.extend(args) + environ = analyzer_context.get_context().get_env_for_bin(binary_path) try: output = subprocess.check_output( invocation, @@ -123,7 +125,7 @@ def __init__(self, analyzer_binary, environ): return analyzer_version = invoke_binary_checked( - self.__analyzer_binary, ['--version'], self.environ) + self.__analyzer_binary, ['--version']) if analyzer_version is False: LOG.debug('Failed to invoke command to get Clang version!') @@ -222,7 +224,7 @@ def is_ctu_capable(self): if not tool_path: return False - return invoke_binary_checked(tool_path, ['-version'], self.environ) \ + return invoke_binary_checked(tool_path, ['-version']) \ is not False @property @@ -233,8 +235,7 @@ def is_on_demand_ctu_available(self): """ analyzer_options = invoke_binary_checked( - self.__analyzer_binary, ['-cc1', '-analyzer-config-help'], - self.environ) + self.__analyzer_binary, ['-cc1', '-analyzer-config-help']) if analyzer_options is False: return False diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index a6a6e17da6..0bbb976f9d 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -142,11 +142,12 @@ def get_diagtool_bin(): return None -def get_warnings(environment=None): +def get_warnings(): """ Returns list of warning flags by using diagtool. """ diagtool_bin = get_diagtool_bin() + environment = analyzer_context.get_context().get_env_for_bin(diagtool_bin) if not diagtool_bin: return [] @@ -284,7 +285,7 @@ def get_analyzer_checkers(cls): checker_description.extend( ("clang-diagnostic-" + warning, "") - for warning in get_warnings(environ)) + for warning in get_warnings()) cls.__analyzer_checkers = checker_description @@ -314,6 +315,9 @@ def get_analyzer_config(cls): """ Return the analyzer configuration with all checkers enabled. """ + if not cls.analyzer_binary(): + return [] + try: result = subprocess.check_output( [cls.analyzer_binary(), "-dump-config", "-checks=*"], diff --git a/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py b/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py index efd4c2eef9..4ad42a296e 100644 --- a/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py @@ -244,10 +244,13 @@ def get_analyzer_checkers(cls): """ Return the list of the supported checkers. """ + if not cls.analyzer_binary(): + return [] command = [cls.analyzer_binary(), "--errorlist"] - + environ = analyzer_context.get_context().get_env_for_bin( + command[0]) try: - result = subprocess.check_output(command) + result = subprocess.check_output(command, env=environ) return parse_checkers(result) except (subprocess.CalledProcessError) as e: LOG.error(e.stderr) diff --git a/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py b/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py index 505194353f..d99e60cf5b 100644 --- a/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/gcc/analyzer.py @@ -55,6 +55,8 @@ def construct_analyzer_cmd(self, result_handler): # unforeseen exceptions where a general catch is justified? config = self.config_handler + if not Gcc.analyzer_binary(): + return None # We don't want GCC do start linking, but -fsyntax-only stops the # compilation process too early for proper diagnostics generation. analyzer_cmd = [Gcc.analyzer_binary(), '-fanalyzer', '-c', @@ -91,10 +93,14 @@ def get_analyzer_checkers(cls): Return the list of the supported checkers. """ command = [cls.analyzer_binary(), "--help=warning"] + if not cls.analyzer_binary(): + return [] + environ = analyzer_context.get_context().get_env_for_bin( + command[0]) checker_list = [] try: - output = subprocess.check_output(command) + output = subprocess.check_output(command, env=environ) # Still contains the help message we need to remove. for entry in output.decode().split('\n'): diff --git a/analyzer/codechecker_analyzer/cmd/analyzers.py b/analyzer/codechecker_analyzer/cmd/analyzers.py index 26d0ddba3b..e235a08234 100644 --- a/analyzer/codechecker_analyzer/cmd/analyzers.py +++ b/analyzer/codechecker_analyzer/cmd/analyzers.py @@ -118,10 +118,13 @@ def main(args): if args.dump_config: binary = context.analyzer_binaries.get(args.dump_config) + environ = analyzer_context.get_context().get_env_for_bin( + binary) if args.dump_config == 'clang-tidy': subprocess.call([binary, '-dump-config', '-checks=*'], - encoding="utf-8", errors="ignore") + encoding="utf-8", errors="ignore", + env=environ) elif args.dump_config == 'clangsa': ret = subprocess.call([binary, '-cc1', @@ -129,7 +132,8 @@ def main(args): '-analyzer-checker-option-help-alpha'], stderr=subprocess.PIPE, encoding="utf-8", - errors="ignore") + errors="ignore", + env=environ) if ret: # This flag is supported from Clang 9. From cbb3b7ba042093429e6f787960f04f41adc864e4 Mon Sep 17 00:00:00 2001 From: bruntib Date: Thu, 12 Sep 2024 18:10:27 +0200 Subject: [PATCH 6/6] [cmd] Display warning instead of debug log for missing diagtool --- .../codechecker_analyzer/analyzers/clangtidy/analyzer.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index 796b850f22..6418a7fdb3 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -136,8 +136,9 @@ def get_diagtool_bin(): if os.path.exists(diagtool_bin): return diagtool_bin - LOG.debug("'diagtool' can not be found next to the clang binary (%s)!", - clang_bin) + LOG.warning( + "'diagtool' can not be found next to the clang binary (%s)!", + clang_bin) return None