NotePublic/Software/Development/Language/Go/Basic/Go_交叉编译.md

3.7 KiB
Raw Blame History

Go 交叉编译

交叉编译宏

Golang 的交叉编译是通过设置编译宏变量来实现的,主要是 GOOS 和 GOARCH列表如下

GOOS - Target Operating System GOARCH - Target Platform
android arm
android arm64
android 386
android amd64
darwin 386
darwin amd64
darwin arm
darwin arm64
dragonfly amd64
freebsd 386
freebsd amd64
freebsd arm
linux 386
linux amd64
linux arm
linux arm64
linux ppc64
linux ppc64le
linux mips
linux mipsle
linux mips64
linux mips64le
netbsd netbsd
netbsd amd64
netbsd arm
openbsd 386
openbsd amd64
openbsd arm
plan9 386
plan9 386
solaris amd64
windows 386
windows amd64

使用示例如下:

GOOS=linux GOARCH=arm64 go build
GOOS=linux GOARCH=arm GOARM=7 go build

交叉编译是不支持 CGO 的,也就是说如果你的代码中存在 C 代码,是编译不了的。,比如说你的程序中使用了 sqlite 数据库,在编译 go-sqlite 驱动时按照上面的做法是编译不通过的。

需要 CGO 支持的,要将 CGO_ENABLED 的 0 改为 1也就是“CGO_ENABLED=1”此外还需要设置编译器例如我想在 linux 上编译 arm 版的二进制,需要这样做:

# Build for arm
CGO_ENABLED=1 GOOS=linux GOARCH=arm CC=arm-linux-gnueabi-gcc go build
# Build and Stripped
GOOS=linux GOARCH=arm go build -ldflags "-s"

编译标签

有时针对不同的平台、架构,在代码中需要进行额外的处理,因此需要在代码中区分平台和架构。

Go语言通过关键字+build在编译时对平台和就够进行区分。

例如:在 Linux 平台386 架构或者 darwin 平台,非 CGo 时编译

// +build linux,386 darwin,!cgo

package mypackage

还可以采用并列的写法。例如:

// +build linux darwin
// +build amd64

package mypackage

注意,在标签和 package 声明之间必须有一个空行。

文件后缀

也可以通过向文件添加后缀来区分不同平台的代码:

myfile_freebsd_arm.go
<file name>_<os>_<arch>.go

注意,源文件不能只提供编译后缀。