Golang本身原生支持跨平台编译,不需要额外安装复杂的依赖工具,只需要通过配置环境变量就能实现不同操作系统和CPU架构下的程序编译。这种方式比传统编译语言的交叉编译配置要简单很多,开发者可以快速生成适配多平台的可执行文件。

跨平台编译核心环境变量
Golang的跨平台编译主要依赖两个核心环境变量,通过设置这两个变量可以指定目标编译平台的信息:
- GOOS:指定目标操作系统,常见的取值有linux、windows、darwin(对应macOS)、freebsd等
- GOARCH:指定目标CPU架构,常见的取值有amd64、386、arm、arm64等
除了这两个核心变量,还可以根据需要设置CGO_ENABLED变量,默认值为1表示开启CGO,若目标平台没有对应的C编译器,可以将其设置为0关闭CGO,此时编译的是纯Go代码的程序。
常见平台编译命令示例
以下是在不同宿主系统下编译常见目标平台的命令示例,假设当前要编译的程序入口文件为main.go:
在macOS/Linux系统下编译
编译Windows 64位程序:
# 编译Windows 64位exe程序 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o app.exe main.go
编译Linux 64位程序:
# 编译Linux 64位二进制程序 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app main.go
编译macOS 64位程序:
# 编译macOS 64位程序 CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o app_mac main.go
在Windows系统下编译
Windows的命令行(CMD)和PowerShell设置环境变量的方式略有不同,以下是CMD下的编译示例:
编译Linux 64位程序:
# CMD下编译Linux 64位程序 set CGO_ENABLED=0 set GOOS=linux set GOARCH=amd64 go build -o app main.go
编译macOS ARM架构程序(适配Apple Silicon芯片):
# CMD下编译macOS ARM架构程序 set CGO_ENABLED=0 set GOOS=darwin set GOARCH=arm64 go build -o app_arm main.go
环境变量取值对照表
为了避免设置错误的GOOS和GOARCH取值,以下是常见的组合对照表:
| 目标操作系统 | 目标CPU架构 | GOOS取值 | GOARCH取值 |
|---|---|---|---|
| Windows | 64位 | windows | amd64 |
| Windows | 32位 | windows | 386 |
| Linux | 64位 | linux | amd64 |
| Linux | ARM64 | linux | arm64 |
| macOS | 64位(Intel芯片) | darwin | amd64 |
| macOS | ARM64(Apple Silicon) | darwin | arm64 |
编译注意事项
在实际编译过程中需要注意以下几点:
- 如果程序使用了CGO调用C代码,那么跨平台编译时需要目标平台对应的C编译器,否则需要将CGO_ENABLED设置为0,仅编译纯Go代码部分
- 编译生成的文件名可以自定义,Windows平台下建议加上.exe后缀,方便用户识别
- 可以通过
go env命令查看当前Golang环境的默认GOOS和GOARCH取值,确认当前宿主平台的配置 - 若需要批量编译多个平台的程序,可以编写简单的脚本循环设置环境变量并执行编译命令,提升效率
下面是一个简单的bash脚本示例,用于批量编译三个常见平台的程序:
#!/bin/bash
# 批量编译多平台程序脚本
platforms=("windows/amd64" "linux/amd64" "darwin/amd64")
for platform in "${platforms[@]}"
do
GOOS=${platform%/*}
GOARCH=${platform#*/}
output_name="app_${GOOS}_${GOARCH}"
if [ "$GOOS" = "windows" ]; then
output_name+=".exe"
fi
CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name main.go
if [ $? -eq 0 ]; then
echo "编译成功:$output_name"
else
echo "编译失败:$output_name"
fi
done