使用 MinGW 从 Linux 交叉编译到 Windows

可以使用 MinGW 交叉编译器从 Linux 交叉构建到 Windows。请注意,此类编译器不会使用 MSVC 运行时,而是使用 MinGW 运行时,后者使用 libstdc++6.dll 运行时。

这篇关于 Windows 中 Clang 的博客文章描述了不同 Windows 子系统的不同运行时,这同样适用于 MinGW。

第一步是安装编译器。在基于 Debian 的系统中

$ sudo apt install gcc-mingw-w64-x86-64-posix
$ sudo apt install g++-mingw-w64-x86-64-posix

如果编译器安装在系统路径中,那么我们可以编写一个 profile,例如

mingw
[settings]
os=Windows
compiler=gcc
compiler.version=10
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
arch=x86_64
build_type=Release

[buildenv]
CC=x86_64-w64-mingw32-gcc-posix
CXX=x86_64-w64-mingw32-g++-posix

接下来,假设我们有一个基本的 CMake 项目,我们可以使用 conan new 创建它。

$ conan new cmake_lib -d name=mypkg -d version=0.1
$ conan create . -pr=mingw

...
-- Using Conan toolchain: .../conan_toolchain.cmake
-- Conan toolchain: Defining architecture flag: -m64
-- Conan toolchain: C++ Standard 17 with extensions ON
-- The CXX compiler identification is GNU 10.0.0
-- Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++-posix - skipped

mypkg/0.1 (test package): Running CMake.build()
mypkg/0.1 (test package): RUN: cmake --build ...
gcc-10-x86_64-gnu17-release" -- -j8
[ 50%] Building CXX object CMakeFiles/example.dir/src/example.cpp.obj
[100%] Linking CXX executable example.exe
[100%] Built target example

example.exe 将不会在 Linux 机器上执行,因为 test_package 包含一个 if can_run(self) 分支,以便在交叉构建场景中不运行它。

现在我们可以将 example.exe 拿出来并在 Windows 机器上运行它。

mypkg/0.1: Hello World Release!
mypkg/0.1: _M_X64 defined
mypkg/0.1: __x86_64__ defined
mypkg/0.1: _GLIBCXX_USE_CXX11_ABI 1
mypkg/0.1: MSVC runtime: MultiThreadedDLL
mypkg/0.1: __cplusplus201402
mypkg/0.1: __GNUC__10
mypkg/0.1: __MINGW32__1
mypkg/0.1: __MINGW64__1

注意

  • ConanCenter 中的某些 recipe 很可能未准备好从 Linux 交叉构建到 Windows。推荐的构建 ConanCenter recipe 的方法是在 Windows 中使用 MSVC 构建它们,因为 recipe 的特定构建系统可能存在限制,并且不保证支持 MinGW。

  • 尝试使用诸如 wine 之类的模拟器运行可执行文件可能需要额外的工作,因为运行时环境旨在是 Windows,因此会创建一个 conanrun.bat 环境文件,但在 Linux 中无法执行。使用诸如 -c tools.build.cross_building:can_run=True -c tools.microsoft.bash:subsystem=mingw -c tools.microsoft.bash:active=True 的配置可以强制生成并执行 conanrun.sh