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

2231 conan compiler detection #2487

Merged
merged 14 commits into from
Feb 26, 2018
Merged
Show file tree
Hide file tree
Changes from 13 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
18 changes: 17 additions & 1 deletion conans/client/conf/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ def _execute(command):


def _gcc_compiler(output, compiler_exe="gcc"):

try:
if platform.system() == "Darwin":
# In Mac OS X check if gcc is a fronted using apple-clang
_, out = _execute("%s --version" % compiler_exe)
out = out.lower()
if "clang" in out:
return None

_, out = _execute('%s -dumpversion' % compiler_exe)
compiler = "gcc"
installed_version = re.search("([0-9](\.[0-9])?)", out).group()
Expand Down Expand Up @@ -147,7 +155,15 @@ def _get_default_compiler(output):
output.info("CC and CXX: %s, %s " % (cc or "None", cxx or "None"))
command = cc or cxx
if "gcc" in command:
return _gcc_compiler(output, command)
gcc = _gcc_compiler(output, command)
if platform.system() == "Darwin" and gcc is None:
output.warn(
"%s detected as a frontend using apple-clang, skipping it to use native apple-clang" % command
)
# Fallback to use clang instead
command = "clang"
Copy link
Member

Choose a reason for hiding this comment

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

I still think this is a weird outcome. So you defined that your CC=gcc, still conan is detecting and defaulting your profile to clang compiler? I think it is safer to just leave the compiler None for this case, so it will fail fast, instead of lots of potential mismatches between the default profile and the declared default compiler CC.

Copy link
Contributor Author

@pvicente pvicente Feb 26, 2018

Choose a reason for hiding this comment

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

@memsharded this is your comment 5 days ago (Ok, makes sense) so I've just left it to use as default clang in case the problem is detected (gcc as a fronted of apple-clang)

memsharded 5 days ago Owner
I am not sure we want to fallback to clang. Because if the env-var CC and CXX are set to gcc, >then, typically CMake will use them when running, and the user might not notice, because it >detected "clang" when CC=gcc. What do you think @lasote?

@lasote
lasote 4 days ago Owner
I'm ok with this. If the user is messing with CC/CXX is his problem. And the default profile is >just a default.

@memsharded
memsharded 4 days ago Owner
Ok, makes sense

@lasote Anything that I'm missing here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I talked with @memsharded and I changed my mind, it is better to no set a compiler and make more visible that we are not managing this situation with Conan. Not a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lasote @memsharded Ok now conan should display:

16:13 $ CC=gcc conan install libiconv/1.15@bincrafters/stable
Auto detecting your dev setup to initialize the default profile (/Users/pvicente/.conan/profiles/default)
CC and CXX: gcc, None
ERROR: gcc detected as a frontend using apple-clang. Compiler not supported
ERROR: Unable to find a working compiler
Default settings
	os=Macos
	os_build=Macos
	arch=x86_64
	arch_build=x86_64
	build_type=Release
*** You can change them in /Users/pvicente/.conan/profiles/default ***
*** Or override with -s compiler='other' -s ...s***
libiconv/1.15@bincrafters/stable: Not found in local cache, looking in remotes...
libiconv/1.15@bincrafters/stable: Trying with 'conan-center'...
libiconv/1.15@bincrafters/stable: Trying with 'conan-transit'...
....

else:
return gcc
if "clang" in command.lower():
return _clang_compiler(output, command)
if platform.system() == "SunOS" and command.lower() == "cc":
Expand Down
51 changes: 44 additions & 7 deletions conans/test/util/detect_test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,52 @@
import platform
import subprocess
import unittest
from conans.test.utils.tools import TestBufferConanOutput

from conans import tools
from conans.client.conf.detect import detect_defaults_settings
import platform
from conans.test.utils.tools import TestBufferConanOutput


class DetectTest(unittest.TestCase):

def detect_test(self):
def detect_default_compilers_test(self):
platform_default_compilers = {
"Linux": "gcc",
"Darwin": "apple-clang",
"Windows": "Visual Studio"
}
output = TestBufferConanOutput()
result = detect_defaults_settings(output)
if platform.system() == "Linux":
for (name, value) in result:
if name == "compiler":
self.assertEquals(value, "gcc")
# result is a list of tuples (name, value) so converting it to dict
result = dict(result)
platform_compiler = platform_default_compilers.get(platform.system(), None)
if platform_compiler is not None:
self.assertEquals(result.get("compiler", None), platform_compiler)

def detect_default_in_mac_os_using_gcc_as_default_test(self):
"""
Test if gcc in Mac OS X is using apple-clang as frontend
"""
# See: https://github.com/conan-io/conan/issues/2231
if platform.system() != "Darwin":
return

try:
output = subprocess.check_output(["gcc", "--version"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
# gcc is not installed or there is any error (no test scenario)
return

if b"clang" not in output:
# Not test scenario gcc should display clang in output
# see: https://stackoverflow.com/questions/19535422/os-x-10-9-gcc-links-to-clang
raise Exception("Apple gcc doesn't point to clang with gcc frontend anymore! please check")

output = TestBufferConanOutput()
with tools.environment_append({"CC": "gcc"}):
Copy link
Member

@memsharded memsharded Feb 18, 2018

Choose a reason for hiding this comment

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

This test is nice, but is not testing the reported issue. Which is gcc being actually a symlink to clang. It might be difficult to fully automate, so I am fine if tested manually.

Actually it might be testing it, if gcc is not installed in the testing environment as real gcc but as the default clang compiler. But it should check "clang" in the test, shouldn't it?

Copy link
Contributor Author

@pvicente pvicente Feb 19, 2018

Choose a reason for hiding this comment

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

@memsharded Indeed, this test is only executed in MacOS x (Darwin) where gcc command is clang which was the bug report for this issue. In my Mac OS X it's returning

17:06 $ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.38)
Target: x86_64-apple-darwin17.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

I've updated it to make more evident that it should detect apple-clang.

Let me know if it makes sense to you. It looks like in CI we have the same environment gcc reports it's apple-clang.

Copy link
Member

Choose a reason for hiding this comment

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

It is not to make it more evident. It could happen that the CI machine could have gcc really installed in it, and the test would pass without checking for clang output, so it wouldn't test at all the reported bug fix. It is necessary to explicitly check for "apple-clang" in the output

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@memsharded I don't understand what's the problem? @lasote do you know what are we talking about? This test is only executed in Mac OS X and the CI machine for Mac OS X has fake gcc as apple-clang, but if you don't want to rely on this assumption maybe it's better to remove this end2end test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just check the output to confirm that the assumption is true. Because if the assumption change, it is better to know it with a fail test than being happy with a green build and a useless test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I got it, thanks for the explanation. I wasn't getting it, sorry guys!!!

result = detect_defaults_settings(output)
# result is a list of tuples (name, value) so converting it to dict
result = dict(result)
self.assertEquals(result.get("compiler", None), "apple-clang")
self.assertIn("gcc detected as a frontend using apple-clang", output)
self.assertIsNotNone(output.warn)