From ff23b2b41c0c99c7e767e5d65be27a9d4dc2f0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Rinc=C3=B3n=20Blanco?= Date: Mon, 3 Jun 2024 16:54:50 +0200 Subject: [PATCH] Improve cc version detection (#16362) * Improve cc version detection * Add more cases --- conan/internal/api/detect_api.py | 11 +++++++++-- test/unittests/util/detect_test.py | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/conan/internal/api/detect_api.py b/conan/internal/api/detect_api.py index aebad6e726c..04bb3ab16fa 100644 --- a/conan/internal/api/detect_api.py +++ b/conan/internal/api/detect_api.py @@ -438,8 +438,15 @@ def _cc_compiler(compiler_exe="cc"): if ret != 0: return None, None, None compiler = "clang" if "clang" in out else "gcc" - installed_version = re.search(r"([0-9]+(\.[0-9])?)", out).group() - if installed_version: + # clang and gcc have version after a space, first try to find that to skip extra numbers + # that might appear in the first line of the output before the version + installed_version = re.search(r" ([0-9]+(\.[0-9])+)", out) + # Try only major but with spaces next + installed_version = installed_version or re.search(r" ([0-9]+(\.[0-9])?)", out) + # Fallback to the first number we find optionally followed by other version fields + installed_version = installed_version or re.search(r"([0-9]+(\.[0-9])?)", out) + if installed_version and installed_version.group(): + installed_version = installed_version.group() ConanOutput(scope="detect_api").info("Found cc=%s-%s" % (compiler, installed_version)) return compiler, Version(installed_version), compiler_exe except (Exception,): # to disable broad-except diff --git a/test/unittests/util/detect_test.py b/test/unittests/util/detect_test.py index 28b004230c7..1ac0e59a94f 100644 --- a/test/unittests/util/detect_test.py +++ b/test/unittests/util/detect_test.py @@ -1,8 +1,11 @@ import unittest import mock +from unittest.mock import patch +import pytest from parameterized import parameterized +from conan.internal.api.detect_api import _cc_compiler from conans.client.conf.detect import detect_defaults_settings from conans.model.version import Version from conan.test.utils.mocks import RedirectedTestOutput @@ -56,3 +59,18 @@ def test_detect_clang_gcc_toolchain(self, _): with environment_update({"CC": "clang-9 --gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/9"}): detect_defaults_settings() self.assertIn("CC and CXX: clang-9 --gcc-toolchain", output) + + +@pytest.mark.parametrize("version_return,expected_version", [ + ["cc.exe (Rev3, Built by MSYS2 project) 14.1.0", "14.1.0"], + ["g++ (Conan-Build-gcc--binutils-2.42) 14.1.0", "14.1.0"], + ["clang version 18.1.0rc (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18.1.0"], + ["cc.exe (Rev3, Built by MSYS2 project) 14.0", "14.0"], + ["clang version 18 (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18"], + ["cc.exe (Rev3, Built by MSYS2 project) 14", "14"], +]) +@patch("conan.internal.api.detect_api.detect_runner") +def test_detect_cc_versionings(detect_runner_mock, version_return, expected_version): + detect_runner_mock.return_value = 0, version_return + compiler, installed_version, compiler_exe = _cc_compiler() + assert installed_version == Version(expected_version)