MinGW交叉编译介绍
✅ 安装正确的 MinGW-w64 工具链(含posix版本如需线程)✅ 使用 CMake + toolchain file 管理交叉编译✅ 优先静态链接(-static)避免运行时依赖✅ 所有依赖库必须用相同工具链交叉编译✅ 用 Wine 快速验证可执行文件✅ Fortran 项目添加✅ 避免 C++ ABI 混用(不要混用 MSVC/MinGW/Clang)
文章目录
在 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-mingw32、i686-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.dll、libstdc++-6.dll、libgfortran-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只能在 Windows 或 Wine 上运行。 - 可用 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)
更多推荐



所有评论(0)