Go可在Linux/macOS交叉编译Windows程序,但需根据是否启用cgo选择CGO_ENABLED=0(纯Go,功能降级)或配置MinGW-w64工具链(支持net/user/exec等,依赖msvcrt.dll);GOOS=windows和GOARCH是基础,arm64需Go 1.20+。

Go 语言编译 Windows 程序不需要 Windows 系统,只要在 Linux/macOS 上交叉编译即可,但必须注意 CGO_ENABLED 和目标平台标识的组合行为——它直接决定是否能生成可运行的 .exe,以及是否依赖 msvcrt.dll 或静态链接。
设置 GOOS=windows 和 GOARCH 是基础,但不是全部
交叉编译 Windows 程序最简命令是:
GOOS=windows GOARCH=amd64 go build -o app.exe main.go
但这只适用于纯 Go 代码(不含 cgo)。一旦引入 net、os/user、os/exec 等包,就可能触发 cgo —— 此时默认会失败,报错类似:
exec: "gcc": executable file not found in $PATH
立即学习“go语言免费学习笔记(深入)”;
- 原因:Go 在
CGO_ENABLED=1(默认)下尝试调用gcc生成 Windows 兼容的 C 对象,而宿主机没有 MinGW-w64 工具链 - 解决方向有两个:关掉 cgo(适合无系统调用的程序),或配好交叉编译工具链(适合需 DNS 解析、用户信息等场景)
-
GOARCH可选值包括amd64、386、arm64;注意arm64Windows 支持从 Go 1.20+ 才稳定
CGO_ENABLED=0 编译时要小心标准库功能降级
禁用 cgo 能绕过工具链依赖,命令为:
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o app.exe main.go
但它会让部分标准库退化:
-
net包使用纯 Go DNS 解析器,不读取 Windows 的hosts文件或本地 DNS 配置,且不支持getaddrinfo级别的 SRV/AAAA 控制 -
user.Lookup和user.Current返回空用户名和 UID/GID,因为无法调用GetUserNameEx等 Win32 API -
os/exec仍可用,但无法继承父进程环境变量(Windows 下需 cgo 实现CreateProcess的bInheritHandles控制)
需要 cgo?那就装 x86_64-w64-mingw32-gcc
Linux/macOS 上启用 cgo 编译 Windows 程序,必须安装对应架构的 MinGW-w64 工具链:
- Ubuntu/Debian:
sudo apt install gcc-mingw-w64,然后确认x86_64-w64-mingw32-gcc在$PATH - macOS(Homebrew):
brew install mingw-w64,工具链前缀通常是x86_64-w64-mingw32- - 关键环境变量:
CC_x86_64_w64_mingw32=x86_64-w64-mingw32-gcc(Go 会自动识别) - 编译命令:
CGO_ENABLED=1 CC_x86_64_w64_mingw32=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -o app.exe main.go
此时生成的 .exe 依赖 Windows 系统自带的 msvcrt.dll(非 VC++ 运行时),无需额外分发 DLL,在 Windows 7+ 均可运行。
加图标、版本信息?得用资源文件(.rc)+ rsrc 工具
Go 原生不支持嵌入 Windows 资源(图标、公司名、文件版本),需借助外部工具:
- 写一个
app.rc文件,内容如:1 ICON "icon.ico" - 用
windres(MinGW 提供)编译成app.syso:x86_64-w64-mingw32-windres app.rc -O coff -o app.syso - 再执行普通编译,Go 会自动链接
.syso文件 - 更轻量方案:用
rsrc(go install github.com/akavel/rsrc@latest),支持 JSON 描述资源并一键生成.syso
漏掉这步,程序在任务管理器里显示为“未知应用”,右键属性看不到版本页签——看似小事,但企业内分发时经常被安全策略拦截。

















