应使用官方二进制安装Go,避免apt或brew等包管理器;解压至标准路径(如/usr/local/go),PATH仅添加$GOROOT/bin;构建时硬编码GOOS/GOARCH,用数组循环处理多平台目标。

直接用官方二进制,别碰系统包管理器
你写的脚本如果还在用 apt install golang 或 brew install go,就先停手——版本滞后、路径不标准、go env GOPATH 输出不可控,后续交叉编译和模块行为全会偏移。官方二进制解压即用,路径固定,go version 和 go env GOROOT 一眼可验。
实操建议:
• 下载地址统一走 https://golang.google.cn/dl/(国内直连)
• 解压到 /usr/local/go(Linux/macOS)或 C:\Go(Windows)
• PATH 只加 $GOROOT/bin,别混入 $GOPATH/bin
• 验证命令必须包含:go version 和 go env GOROOT GOPATH GO111MODULE
GOOS/GOARCH 构建逻辑要硬编码进脚本,别靠环境变量临时设
CI 或本地一键构建时,如果靠 GOOS=linux GOARCH=arm64 go build 这种 shell 方式拼接,容易漏掉空格、被子 shell 覆盖、或在 Windows cmd 下失效。脚本里应显式调用 go build 并传参,避免依赖外部环境。
实操建议:
• 用数组存目标平台组合:targets=("linux/amd64" "darwin/arm64" "windows/386")
• 循环中拆解:IFS="/" read -r os arch (bash)或对应 Go 的 <code>strings.Split(Go 脚本)
• 构建命令写成:GOOS=$os GOARCH=$arch go build -o "dist/app-$os-$arch$(if [ "$os" = "windows" ]; then echo ".exe"; fi)" main.go
• 注意:含 cgo 的项目必须同步设置 CGO_ENABLED=0,否则 macOS 上默认开 CGO,交叉编译 Linux 会失败
go.mod 初始化和依赖拉取必须带超时与代理控制
脚本执行到 go mod init 或 go mod tidy 时,若没设超时或代理,遇到网络抖动或 goproxy 失效,就会卡死几分钟甚至失败退出,CI 流水线直接中断。
实操建议:
• 初始化前先设代理:go env -w GOPROXY=https://goproxy.cn,direct
• 所有 go mod 命令加 -timeout 60s 参数(Go 1.21+ 支持)
• go mod tidy 后立即校验:git status --porcelain go.mod go.sum,非空则说明依赖变动,需提交
• 若项目禁用模块(GO111MODULE=off),脚本必须报错退出,不能静默降级到 GOPATH 模式
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
清理缓存和构建产物得在每次构建前强制执行
很多人忽略 go clean -cache -modcache,导致旧版本依赖残留、go.sum 校验失败、甚至跨平台构建时复用错误的 cgo 对象文件。
实操建议:
• 所有构建流程开头加:go clean -cache -modcache -r
• dist/ 目录必须 rm -rf dist/ && mkdir dist,不能只 rm -f dist/*(Windows 下可能删不干净)
• 如果脚本支持多版本 Go 切换(如用 asdf),每次切换后必须重跑 go env -w 设置代理和模块开关,不能复用上一版的 go env 输出
立即学习“go语言免费学习笔记(深入)”;
真正麻烦的不是写几行go build,而是不同平台对 GOOS 默认值、路径分隔符、行尾符、以及 os/exec 启动子进程的行为差异——这些不会报错,但会让生成的二进制在目标机器上静默崩溃。脚本里每一步都要假设它会在陌生系统上运行,而不是只在你本地 terminal 里能过就行。

















