Skip to content

Commit

Permalink
detect msvc and version when CC/CXX point to cl.exe (#14364)
Browse files Browse the repository at this point in the history
* add test_profile_new_msvc_vcvars

* detect msvc version from cl.exe
  • Loading branch information
jcar87 authored Aug 2, 2023
1 parent 0ad3bd7 commit 05947c5
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
22 changes: 22 additions & 0 deletions conans/client/conf/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ def _gcc_compiler(compiler_exe="gcc"):
return compiler, installed_version
except Exception:
return None

def _msvc_cl_compiler(compiler_exe="cl"):
try:
compiler_exe = compiler_exe.strip('"')
ret, out = detect_runner(f'"{compiler_exe}" /?')
if ret != 0:
return None
first_line = out.splitlines()[0]
if not "Microsoft" in first_line:
return None
compiler = "msvc"
version_regex = re.search(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.([0-9]+)\.?([0-9]+)?", first_line)
if not version_regex:
return None
# 19.36.32535 -> 193
version = f"{version_regex.group('major')}{version_regex.group('minor')[0]}"
return (compiler, version)
except Exception:
return None


def _clang_compiler(compiler_exe="clang"):
Expand Down Expand Up @@ -96,6 +115,9 @@ def _get_default_compiler():
return gcc
if platform.system() == "SunOS" and command.lower() == "cc":
return _sun_cc_compiler(command)
if platform.system() == "Windows" and command.rstrip('"').endswith(("cl", "cl.exe")) and not "clang" in command:
return _msvc_cl_compiler(command)

# I am not able to find its version
output.error("Not able to automatically detect '%s' version" % command)
return None
Expand Down
25 changes: 24 additions & 1 deletion conans/test/functional/command/profile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from conans.util.env import environment_update
from conans.util.files import save
from conans.util.runners import check_output_runner

from conan.tools.microsoft.visual import vcvars_command

class TestProfile(unittest.TestCase):

Expand Down Expand Up @@ -128,3 +128,26 @@ def test_profile_new(self):
assert "MyProfile2' already exists" in c.out

c.run("profile detect --name=./MyProfile2 --force") # will not raise error

@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows and msvc")
def test_profile_new_msvc_vcvars(self):
c = TestClient()

# extract location of cl.exe from vcvars
vcvars = vcvars_command(version="15", architecture="x64")
ret = c.run_command(f"{vcvars} && where cl.exe")
assert ret == 0
cl_executable = c.out.splitlines()[-1]
assert os.path.isfile(cl_executable)
cl_location = os.path.dirname(cl_executable)

# Try different variations, including full path and full path with quotes
for var in ["cl", "cl.exe", cl_executable, f'"{cl_executable}"']:
output = RedirectedTestOutput()
with redirect_output(output):
with environment_update({"CC": var, "PATH": cl_location}):
c.run("profile detect --name=./cl-profile --force")

profile = c.load("cl-profile")
assert "compiler=msvc" in profile
assert "compiler.version=191" in profile

0 comments on commit 05947c5

Please sign in to comment.