Golang源码构建指南:从源代码编译Go
Golang源码构建指南:从源代码编译Go 这是大型小组活动gophersource的一部分,你可以加入其中学习如何为上游Go项目及其他开源项目做贡献。
-
查找从源码构建Go的文档 ✅ https://golang.org/doc/install/source
-
Go 是用… Go 编译的!🤯 我需要决定是引导一个Go编译器,还是使用我电脑上已有的Go。我比较懒,所以选择后者。✅
-
$GOROOT_BOOTSTRAP是一个必须设置的环境变量,指向我要使用的Go编译器的位置。因为我使用的是Mac上已有的常规Go安装,所以我通过export GOROOT_BOOTSTRAP=$(go env GOROOT)来设置它。我通过运行$GOROOT_BOOTSTRAP/bin/go并确保看到了Go帮助文本来测试它是否工作。 -
克隆Go源代码
git clone https://go.googlesource.com/go。我不确定是否需要将其放在GOPATH下(我猜不需要?)。 -
切换到go源码目录并运行
git tag,欣赏一下有多少标签,看看可以从哪个版本开始构建。我选择了最新的git checkout go1.11beta1。 -
切换到仓库中的
src/目录,然后运行./all.bash。立刻就后悔在我的Mac Book Air上做这件事了。 -
有一个测试失败了,是关于
os/signal的,出现了一些奇怪的超时。我打算把这归咎于我的旧笔记本电脑,并祈祷一切顺利! -
既然测试失败了,我就绕过它们,只用
./make.bash进行构建和安装。 -
将我当前的shell会话从使用稳定版Go切换到我刚刚构建的版本:
$ go version go version go1.10 darwin/amd64 $ which go /usr/local/go/bin/go $ export PATH=/Users/carolynvs/src/go/bin:$PATH $ which go /Users/carolynvs/src/go/bin/go $ go version go version devel +a12c1f26e4 Tue Jun 26 20:00:51 2018 +0000 darwin/amd64 -
好的,现在如何调整它才能启用新的vgo原型功能呢?在这里找到了Pull Request(Google喜欢称它们为CL):https://go-review.googlesource.com/c/go/+/118095
… 短暂插曲,享受我的周末 …
天气更新:芝加哥还是太热了,所以继续捣鼓!
我了解到vgo原型已经合并到上游Go中,但它被关闭了。我创建了一个分支将其重新启用。原型的代码位于 src/cmd/go/internal/vgo,还没有完全连接到所有命令。看起来 go build 可以工作,并且使用了原型,但像 go list -m 这样的功能还没有连接好。
我创建了一个示例仓库来试用我本地构建的精良Go版本。go.mod 文件的存在是为了告诉Go我们想使用所有酷炫的新功能。我把它留空,这样当我运行 go build 时,它会检测我的依赖项并为我填充该文件。
$ go run main.go
vgo: resolving import "github.com/pkg/errors"
vgo: finding github.com/pkg/errors (latest)
vgo: adding github.com/pkg/errors v0.8.0
hello world!
太棒了!💃
我们已经从源码构建了Go,编辑源码以启用vgo原型,调整了我们的PATH以便试用我们的自定义构建,并且看到了一些输出,这让我觉得我做对了。🎉
更多关于Golang源码构建指南:从源代码编译Go的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个不同的 vgo。有关预期版本(包括文章和视频)的更多信息,请参阅 https://github.com/golang/go/wiki/vgo。https://www.youtube.com/watch?v=F8nrpe0XWRg 是一个很好的介绍。
更多关于Golang源码构建指南:从源代码编译Go的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
今天了解到 vgo 原型尚未完全集成到上游主 go 命令中。因此,如果你想试用原型中的 go get 功能,目前仍需直接使用 vgo 原型。目前似乎只有 go build 功能已完成集成。
待有变化时我会再回来汇报!
rot13:
我很惊讶你使用了 git 克隆(开发版本)而不是下载并解压 go1.10.3.src.tar.gz
这个帖子以及所有标记为 [gophersource] 的帖子的目的是学习如何成为 Go 贡献者。这就是为什么我遵循官方 Go 文档的说明,并使用 git:这样在我们进行更改时,我们可以向上游提交拉取请求。
你好,
只是想告诉你我成功使用 go1.11beta1 完成了构建并通过了测试。不过我还无法在构建中启用 vgo。请问你是如何实现的? 我的项目安装在文件系统的任意位置,这似乎没有造成任何影响。 你了解这个代码库吗?http://vgo.readthedocs.io/en/latest/installation.html 我刚刚安装完成,稍后会进一步尝试。祝你今天愉快。
看起来Russ已经完成了将vgo原型集成到上游Go的工作,现在被称为"go模块"支持。🎉
https://groups.google.com/forum/#!msg/golang-dev/a5PqQuBljF4/61QK4JdtBgAJ
所以我打算这个周末试用一下,看看它是否能完全替代我的补丁,让我们继续尝试使用它。
如果你正在跟着学习(我希望你是!),我们已经弄清楚了如何从源代码构建,但还没有深入分析底层发生了什么。我想了解更多关于:
- 当我运行
./src/make.bash时发生了什么?看起来它构建然后重新构建了代码? - 为什么我无法成功运行所有测试?
- 似乎我不需要将 Go 源代码克隆到 GOPATH 中。这是正确的还是我以后会后悔?

