dist是用来编译go语言的工具,而且dist本身是由go语言写的
所以可以用低版本的go编译dist, 再用dist编译高版本的go
/src/cmd/dist是go dist工具的代码目录
main.go中的main为入口函数
主要的流程为
- 检测操作系统
- 检测系统架构
- bginit() //启动一组后端运行的goroutine, 用于在后台运行go
- xinit() //初始化全局变量/状态
- xmain() //执行全局commands变量中存储的操作
- xexit() //资源检查/进程退出
查看usage()函数可知
func usage() {
xprintf(`usage: go tool dist [command]
Commands are:
banner print installation banner
bootstrap rebuild everything
clean deletes all built files
env [-p] print environment (-p: include $PATH)
install [dir] install individual directory
list [-json] list all supported platforms
test [-h] run Go test(s)
version print Go version
All commands take -v flags to emit extra information.
`)
xexit(2)
}
查看commands的定义
// commands records the available commands.
var commands = map[string]func(){
"banner": cmdbanner,
"bootstrap": cmdbootstrap,
"clean": cmdclean,
"env": cmdenv,
"install": cmdinstall,
"list": cmdlist,
"test": cmdtest,
"version": cmdversion,
}
着重看cmdbootstrap流程
cmdbootstrap流程中
- 检查rebuildall, debug, nobanner三个参数
- setup() //初始化变量
- checkCC() //检查C++编译器
- bootstrapBuildTools() //编译bootstrap工具链,主要的目录都列在了bootstrapDirs变量中
- install("runtime")
- install("cmd/go")
- goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...)
- goInstall(goBootstrap, append([]string{"-a", "-i"}, toolchain...)...)
- goInstall(goBootstrap, targets...)