Skip to content

编译 ​

解决如何将源代码编译为不同操作系统CPU架构能够直接运行的可执行二进制文件

编译的问题 ​

编译问题的原因:

  1. 由于 go 是一门静态类型的语言, 需要编译为二进制文件才能运行
  2. 不同的 CPU架构的指令是不同的(x86/arm64), 这就导致不同 CPU架构 的可执行二进制文件是不一样的
  3. 不同的操作系统(MacOS/Windows)的可执行二进制文件也是不同的, 这就导致不同操作系统的的可执行二进制文件是不一样的
  4. 总结 2,3 来说: 不同的操作系统 和 不同的 CPU 架构的 可执行二进制文件 都是不一样的

假设我只有一台电脑, 我如何将同一份 go 源码编译成可以适用 不同CPU架构(amd64/arm64) 和 & 操作系统(Windows/macOS/Linux) 的可执行二进制文件呢? 此时就需要: 交叉编译

本地编译 & 交叉编译 ​

  • 本地编译(Native Compilation)

编译环境、编译器运行环境与目标代码运行环境完全一致

在 MacOS/arm64 编译出可以在 MacOS/arm64 平台的可执行二进制文件

  • 交叉编译(Cross-Compilation)

是指在一种特定CPU架构(如: amd64/arm64)或操作系统上(如:Windows/Linux/MacOS), 使用特定的编译工具链, 生成其他不同CPU架构或操作系统上可执行的二进制代码的过程

比如: 在 Windows/x86 平台编译出可以运行在 Windows/arm64 平台的可执行二进制文件

编译工具了解 ​

将源代码编译为可执行二进制的工具, 这样的编译工具可以有多个, 这个很好理解

将带有细菌的冷水 -> 烧开为没有细菌的热水

  1. 使用柴火加热可以将水变成开水
  2. 使用热水壶也可以将水变成开水

内置构建工具 ​

官方提供的编译工具, 只要安装了 go 开发环境就自带的编译工具

go build -o xxx 主要是依赖 GOOS 和 GOARCH 两个环境变量来决定打包什 么操作系统+CPU架构的二进制文件, 需要自己手动处理 cgo 依赖等问题

sh
# 查看环境变量
# GOOS:   操作系统名称
# GOARCH: CPU架构(arm/amd64)
go env GOOS GOARCH

# 基础用法
go build . -o bin

xgo ​

xgo 是基于 Docker 环境的 Go 交叉编译器,能够轻松编译跨多个平台和架构的Go项目, 并且可以自动处理依赖CGO的项目, 核心功能聚焦于打包出对应平台的二进制文件

goreleaser ​

goreleaser 是集编译、打包(tar/zip/deb/rpm)、签名、生成 Changelog、发布到 GitHub/GitLab 等功能于一体的软件, 主要用于 CICD 环境, 如用于 Github Actions 的 goreleaser-action

  1. 它适合用于纯 Go 项目(无 CGO 依赖), 如果有 CGO 依赖, 还需要集成 xgo 用于打包
  2. 它也可以用来管理其他语言项目的编译&发布(比如 nodejs 项目: npm run build & publish to npmjs.com)

xgo 基本使用 ​

  1. 下载 docker 容器: docker pull techknowlogick/xgo:latest
  2. 下载 xgo 命令: go install src.techknowlogick.com/xgo@latest
  3. 打包你的项目
sh
cd go-demo

# 打包所有操作系统所有架构的二进制包
xgo .

# 仅打包 windows 系统 CPU 架构为 amd64 和 arm64的二进制包
xgo --targets=windows/amd64,windows/arm64 .

# 打包 windows 系统所有 CPU 架构的二进制包
xgo --targets=windows/* .

# 打包 Mac 和 linux 系统所有 CPU 架构的二进制包
xgo --targets=darwin/*,linux/* .

goreleaser 基本使用 ​

  1. 初始化项目: mkdir go_demo && cd - go mod init go_demo
  2. 安装 goreleaser 命令: go install github.com/goreleaser/goreleaser/v2@latest
  3. 初始化 .goreleaser.yaml 配置文件: goreleaser init
  4. 发布版本: goreleaser release --snapshot --clean
    • --snapshot: 生成一个快照版本, 而非正式的发布版本(这只是在本地编译打包, 正式发布会同步到Github)
    • --clean: 在执行发布命令之前, 强制清理输出目录(dist)

执行 发布版本 的命令后 会自动编译 + 打包 -> 生成符合配置文件中配置的操作系统平台&CPU架构的二进制可执行文件

更多详细使用方式请阅读官网文档

部署 ​

如何将打包后的代码运行起来(手动执行? Docker 执行?)

分发 ​

解决如何管理源代码的迭代问题, 以及将将二进制文件发布到不同的工具平台(winget/brew/apt/yum)

Released under the MIT License.