如果你有更多问题,或者甚至能给我一些答案,请分享!
我无法在构建中激活vgo。你是怎么做到的?
我移除了禁用vgo原型的硬编码功能标志。这个改动非常小
// 代码变更内容
在检出主分支并拉取最新代码后,我现在可以使用"Go模块"了(这是vgo原型所添加功能的长期名称)!😎
许多有趣的代码位于 src/cmd/go/internal/modload/init.go 中。我建议从那里开始了解Go模块何时被启用,并以此跟踪go工具链中其他代码(如get或build)何时使用它们。到目前为止,只需查找谁在调用 modload.Enabled 或搜索术语 modload. 似乎是查看代码库中哪些地方添加了特殊"go模块"功能的好方法。
我今天将写一篇博客文章,整理我的笔记并为人们提供"最短的成功路径",并在此处添加链接。
func main() {
fmt.Println("hello world")
}
在Linux(Ubuntu 18.04)上从源码构建Go
这是我在全新系统(之前未安装Go)上按照官方文档从源码构建/设置Go的方法。
-
创建一个空的
$HOME/go目录 -
下载并将 go1.4源码分发版 解压到
$HOME,将刚解压的目录重命名为go1.4 -
要构建引导工具链,请运行以下命令:
$ cd $HOME/go1.4
$ ./make.bash
(对我来说不需要设置 CGO_ENABLED=0)
- 获取Go仓库并安装所需版本:
$ cd /usr/local/
$ git clone https://go.googlesource.com/go
要安装和切换版本,检出稳定版本的分支,例如 git checkout go1.10.3,或者留在 master 分支以使用开发版本,然后运行:
$ cd /usr/local/go/src/
$ ./all.bash
构建和运行所有测试需要一些时间。完成后,将以下内容添加到您的 ~/.profile、~/.bash_profile 或您使用的任何在启动shell时执行的文件中。
export GOROOT=/usr/local/go
export PATH=$PATH:/usr/local/go/bin
export PATH=$PATH:/home/[YOUR USER]/go/bin
应用更改:
$ source ~/.profile
- 验证安装的版本
$ go version
go version devel +f17220c208 Tue Jul 17 05:41:06 2018 +0000 linux/amd64
VGO / Go模块
如果您安装了 master 分支,自 CL 123580 起这些功能将默认可用。有关用法的更多信息,请在CLI上运行 go help modules
以下是关于从源代码编译Go的详细步骤和示例代码,基于你的描述和官方文档。这个过程适用于想要构建自定义Go版本或为上游贡献的开发人员。
环境准备和引导编译器设置
首先,设置 GOROOT_BOOTSTRAP 环境变量,指向现有Go安装的根目录。这用于引导编译过程。
# 设置引导编译器路径(假设使用系统已安装的Go)
export GOROOT_BOOTSTRAP=$(go env GOROOT)
# 验证引导编译器是否工作
$GOROOT_BOOTSTRAP/bin/go version
输出应显示当前Go版本,例如:go version go1.10 darwin/amd64。
克隆和准备Go源代码
Go源代码存储在Git仓库中,不需要放在GOPATH下。
# 克隆Go源代码仓库
git clone https://go.googlesource.com/go
cd go
# 查看可用标签并选择版本(例如go1.11beta1)
git tag
git checkout go1.11beta1
构建Go
进入源代码的 src/ 目录,运行构建脚本。如果测试失败,可以使用 make.bash 跳过测试。
cd src
# 完整构建和测试(可能耗时较长)
./all.bash
# 如果测试失败(如os/signal超时),仅构建和安装
./make.bash
构建成功后,二进制文件将生成在 go/bin/ 目录中。
切换到自定义构建的Go版本
更新PATH环境变量以使用新构建的Go。
# 检查当前Go版本
go version
which go
# 添加自定义Go到PATH(假设构建路径为/Users/carolynvs/src/go)
export PATH=/Users/carolynvs/src/go/bin:$PATH
# 验证切换
which go
go version
输出应显示自定义版本,例如:go version devel +a12c1f26e4 Tue Jun 26 20:00:51 2018 +0000 darwin/amd64。
启用实验性功能(如vgo)
vgo原型已合并到上游但默认关闭。可以通过修改源代码启用它。例如,在分支中启用vgo:
# 假设使用自定义分支(如go1.11beta1-vgo-enabled)
git checkout go1.11beta1-vgo-enabled
# 重新构建以应用更改
cd src
./make.bash
vgo相关代码位于 src/cmd/go/internal/vgo。构建后,可以使用vgo功能,如模块支持。
测试自定义构建
创建一个示例项目来验证vgo功能。项目根目录包含 go.mod 文件(可为空),Go会自动解析依赖。
示例项目结构:
go-depmgmt-testrepo/
├── go.mod
└── main.go
main.go 内容:
package main
import (
"fmt"
"github.com/pkg/errors"
)
func main() {
err := errors.New("example error")
fmt.Println("Error:", err)
fmt.Println("hello world!")
}
运行项目:
cd go-depmgmt-testrepo
go run main.go
输出应显示vgo解析依赖的过程:
vgo: resolving import "github.com/pkg/errors"
vgo: finding github.com/pkg/errors (latest)
vgo: adding github.com/pkg/errors v0.8.0
hello world!
总结
这个过程演示了从源代码编译Go、启用实验性功能以及测试自定义构建。关键步骤包括设置引导编译器、构建源代码、切换PATH和使用模块功能。如果在构建中遇到测试失败,可以跳过测试以节省时间。

