1、下载源码

首先需要下载Go源码最好使用git下载

git clone https://github.com/golang/go.git

因为编译源码时需要源码是Git仓库,否则会无法编译
下载完成后进入Go源码目录执行

git checkout release-branch.go1.4

切换代码到1.4版本
为什么使用1.4版本?
因为1.4之前的版本使用的版本控制工具是Mercurial,至于为什么用的是Mercurial,可以看上一篇文章Go的版本控制历史
所以1.4之前的版本需要安装Mercurial,故不建议用之前的版本。

那为什么不用最新的版本呢?
编译1.4之后的版本需要用到已编译好的go二进制程序,没错就是套娃,如果你想要编译Go1.4之后的版本,那你要先有Go1.4或1.4之后的版本。就好像,如果你在野外想要做一把锤子,那你可以先用石头砸出一把简易的锤子,之后在用这把简易的锤子做出更好的锤子。而c就像石头,而这把简易的锤子就是1.4版本的Go。
而编译新版本也可以用1.4编译出来的可执行文件做依赖。所以1.4版本简单上手,而且用处多多。

2、安装Git

如果已完装过Git就可以跳过了,确保git命令可用,windows系统在cmd内git命令可用。
Git安装地址:https://git-scm.com/downloads
官网下载安装包,安装流程就不多赘述了。

3、安装GCC

Go1.4及之前版本的工具链包含C语言实现的模块,所以需要GCC,如已有gcc指令则不用在安装了,跳过即可。

在 OS X 上,C 编译器捆绑在Xcode的命令行工具中 ,您无需安装整个 Xcode 即可编译 Go。如果您已经安装了 Xcode 4.3+,您可以从“下载”首选项面板的“组件”选项卡中安装命令行工具。在更新的 Xcode 版本中,您可以使用xcode-select --install command 来安装命令行工具,而无需打开 Xcode。要验证您有一个工作编译器,只需gcc 在新创建的终端窗口中调用,除非您看到 "gcc: command not found"错误,否则您已准备好开始。

在 Ubuntu/Debian 上,使用sudo apt-get install gcc libc6-dev. 如果您想在 64 位系统上构建 32 位二进制文​​件,您还需要该libc6-dev-i386软件包。

在 RedHat/Centos 6 上,使用sudo yum install gcc glibc-devel. 如果您想在 64 位系统上构建 32 位二进制文​​件,您将需要 glibc-devel.i386和glibc-devel.x86_64包。

在 Windows 上,gcc使用 TDM-GCC安装。(确保将其bin子目录添加到您的PATH)Go 不支持 Cygwin 工具链。

4、编译运行

接下来,准备工作就完成了,我们可以在Go源码中加一点自己的代码,以测试是否编译成功。
例如:在Go源码目录下 src/fmt/print.go 中找位置插入如下代码

func MyPrintln() {
    Println("this is MyPrintln")
}

然后在进入终端或cmd,cd进Go源码所在的目录

cd src
./all.bash

Windows 使用 all.bat

C:\...\go> cd src
C:\...\go\src> all.bat

编译完成后即可在Go源码目录 bin 目录下看到 go 或 go.exe 可执行文件
然后可以直接在 bin 目录下写一段代码测试一下是否成功。
如在 bin 目录下新建 main.go 文件,内容为

package main

import "fmt"

func main() {
    fmt.MyPrintln()
}

然后在bin目录下执行

./go run main.go

this is MyPrintln

Windows下

go.exe run main.go

this is MyPrintln

如成功运行,则说明成功了。当然也可以把 main.go 写在其它地方,此处写在bin目录下是不合理的(bin目录下不应该有源码),但此处是为了好测试,所以才写到bin目录下的。

5.编译新版本

如果只是想看一些基础的源码,那1.4版本完全是够用的,但如果需要看 syn.Map 之类的新源码,那用1.4版本就不行了,那这里也教一下大家怎么借用刚才编译好的go 1.4来编译新版本。
首先将刚才编译好的 go1.4 的整个源码目录拷贝到其它位置,例如,我就放到了用户目录中
Linux /home/{用户名}/Go1.4/
Windows C:\Users{用户名}\Go1.4\

注意是整个源码目录,要包含 src目录下的源码,还要有 bin目录下编译好的可执行文件 !

拷贝完成后的备份就不要动了,然后回到之前的Go源码,先检出代码,以1.17为例,go源码根目录下执行:

git checkout release-branch.go1.17
git clean -fdx  #清理之前编译后的残留,会影响1.17的编译,也可手动清理

注意!不要在拷贝后的目录内执行这条命令,要回到之前的目录执行,拷贝到 ~/Go1.4 内的代码要保持 1.4 的版本

然后我们需要设置环境变量,告诉Go程序去哪找go1.4,注意路径后面不要加bin,编译时程序会去找 $GOROOT_BOOTSTRAP/Go1.4/bin ,所以在设置GOROOT_BOOTSTRAP时不用加后面的bin目录了。

export GOROOT_BOOTSTRAP=/home/{用户名}/Go1.4

Windows

SET GOROOT_BOOTSTRAP=C:\Users\{用户名}\Go1.4

最后同样的在1.17源码的src目录下,修改 src/fmt/print.go
增加一个函数

func MyPrintln() {
    Println("MyPrintln go 1.17")
}

然后进入 src 目录,执行编译命令

./all.bash

Windows

.\all.bat

编译完成后会进入Package Tests检查,可能会有一些gcc相关的库报错,可以忽略。
最后同相的进入 bin 目录,增加测试文件 main.go 和之前的相同,执行

./go run main.go

MyPrintln go 1.17

Windows

go.exe run main.go

MyPrintln go 1.17