Windows Subsystems
On Windows, you can run different subsystems that enhance with UNIX capabilities the operating system.
Conan supports MSYS2
, CYGWIN
, WSL
and in general any subsystem that is able to run a bash
terminal.
Many libraries use these subsystems to be able to use the Unix tools like the Autoconf
suite
to generate and build Makefiles
.
The difference between MSYS2 and CYGWIN is that MSYS2 is oriented to the development of native Windows packages, while CYGWIN tries to provide a complete unix-like system to run any Unix application on it.
For that reason, we recommend the use of MSYS2 as a subsystem to be used with Conan.
Operation Modes
The MSYS2
and CYGWIN
can be used with different operation modes:
You can use them together with MinGW to build Windows-native software.
You can use them together with any other compiler to build Windows-native software, even with Visual Studio.
You can use them with MinGW to build specific software for the subsystem, with a dependency to a runtime DLL (
msys-2.0.dll
andcygwin1.dll
)
If you are building specific software for the subsystem, you have to specify a value for the setting os.subsystem
,
if you are only using the subsystem for taking benefit of the UNIX tools but generating native Windows software, you
shouldn’t specify it.
Running commands inside the subsystem
self.run()
In a Conan recipe, you can use the self.run
method specifying the parameter win_bash=True
that will call automatically to the tool tools.run_in_windows_bash.
It will use the bash in the path or the bash specified for the environment variable CONAN_BASH_PATH to run the specified command.
Conan will automatically escape the command to match the detected subsystem.
If you also specify the msys_mingw
parameter to False, and the subsystem is MSYS2
it will
run in Windows-native mode, the compiler won’t link against the msys-2.0.dll
.
AutoToolsBuildEnvironment
In the constructor of the build helper, you have the win_bash
parameter. Set it to True
to
run the configure
and make
commands inside a bash.
Controlling the build environment
Building software in a Windows subsystem for a different compiler than MinGW can be painful sometimes. The reason is how the subsystem finds your compiler/tools in your system.
For example, the icu library requires Visual Studio to be built in Windows, but also a subsystem
able to build the Makefile. A very common problem and example of the pain is the link.exe
program.
In the Visual Studio suite, link.exe
is the linker, but in the MSYS2
environment the link.exe
is a tool to manage symbolic links.
Conan is able to prioritize the tools when you use build_requires
, and put the tools in the PATH in
the right order.
There are some packages you can use as build_requires
:
From Conan-center:
mingw_installer/1.0@conan/stable: MinGW compiler installer as a Conan package.
msys2_installer/latest@bincrafters/stable: MSYS2 subsystem as a Conan package.
cygwin_installer/2.9.0@bincrafters/stable: Cygwin subsystem as a Conan package.
For example, create a profile and name it msys2_mingw with the following contents:
[build_requires]
mingw_installer/1.0@conan/stable
msys2_installer/latest@bincrafters/stable
[settings]
os_build=Windows
os=Windows
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=4.9
compiler.exception=seh
compiler.libcxx=libstdc++11
compiler.threads=posix
build_type=Release
Then you can have a conanfile.py that can use self.run()
with win_bash=True
to run any
command in a bash terminal or use the AutoToolsBuildEnvironment
to invoke configure/make
in the subsystem
:
from conans import ConanFile
import os
class MyToolchainXXXConan(ConanFile):
name = "mylib"
version = "0.1"
...
def build(self):
self.run("some_command", win_bash=True)
env_build = AutoToolsBuildEnvironment(self, win_bash=True)
env_build.configure()
env_build.make()
...
And apply the profile in your recipe to create a package using the MSYS2 and MINGW:
$ conan create . user/testing --profile msys2_mingw
As we included in the profile the MinGW
and then the MSYS2
build_require, when we run a command, the PATH
will contain first the MinGW tools and finally the MSYS2.
What could we do with the Visual Studio issue with link.exe
? You can pass an additional parameter to run_in_windows_bash
with a dictionary of environment variables to have more priority than the others:
def build(self):
# ...
vs_path = tools.vcvars_dict(self.settings)["PATH"] # Extract the path from the vcvars_dict tool
tools.run_in_windows_bash(self, command, env={"PATH": vs_path})
So you will get first the link.exe
from the Visual Studio.
Also, Conan has a tool tools.remove_from_path
that you can use in a recipe to remove temporally a
tool from the path if you know that it can interfere with your build script:
class MyToolchainXXXConan(ConanFile):
name = "mylib"
version = "0.1"
...
def build(self):
with tools.remove_from_path("link"):
# Call something
self.run("some_command", win_bash=True)
...