直接在Windows上用go build -o app.exe可生成可运行exe;跨平台编译需设GOOS=windows和GOARCH=amd64,推荐CGO_ENABLED=0避免DLL依赖,图标/版本/UAC须用go-winres注入。

直接在 Windows 上用 go build -o app.exe 就能生成可运行的 exe,但如果你是在 macOS 或 Linux 上交叉编译 Windows 程序,必须显式设置 GOOS=windows 和 GOARCH=amd64,否则生成的不是 Windows 可执行文件,只是后缀名碰巧叫 .exe 而已。
Windows 本地构建:不用设 GOOS,但要注意工作目录和 main 包
在 Windows 的 cmd 或 PowerShell 中,只要当前目录下有 main.go 且含 func main(),直接运行:
go build -o myapp.exe
就能得到可双击运行的 exe。常见失败点:
-
build failed: no Go files in:当前目录没有main.go,或没在项目根目录(含go.mod的地方) -
cannot find package "main":main.go文件里没写package main,或用了其他包名 - 双击闪退:程序是命令行工具,没参数就立即退出;可加
fmt.Scanln()临时卡住看输出,但正式发布不建议
macOS/Linux 交叉编译 Windows exe:GOOS 和 CGO_ENABLED 是关键
在非 Windows 系统上生成真正可用的 Windows exe,这两项缺一不可:
立即学习“go语言免费学习笔记(深入)”;
-
GOOS=windows:必须设,否则生成的是宿主机二进制(比如 macOS 的 Mach-O),Windows 根本不认 -
CGO_ENABLED=0:推荐设,避免依赖vcruntime140.dll等 VC++ 运行时——目标机器没装对应 Redistributable 就直接报错“找不到 XXX.dll”
正确命令示例(Linux/macOS):
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o myapp.exe main.go
PowerShell 用户注意:不能用 = 赋值语法,得写成:
$env:CGO_ENABLED="0"; $env:GOOS="windows"; $env:GOARCH="amd64"; go build -o myapp.exe main.go
生成的 exe 双击没反应?检查代码是否跨平台兼容
交叉编译不会检查代码里有没有 Windows 不支持的操作,等你拷到 Windows 上一跑才暴露问题。典型雷区:
-
os/exec.Command("bash", ...)或"sh":Windows 没 bash,得换成os/exec.Command("cmd", "/c", ...) - 硬编码路径分隔符:
"/tmp/data.txt"→ 改用filepath.Join(os.TempDir(), "data.txt") - 调用 Linux 专属 syscall 或读
/proc:Windows 上会 panic,可用//go:build windows构建约束隔离 - Kingpin/v2 等 CLI 库:双击启动时无命令行参数,程序按默认行为退出;如需交互,得自己加 GUI 或封装成带 pause 的批处理
体积大、没图标、没版本信息?这些 Go 原生不支持
go build 生成的 exe 默认就是裸二进制:5–10MB 是正常现象(含运行时+所有依赖),没图标、没公司名、没右键属性里的“详细信息”标签页。
- 减体积:加
-ldflags "-s -w"去掉符号表和调试信息,通常省 1–3MB;别用 UPX,杀软易误报 - 加图标/版本/UAC:必须用外部工具,如
go-winres。流程是写myapp.rc或 JSON 描述资源 →go-winres make生成resources.syso→go build -o myapp.exe main.go resources.syso - UAC 提权(右键“以管理员身份运行”):仅靠 Go 代码做不到,必须注入 manifest,同样靠
go-winres处理
最常被忽略的一点:交叉编译出的 exe,哪怕看起来生成成功了,也一定要在真实 Windows 环境里测试——尤其是用了 cgo、syscall 或第三方 C 绑定时,宿主机上一切正常,到目标机上可能连进程都拉不起来。


















