Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/detect api compilers #16092

Merged
merged 3 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions conan/internal/api/detect_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,50 +361,49 @@ def detect_default_compiler():
output.info("CC and CXX: %s, %s " % (cc or "None", cxx or "None"))
command = cc or cxx
if "clang" in command.lower():
return _clang_compiler(command)
return detect_clang_compiler(command)
if "gnu-cc" in command or "gcc" in command or "g++" in command or "c++" in command:
gcc, gcc_version, compiler_exe = _gcc_compiler(command)
gcc, gcc_version, compiler_exe = detect_gcc_compiler(command)
if platform.system() == "Darwin" and gcc is None:
output.error("%s detected as a frontend using apple-clang. "
"Compiler not supported" % command)
return gcc, gcc_version, compiler_exe
if "icpx" in command or "icx" in command:
intel, intel_version, compiler_exe = _intel_compiler(command)
intel, intel_version, compiler_exe = detect_intel_compiler(command)
return intel, intel_version, compiler_exe
if platform.system() == "SunOS" and command.lower() == "cc":
return _sun_cc_compiler(command)
return detect_suncc_compiler(command)
if (platform.system() == "Windows" and command.rstrip('"').endswith(("cl", "cl.exe"))
and "clang" not in command):
return _msvc_cl_compiler(command)
return detect_cl_compiler(command)

# I am not able to find its version
output.error("Not able to automatically detect '%s' version" % command)
return None, None, None

if platform.system() == "Windows":
version = _detect_vs_ide_version()
version = {"17": "193", "16": "192", "15": "191"}.get(str(version)) # Map to compiler
if version:
return 'msvc', Version(version), None
compiler, version, compiler_exe = detect_msvc_compiler()
if compiler:
return compiler, version, compiler_exe

if platform.system() == "SunOS":
sun_cc, sun_cc_version, compiler_exe = _sun_cc_compiler()
sun_cc, sun_cc_version, compiler_exe = detect_suncc_compiler()
if sun_cc:
return sun_cc, sun_cc_version, compiler_exe

if platform.system() in ["Darwin", "FreeBSD"]:
clang, clang_version, compiler_exe = _clang_compiler() # prioritize clang
clang, clang_version, compiler_exe = detect_clang_compiler() # prioritize clang
if clang:
return clang, clang_version, compiler_exe
return None, None, None
else: # linux like system
compiler, compiler_version, compiler_exe = _cc_compiler()
if compiler:
return compiler, compiler_version, compiler_exe
gcc, gcc_version, compiler_exe = _gcc_compiler()
gcc, gcc_version, compiler_exe = detect_gcc_compiler()
if gcc:
return gcc, gcc_version, compiler_exe
return _clang_compiler()
return detect_clang_compiler()


def default_msvc_ide_version(version):
Expand Down Expand Up @@ -441,7 +440,7 @@ def _cc_compiler():
return None, None, None


def _gcc_compiler(compiler_exe="gcc"):
def detect_gcc_compiler(compiler_exe="gcc"):
try:
if platform.system() == "Darwin":
# In Mac OS X check if gcc is a fronted using apple-clang
Expand Down Expand Up @@ -471,7 +470,7 @@ def detect_compiler():
return compiler, version


def _intel_compiler(compiler_exe="icx"):
def detect_intel_compiler(compiler_exe="icx"):
try:
ret, out = detect_runner("%s --version" % compiler_exe)
if ret != 0:
Expand All @@ -485,7 +484,7 @@ def _intel_compiler(compiler_exe="icx"):
return None, None, None


def _sun_cc_compiler(compiler_exe="cc"):
def detect_suncc_compiler(compiler_exe="cc"):
try:
_, out = detect_runner('%s -V' % compiler_exe)
compiler = "sun-cc"
Expand All @@ -501,7 +500,7 @@ def _sun_cc_compiler(compiler_exe="cc"):
return None, None, None


def _clang_compiler(compiler_exe="clang"):
def detect_clang_compiler(compiler_exe="clang"):
try:
ret, out = detect_runner('%s --version' % compiler_exe)
if ret != 0:
Expand All @@ -520,7 +519,15 @@ def _clang_compiler(compiler_exe="clang"):
return None, None, None


def _msvc_cl_compiler(compiler_exe="cl"):
def detect_msvc_compiler():
version = _detect_vs_ide_version()
version = {"17": "193", "16": "192", "15": "191"}.get(str(version)) # Map to compiler
if version:
return 'msvc', Version(version), None
return None, None, None


def detect_cl_compiler(compiler_exe="cl"):
""" only if CC/CXX env-vars are defined pointing to cl.exe, and the VS environment must
be active to have them in the path
"""
Expand Down
7 changes: 6 additions & 1 deletion conans/test/functional/test_profile_detect_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ def test_profile_detect_compiler(self):

@pytest.mark.skipif(platform.system() != "Linux", reason="Only linux")
def test_profile_detect_libc(self):

client = TestClient()
tpl1 = textwrap.dedent("""
{% set compiler, version, _ = detect_api.detect_gcc_compiler() %}
{% set libc, libc_version = detect_api.detect_libc() %}
[settings]
os=Linux
compiler={{compiler}}
compiler.version={{version}}
[conf]
user.confvar:libc={{libc}}
user.confvar:libc_version={{libc_version}}
Expand All @@ -61,9 +63,12 @@ def test_profile_detect_libc(self):
libc_name, libc_version = detect_api.detect_libc()
assert libc_name is not None
assert libc_version is not None
_, version, _ = detect_api.detect_gcc_compiler()
expected = textwrap.dedent(f"""\
Host profile:
[settings]
compiler=gcc
compiler.version={version}
os=Linux
[conf]
user.confvar:libc={libc_name}
Expand Down
7 changes: 7 additions & 0 deletions conans/test/integration/configuration/test_profile_jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,10 @@ def test_profile_detect_os_arch(self):
os={the_os}
""")
assert expected in client.out


def test_profile_jinja_error():
c = TestClient(light=True)
c.save({"profile1": "{% set kk = other() %}"})
c.run("profile show -pr=profile1", assert_error=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

assert "ERROR: Error while rendering the profile template file" in c.out
4 changes: 2 additions & 2 deletions conans/test/unittests/client/conf/detect/test_gcc_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from parameterized import parameterized


from conan.internal.api.detect_api import _gcc_compiler
from conan.internal.api.detect_api import detect_gcc_compiler


class GCCCompilerTestCase(unittest.TestCase):
Expand All @@ -13,7 +13,7 @@ class GCCCompilerTestCase(unittest.TestCase):
def test_detect_gcc_10(self, version):
with mock.patch("platform.system", return_value="Linux"):
with mock.patch("conan.internal.api.detect_api.detect_runner", return_value=(0, version)):
compiler, installed_version, compiler_exe = _gcc_compiler()
compiler, installed_version, compiler_exe = detect_gcc_compiler()
self.assertEqual(compiler, 'gcc')
self.assertEqual(installed_version, version)
self.assertEqual(compiler_exe, 'gcc')
2 changes: 1 addition & 1 deletion conans/test/unittests/util/detect_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_detect_arch(self, machine, expected_arch):
result = dict(result)
self.assertEqual(expected_arch, result['arch'])

@mock.patch("conan.internal.api.detect_api._clang_compiler",
@mock.patch("conan.internal.api.detect_api.detect_clang_compiler",
return_value=("clang", Version("9"), "clang"))
def test_detect_clang_gcc_toolchain(self, _):
output = RedirectedTestOutput()
Expand Down