本文档描述了 Go 编程语言的构建、测试和发布过程。它侧重于 Go 本身的开发方式,而不是如何使用 Go 开发软件。本文档解释了支持 Go 开发周期的工具以及对 Go 存储库进行更改所涉及的步骤。
Go 使用一个以 dist 工具为中心定制的构建系统,该工具负责引导过程、编译和测试。该工具通过采用多阶段方法来处理使用 Go 构建 Go 的复杂性,从而解决了引导难题。
来源: src/cmd/dist/build.go25-606 src/cmd/dist/build.go490-606
构建系统依赖几个环境变量来控制其行为。这些变量在 dist 工具中的 xinit() 函数中进行初始化。
| 环境变量 | 目的 |
|---|---|
| GOROOT | Go 存储库的根目录 |
| GOOS | 目标操作系统 |
| GOARCH | 目标架构 |
| GOARM, GOARM64, GO386 等 | 特定于体系结构的选项 |
| GOHOSTOS, GOHOSTARCH | 主机操作系统和体系结构 |
| GOEXPERIMENT | 要启用的实验性功能 |
| GOFIPS140 | FIPS 140 模式配置 |
来源: src/cmd/dist/build.go109-278 src/cmd/dist/build.go490-606
Go 的引导过程是一个多阶段编译过程,解决了使用 Go 编译 Go 的鸡生蛋还是蛋生鸡的问题。该过程分为几个阶段:
在引导过程中
setup() 函数准备目录结构go_bootstrap)go_bootstrap 构建实际的 Go 工具链来源: src/cmd/dist/build.go525-606 src/cmd/dist/build.go677-1063
Go 的构建系统采用基于包的编译方法,由 install() 和 runInstall() 等函数管理。这些函数负责编译单个包、解析依赖项并将生成的工件放置在适当的位置。
包安装的关键步骤
来源: src/cmd/dist/build.go677-1063 src/cmd/dist/buildgo.go31-64
Go 项目使用一个全面的测试框架,由 dist test 命令管理。测试由 tester 结构协调,该结构处理许多不同类型的测试。
测试类型包括
go test std cmd)-race 标志)-msan 标志)-asan 标志)来源: src/cmd/dist/test.go27-275 src/cmd/dist/test.go543-994 src/cmd/dist/testjson.go17-27
Go 中的测试是高度并行化的,并进行了仔细的依赖管理。work 结构表示一个测试作业,而 tester 结构协调执行。
测试执行的关键方面
-run 正则表达式过滤测试-compile-only)-k 标志)-json 标志)来源: src/cmd/dist/test.go83-94 src/cmd/dist/test.go112-275 src/cmd/dist/testjson.go17-27
Go 支持广泛的架构和操作系统,并为不同平台提供专门的处理。
平台支持的差异通过以下方式处理:
来源: src/internal/platform/supported.go19-34 src/internal/platform/zosarch.go10-57 src/cmd/dist/build.go70-106
Go 支持多种构建模式,这些模式会影响代码的编译和链接方式。buildModeInit() 函数在 build 包中配置这些模式。
| 构建模式 | 描述 |
|---|---|
| archive | 常规包归档 (.a 文件) |
| c-archive | C 兼容的归档,可以链接到 C 程序中 |
| c-shared | C 兼容的共享库 (.so, .dll, .dylib) |
| 默认 | 默认可执行文件(在某些平台上可能是 PIE) |
| exe | 强制非 PIE 可执行文件 |
| pie | 位置无关的可执行文件 |
| shared | 用于动态链接的 Go 共享库 |
| plugin | 可加载插件 (go plugin) |
来源: src/cmd/go/internal/work/init.go188-342 src/cmd/link/internal/ld/config.go13-114
Go 使用语义化版本控制,并采用独特的版本标识方案。版本信息来自多个来源:
src/internal/goversion/goversion.go 中的内部版本号findgoversion() 中构造版本字符串,格式如下:
go1.21.0 (用于发布版本)devel go1.21-abc123 (用于开发版本)来源: src/cmd/dist/build.go362-445
在对 Go 仓库进行更改时,开发者遵循以下工作流程:
./make.bash 或 ./make.bat 构建 Gogo test 或 dist test 运行相关测试来源:src/cmd/dist/test.go956-994 src/cmd/dist/build.go109-154
Go 构建系统支持通过环境变量和编译器配置进行交叉编译。
交叉编译在构建系统中拥有特殊的处理方式,包括不同的链接策略和编译器标志。compilerEnv() 函数通过将不同的编译器设置映射到不同的目标平台来管理这种复杂性。
来源:src/cmd/dist/build.go280-319 src/cmd/dist/build.go609-656
Go 的开发工作流程结合了自定义构建系统和全面的测试,以确保在众多平台上发布高质量的软件。dist 工具协调这一过程,处理引导的挑战、依赖管理和特定于平台的各种需求。理解这个工作流程对于任何为 Go 本身做出贡献的人来说都是至关重要的。