Repository: conan-io/conan

Issue:
[bug] MSYS2 is not properly detected as Windows
While working on #2568 I tested conan with MSYS2. To my surprise, conan does not work out of the box in this environment. More specifically, the profile auto detection fails to detect the MSYS2 environment as `os=Windows` with `subsystem=msys2`. Instead, the following profile is generated:
~~~
[settings]
os=MSYS_NT-10.0
os_build=MSYS_NT-10.0
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=6
compiler.libcxx=libstdc++
build_type=Release
[options]
[build_requires]
[env]
~~~

It seems like the reason for this behavior is that `platform.system()` is not returning the expected `Windows` but `MSYS_NT-10.0` instead. Interestingly, `sys.platform` is `msys`.  Considering how often `platform.system() == "Windows"` is used within the conan codebase this makes me a little bit nervous... 

Best,
Mario


Discussion:
Which MSYS2 subsystem/shell did you use?
Msys (also called Msys2 on the wiki), Mingw32 or Mingw64?
https://github.com/msys2/msys2/wiki/MSYS2-introduction#msys2-susbsystems

I believe Conan generates `os=Windows` for Mingw64 one, but doesn't create `subsystem=msys2`.
Great question, I used the python that you get when you install with `pacman -S python`. Apparently, that is the python from the `msys` subsystem. What shell you use (through the `msys`, `mingw32` or `mingw64` launchers) seems to be unimportant in this case because the `msys` binaries are in the path of all three subsystem shells.

There are indeed other python packages for the `mingw` subsystems (e.g., `mingw64/mingw-w64-x86_64-python3`) that seem to behave like expected (i.e., `platform.system()` returns `Windows`). It seems therefore possible to work around the specific problem by installing additional python, pip, and conan versions for each subsystem. Anyway, I am not very thrilled to have this redundancy and I think we should strive to improve the situation.

Thank you @ArekPiekarz for helping me figuring out what is going wrong!



Since it is not only relevant for generating the correct default profiles but also for #2568, I had a closer look at all the different python versions I could find on my Windows PC. Here are the (truncated) results on how they behave regarding platform identification and abstraction:
~~~python
import os
import platform
import sys

print("repr(os.linesep)     : " + repr(os.linesep))
print("os.name              : " + os.name)
print("os.pathsep           : " + os.pathsep)
print("os.sep               : " + os.sep)
print("platform.system()    : " + platform.system())
print("sys.platform         : " + sys.platform)
print("sys.version          : " + sys.version)
print("os.environ['PATH']   : " + os.environ['PATH'])
print("os.path.join('a','b'): " + os.path.join('a','b'))
~~~

msys python (installed via `pacman -S python`)
----------------------------------------------------------------------------
~~~
repr(os.linesep)     : '\n'
os.name              : posix
os.pathsep           : :
os.sep               : /
platform.system()    : MSYS_NT-10.0
sys.platform         : msys
sys.version          : 3.6.2 (default, Sep  7 2017, 13:16:50)
[GCC 6.3.0]
os.environ['PATH']   : /home/Mario/bin:/usr/local/bin:/usr/bin:...
os.path.join('a','b'): a/b

~~~
This is the python installation I used when I reported this issue. It seems to behave like a regular Linux python but the `platform.system()` value is strange. Interestingly, launching the same python binary from the mingw64 shell returns `MINGW64_NT-10.0` as `platform.system()` result. Still, in my understanding it is the configuration where the [documentation](http://docs.conan.io/en/latest/systems_cross_building/windows_subsystems.html?highlight=msys#operation-modes) says that `os.subsystem` should be set to `msys2` given that binaries built with the corresponding gcc depend on `msys-2.0.dll`. 

mingw64 subsystem python3 (installed via `pacman -S mingw64/mingw-w64-x86_64-python3`)
---
~~~
repr(os.linesep)     : '\r\n'
os.name              : nt
os.pathsep           : ;
os.sep               : /
platform.system()    : Windows
sys.platform         : win32
sys.version          : 3.6.4 (default, Jan 23 2018, 13:17:37)  [GCC 7.2.0 64 bit (AMD64)]
os.environ['PATH']   : D:\msys64\mingw64\bin;D:\msys64\home\Mario\bin;D:\msys64\usr\local\bin;...
os.path.join('a','b'): a/b
~~~
This is the version @ArekPiekarz directed me to. Like expected, it behaves like a native Windows python in most cases except for the path handling. It seems to load the `posixpath` module instead of the `ntpath` module as `os.path`. Given that it properly identifies as Windows everything seems to work fine though.

Random native python3.3
----
~~~
repr(os.linesep)     : '\r\n'
os.name              : nt
os.pathsep           : ;
os.sep               : \
platform.system()    : Windows
sys.platform         : win32
sys.version          : 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:35:05) [MSC v.1600 64 bit (AMD64)]
os.environ['PATH']   : D:\AC\python33\;C:\WINDOWS\system32;C:\WINDOWS;...
os.path.join('a','b'): a\b
~~~
Nothing special. Just a proper native python that identifies and behaves as expected.

python and python3 from WSL
---
~~~
repr(os.linesep)     : '\n'
os.name              : posix
os.pathsep           : :
os.sep               : /
platform.system()    : Linux
sys.platform         : linux2
sys.version          : 2.7.6 (default, Nov 23 2017, 15:49:48)
[GCC 4.8.4]
os.environ['PATH']   : /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/d/AC/python33:...
os.path.join('a','b'): a/b
~~~
~~~
repr(os.linesep)     : '\n'
os.name              : posix
os.pathsep           : :
os.sep               : /
platform.system()    : Linux
sys.platform         : linux
sys.version          : 3.4.3 (default, Nov 28 2017, 16:41:13)
[GCC 4.8.4]
os.environ['PATH']   : /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/d/AC/python33:...
os.path.join('a','b'): a/b
~~~
Both identify as proper Linux versions and generate the according profiles. At least with the printed information nothing directly identifies these versions as being part of WSL. 

Maybe these results help improving the platform detection in the future. The issue that the msys python does not identify as Windows is still concerning though.

Resolving patch:
diff --git a/conans/client/conf/detect.py b/conans/client/conf/detect.py
--- a/conans/client/conf/detect.py
+++ b/conans/client/conf/detect.py
@@ -235,6 +235,10 @@ def detected_os():
         return "Macos"
     if result.startswith("CYGWIN"):
         return "Windows"
+    if result.startswith("MINGW32_NT") or result.startswith("MINGW64_NT"):
+        return "Windows"
+    if result.startswith("MSYS_NT"):
+        return "Windows"
     return result
 
 


Test patch: