在 Ubuntu 下使用 MinGW-w64 作为交叉编译器来构建 Windows 平台的 C/C++/Fortran 项目,是一种常见的跨平台开发方式。以下是完整的操作指南、关键注意事项及最佳实践。

MinGW-w64
https://packages.msys2.org/packages/
OpenFOAM v3.0+ on Windows
Package scripts for MinGW-w64 targets to build under MSYS2


一、安装 MinGW-w64 交叉编译工具链

Ubuntu 官方仓库提供了 MinGW-w64 工具链,支持多种目标架构(如 x86_64-w64-mingw32i686-w64-mingw32)。

1. 安装(以 64 位 Windows 目标为例)

sudo apt update
sudo apt install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 gfortran-mingw-w64-x86-64

若需 32 位 Windows 支持,安装 gcc-mingw-w64-i686 等对应包。

2. 验证安装

x86_64-w64-mingw32-gcc --version
x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-gfortran --version

这些命令应能正常输出版本信息。


二、基本交叉编译示例

C 示例

// hello.c
#include <stdio.h>
int main() {
    printf("Hello from Windows!\n");
    return 0;
}

编译:

x86_64-w64-mingw32-gcc -o hello.exe hello.c

生成的 hello.exe 可在 Windows 上直接运行。

C++ 示例

// test.cpp
#include <iostream>
int main() {
    std::cout << "C++ on Windows via MinGW-w64\n";
    return 0;
}

编译:

x86_64-w64-mingw32-g++ -o test.exe test.cpp

Fortran 示例

! hello.f90
program hello
  print *, 'Hello from Fortran on Windows!'
end program

编译:

x86_64-w64-mingw32-gfortran -o hello.exe hello.f90

三、构建复杂项目(CMake / Autotools)

✅ 使用 CMake(推荐)

方法 1:指定工具链文件(Toolchain File)

创建 mingw64-toolchain.cmake

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

set(CMAKE_C_COMPILER   x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_Fortran_COMPILER x86_64-w64-mingw32-gfortran)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

构建项目:

mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../mingw64-toolchain.cmake
cmake --build .

输出的可执行文件和 DLL 将是 Windows 格式(PE/COFF)。

方法 2:环境变量方式(简单项目)
CC=x86_64-w64-mingw32-gcc \
CXX=x86_64-w64-mingw32-g++ \
FC=x86_64-w64-mingw32-gfortran \
cmake .. -DCMAKE_SYSTEM_NAME=Windows

✅ 使用 Autotools(configure 脚本)

./configure --host=x86_64-w64-mingw32
make

Autotools 会自动使用 x86_64-w64-mingw32-* 工具链。


四、关键注意事项

1. 运行时依赖(CRT)

  • MinGW-w64 默认静态链接 CRT(-static),生成的 .exe 无需额外 DLL。
  • 若动态链接(默认行为可能因发行版而异),会依赖 libgcc_s_seh-1.dlllibstdc++-6.dlllibgfortran-5.dll 等。
    • 建议:发布时加上 -static 避免依赖问题:
      x86_64-w64-mingw32-g++ -static -o app.exe app.cpp
      

2. 线程模型:posix vs win32

Ubuntu 的 MinGW-w64 包通常提供两种线程模型:

  • x86_64-w64-mingw32-gcc → 默认 win32 线程(无 pthread)
  • x86_64-w64-mingw32-gcc-posix → 支持 pthread(通过 winpthreads)

如果项目使用 std::thread、OpenMP 或依赖 POSIX 线程,必须使用 posix 版本

# 安装 posix 版本(如果未安装)
sudo apt install gcc-mingw-w64-x86-64-posix g++-mingw-w64-x86-64-posix

# 使用
x86_64-w64-mingw32-g++-posix -static -fopenmp -o omp.exe omp.cpp

3. 异常处理模型:SEH vs SJLJ

  • 64 位:通常使用 SEH(Structured Exception Handling),性能更好。
  • 32 位:可能用 SJLJ(Set Jump / Long Jump)。
  • Ubuntu 的 MinGW-w64 通常已正确配置,一般无需干预。

4. Fortran 特殊性

  • gfortran 会链接 libgfortran,若动态链接,需分发相应 DLL。
  • 使用 -static-libgfortran -static-libgcc 可减少依赖:
    x86_64-w64-mingw32-gfortran -static -static-libgfortran -static-libgcc -o fapp.exe fapp.f90
    

5. 路径与文件系统

  • Windows 路径分隔符为 \,但 MinGW 在 Linux 下编译时仍用 /
  • 避免硬编码路径,使用 CMAKE_INSTALL_PREFIX 或运行时检测。

6. 第三方库依赖

  • 所有依赖库(如 zlib、HDF5、OpenMP)必须也用 MinGW-w64 交叉编译
  • 不能直接链接 Linux 的 .so 或 MSVC 的 .lib
  • 建议使用 vcpkg(支持 MinGW)或手动交叉编译依赖。
使用 vcpkg(可选)
git clone https://github.com/microsoft/vcpkg
./vcpkg/bootstrap-vcpkg.sh
./vcpkg install zlib:x64-mingw-static

然后在 CMake 中集成。


五、调试与测试

  • 生成的 .exe 只能在 WindowsWine 上运行。
  • 可用 Wine 快速测试:
    sudo apt install wine
    wine ./myapp.exe
    
  • 调试:可用 gdb(MinGW 版本)配合 Wine,但体验有限;建议在 Windows 上用 GDB 或 Visual Studio Debugger。

六、常见问题排查

问题 解决方案
undefined reference to '__imp_xxx' 缺少导入库,或未正确链接 DLL;检查是否混用了 MSVC 和 MinGW 库
std::thread not supported 使用 *-posix 编译器版本
Fortran 程序崩溃 添加 -static-libgfortran -static-libgcc
OpenMP 不工作 确保使用 *-posix 编译器,并加 -fopenmp
生成的 exe 在 Windows 报错“不是有效的 Win32 应用” 检查是否误用了 32/64 位工具链不匹配

七、总结:最佳实践清单

✅ 安装正确的 MinGW-w64 工具链(含 posix 版本如需线程)
✅ 使用 CMake + toolchain file 管理交叉编译
✅ 优先静态链接(-static)避免运行时依赖
✅ 所有依赖库必须用相同工具链交叉编译
✅ 用 Wine 快速验证可执行文件
✅ Fortran 项目添加 -static-libgfortran -static-libgcc
✅ 避免 C++ ABI 混用(不要混用 MSVC/MinGW/Clang)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