-
Notifications
You must be signed in to change notification settings - Fork 1k
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
2231 conan compiler detection #2487
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job. Take a look to my comment.
conans/client/conf/detect.py
Outdated
@@ -146,9 +159,9 @@ def _get_default_compiler(output): | |||
if cc or cxx: # Env defined, use them | |||
output.info("CC and CXX: %s, %s " % (cc or "None", cxx or "None")) | |||
command = cc or cxx | |||
if "gcc" in command: | |||
if _is_real_compiler("gcc", command): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is clearer to get here the output of the "command --help", then "if "gcc" in output:" and "if "clang" in output". The function is real compiler feels a little confusing. Maybe also check the output in lowercase in case GCC or Clang in output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for my comments formatting. I'm with the mobile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agree, I'd think it would be more understandable. I think that @lasote meant command --version
, not --help
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lasote @memsharded do you mean something like this?
if "gcc" in command:
_, out = _execute("%s --version" % command)
if "gcc" in out.lower():
return _gcc_compiler(output, command)
if "clang" in command.lower():
_, out = _execute("%s --version" % command.lower())
if "clang" in out.lower():
return _clang_compiler(output, command)
or:
if "gcc" in command or "clang" in command.lower():
_, out = _execute("%s --version" % command)
out = out.lower()
if "gcc" in out:
return _gcc_compiler(output, command)
if "clang" in out:
return _clang_compiler(output, command)
I would go for 2nd option only one call to _execute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed it with 2nd option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conans/client/conf/detect.py
Outdated
@@ -146,9 +159,9 @@ def _get_default_compiler(output): | |||
if cc or cxx: # Env defined, use them | |||
output.info("CC and CXX: %s, %s " % (cc or "None", cxx or "None")) | |||
command = cc or cxx | |||
if "gcc" in command: | |||
if _is_real_compiler("gcc", command): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agree, I'd think it would be more understandable. I think that @lasote meant command --version
, not --help
.
conans/test/util/detect_test.py
Outdated
def detect_default_in_mac_os_using_gcc_as_default_test(self): | ||
# See: https://github.com/conan-io/conan/issues/2231 | ||
output = TestBufferConanOutput() | ||
with tools.environment_append({"CC": "gcc"}): |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!!!
may be it's better and more reliable to avoid parsing |
conans/client/conf/detect.py
Outdated
@@ -49,7 +49,7 @@ def _clang_compiler(output, compiler_exe="clang"): | |||
compiler = "apple-clang" | |||
elif "clang version" in out: | |||
compiler = "clang" | |||
installed_version = re.search("([0-9]\.[0-9])", out).group() | |||
installed_version = re.search("version ([0-9]\.[0-9])", out).group(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change in the regular expression worries me a little. If some specific clang is not printing the "version" word we could be breaking. Why did you need it? If there is a good reason I'm ok with it, if don't, better keep it like it was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is only for apple-clang I would prefer to limit it to the Apple if to mitigate possible issues
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But apple-clang was already working, when the compiler is "clang --version". So parsing didn't seem an issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question, but looking at the output it could be:
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.4.0
Please @pvicente confirm then it is failing and why didn't fail so far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is when using fake gcc in mac os x.
This is the output for gcc:
10:31 $ 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
The previous regular expression catches 4.2 as compiler version, see regex problem
When I added version in regex I checked out that clang in linux, clang in apple are returning version
in the output.
MacOSX:
23:21 $ clang --version
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
Linux:
conan@8bb2abebb6c8:/Users/pvicente/git/conan/conan$ clang --version
clang version 5.0.0-3 (tags/RELEASE_500/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Hope it makes sense to you.
@SSE4 could be more accurate, but I think we are good by now with the |
f5fd32a
to
22b941a
Compare
@lasote @memsharded fixed test case checking output |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take a look to: #2231
I think in case of see gcc in CC in osx, if the returned trace is about clang, we should discard this detection (warn something maybe) and try with the regular one (not looking defaults CC).
You could think that the result is the same, but I think it is cleaner and safer.
conans/test/util/detect_test.py
Outdated
|
||
def detect_default_in_mac_os_using_gcc_as_default_test(self): | ||
""" | ||
In some Mac OS X gcc is in reality clang. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We investigate it and we changed our mind, the clang "gcc" is not a pure gcc. Read the last comment of @memsharded here: #2231
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lasote @memsharded I've updated the code to skip gcc detection this case arises as commented in #2231
16b1e85
to
a8c1e6d
Compare
@lasote @memsharded it's ready for review with suggested changes #2231
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a little simplification in the test and the rest I think it is ok.
conans/test/util/detect_test.py
Outdated
if platform.system() != "Darwin": | ||
return | ||
|
||
def _execute(command): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can simplify all this with output_str = subprocess.check_output(command)
and try, except in case of subprocess failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, totally right!!! fixing it!!!
conans/test/util/detect_test.py
Outdated
if proc_return != 0 or "clang" not in output: | ||
# Not test scenario (gcc should display clang in output | ||
if "clang" not in output: | ||
# Not test scenario gcc should display clang in output | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhh, may we raise here to realize that maybe the default OSX policy for "gcc" has changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that it is not the scope of the test, but useful to know if something changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes It's a good idea, @memsharded WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like: raise Exception("Apple gcc doesn't point to clang with gcc frontend anymore! please check")
conans/client/conf/detect.py
Outdated
if "clang" not in out: | ||
return _gcc_compiler(output, command) | ||
output.warn("%s detected as a frontend using apple-clang, skipping it to use native apple-clang" % command) | ||
command = "clang" # Force use of clang when gcc is detected as a fronted of apple-clang |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with this. If the user is messing with CC/CXX is his problem. And the default profile is just a default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, makes sense
conans/client/conf/detect.py
Outdated
_, out = _execute("%s --version" % command) | ||
out = out.lower() | ||
if "clang" not in out: | ||
return _gcc_compiler(output, command) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The overall logic of this code seems a bit convolute IMHO, with 2 calls to _gcc_compiler()
plus one manual _execute("gcc...
. Maybe it would make more sense to put this logic inside _gcc_compiler()
, so the compiler is called exactly once, and the rest is processing the output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@memsharded @lasote in that case what about the fallback to clang when gcc is a frontend of apple-clang
.
Shall we call _clang_compiler(output, "clang")
inside _gcc_compiler(output, command)
as the logic will be inside _gcc_compiler
?
I've seen that we are using _gcc_compiler also in the case that we are not forcing the usage of gcc with CC variable so I'm not sure about putting the logic inside _gcc_compiler
…ned. Checked if compiler name is matches with compiler exe output
0a467d1
to
5b7b94d
Compare
conans/client/conf/detect.py
Outdated
"%s detected as a frontend using apple-clang, skipping it to use native apple-clang" % command | ||
) | ||
# Fallback to use clang instead | ||
command = "clang" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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'...
....
* Fixing default compiler detection when environment variables are defined. Checked if compiler name is matches with compiler exe output * Added end2end tests for compiler detection * Addressed comment from PR, removing _is_real_compiler method * Updated test for mac os x reported bug * Checking output of "gcc --version" and execute in right test scenario. * Updated code to skip gcc when it's using apple-clang as a frontend in Mac OS X * Updated test to run only in Mac OS X * Simplified test using subprocess.check_output * Raising exception if gcc doesn't point to clang in Mac OS X * Fixed problem python 2/3 * As sugested in PR putting logic to detect GCC as clang frontend inside _gcc_compiler method * Updated to simplify logic * Moving check inside try/except * As commented in PR now compiler GCC if it's a fronted of apple-clang is not supported
closes #2231
Previously failing compiler detection in mac os x when gcc was forced:
Now: