# 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 | 使用示例如下: ```bash 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 版的二进制,需要这样做: ```bash # 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 时编译 ```go // +build linux,386 darwin,!cgo package mypackage ``` 还可以采用并列的写法。例如: ```go // +build linux darwin // +build amd64 package mypackage ``` ***注意,在标签和 package 声明之间必须有一个空行。*** ## 文件后缀 也可以通过向文件添加后缀来区分不同平台的代码: ```bash myfile_freebsd_arm.go __.go ``` ***注意,源文件不能只提供编译后缀。***