Golang交叉编译多平台二进制文件一文搞定

  • 发表于
  • go

Go跨平台交叉编译介绍

golang依托语言特性跨平台、性能效率、周边都还算不错,有不少开发者把Go做为跨平台SDK来封装,起到了不错的效果,今天写篇Go如何交叉编译多平台二进制文件的文章,以达到跨平台调用的目的。

Golang 1.5开始,交叉编译变得非常便捷:

  • 对于没有使用CGO的程序,只需设置GOOSGOARCHCGO_ENABLED这几个环境变量,即可直接利用编译器自带的跨平台特性实现跨平台编译
  • 对于使用CGO的程序,大部分情况下可以通过配置CC环境变量使用自行准备的交叉编译工具进行编译

首先当然是安装go的脚手架,这部分自行补充,我们看一下go支持的跨平台交叉编译支持列表:

GOOS - Target Operating SystemGOARCH - Target Platform
系统平台

查看当前 Go 版本支持的编译平台

支持非常广泛,最常用的大概是x86amd64架构:

  • darwin/386:对应 Mac x86
  • darwin/amd64:对应 Mac amd64
  • linux/386:对应 Linux x86
  • linux/amd64:对应 Linux amd64
  • Windows/386:对应 Windows x86
  • Windows/amd64:对应 Windows amd64

对应关系补充

Go多平台交叉编译示例 macOS

以下示例是Mac下go交叉编译跨平台的 动态库与静态库 .so .a .dll

这里有几点要注意

  1. package 一定要是 main(强制规定)
  2. 一定要包含 main 函数(强制规定)
  3. import "", 不能少, 因为要编译出 c(c++)的头文件
  4. 每个方法前要加//export 方法名, 这里要注意
    1. // 和 export间不能有空格
    2. 方法名和 go 的方法名必须完全一样
    3. 方法名不能是 c 内置的方法名, 比如remove就不行

main.go

注意:下面的 -ldflags "-w -s" 参数很多时候并不需要,自行调整。

编译变量说明

  1. GOOS=目标平台(编译后要运行的目标平台)的操作系统(darwin、freebsd、linux、windows、android、IOS)
  2. GOARCH=目标平台(编译后要运行的目标平台)的体系架构(386、amd64、arm)分别对应(32位、64位、ARM平台)的架构
  3. CGO_ENABLED=1 是否开启CGO编译,0关闭CGO
  4. CC=ndk 里的 clang,需要是对应 CPU 版本的, API 呢建议是最低
    1. 这里单独说明一下, 高版本的 ndk 用的是 clang, 低版本用的是 gcc, 这个根据你情况来, 个人建议直接用 21.0.6113669版本, 这个我测试过, 没有问题, ndk20 我也试过, 也是 ok 的
  5. go build 命令
    1. -buildmode=c-shared 构建类型, 使用 go help buildmode查看, 安卓一般用c-shared就可以了, 意思就是 c 类型的共享库(动态库)
    2. -o 后面跟输出的位置, 一般建议使用 libxxx.so 的格式, 相对的, 头文件也会被生成在同一目录下, xxx 就是库的名字, 对应到 Java 里加载库的方法就是System.loadLibrary("xxx") 而不是System.loadLibrary("libxxx")
    3. 最后一个是需要编译的 go 文件

CPU 类型和设备类型可以使用go tool dist list查看

macOS 下编译 macos 二进制

macOS 下编译 Windows .dll

macOS 下编译 Linux .so

macOS 下编译 Android .so

macOS 下编译 iOS .a

下面补充其它平台下编译示例

Go多平台交叉编译示例 Windows

在 Windows 下编译 MacOS 和 Linux 的 64 位程序:

Go多平台交叉编译示例 Linux

在 Linux 下编译 MacOS 和 Windows 的 64 位程序:

参考文章