Conan: [bug] MSYS2 is not properly detected as Windows

Created on 19 Mar 2018  路  3Comments  路  Source: conan-io/conan

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

bug

Most helpful comment

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 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:msys64mingw64\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.

All 3 comments

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 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:msys64mingw64\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.

Was this page helpful?
0 / 5 - 0 ratings