今天看到@polaris1119的這篇分析源碼安裝Go的過程(初稿)
至今還沒仔細看過make.bash的內容。這篇算是閱讀筆記了。
環境變量
首先是make.bash中用到的環境變量:
GOROOT_FINAL:Go源碼的根目錄,這個變量的是在gcc的時候使用的,如果你設置了這個,gcc的-D參數就是你設置的
GOHOSTARCH:Go所在的宿主機器的架構,當然這里指的是CPU的架構
GOARCH:安裝包和工具所在的機器的架構。
GOOS:安裝包和工具所在的機器的操作系統。
GO_GCFLAGS:是否要在編譯的時候需要帶上5g/6g/8g的參數
GO_LDFLAGS:是否要在鏈接的時候帶上5l/6l/8l的參數
CGO_ENABLED:是否能使用cgo
對於環境變量,你可以在編譯完成后使用dist工具來查看,比如:
yejianfengtekiMacBook-Air:darwin_amd64 yejianfeng$ ./dist env
GOROOT="/Users/yejianfeng/software/go"
GOBIN="/Users/yejianfeng/software/go/bin"
GOARCH="amd64"
GOOS="darwin"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOTOOLDIR="/Users/yejianfeng/software/go/pkg/tool/darwin_amd64"
GOCHAR="6"
為什么有GOARCH和GOHOSTARCH的分別?
下面一個情境:amd64的機器上,下載了一份源碼,所以GOHOSTARCH是設置成為AMD64,但是我現在想寫的是Intel X86-32的Go可執行文件,所以設置GOARCH為Intel86。這就是交叉編譯的概念。
當然這兩個環境變量是在編譯出go工具的時候才有用,具體的編譯go代碼就沒用了。
GOTOOLDIR是什么?
go tool命令后面可以跟其他的工具,比如pprof, yacc, api等。go tool實質上只是一個轉發命令給這些工具,這些工具的源代碼是放在goroot/src/cmd下面,這些工具的源碼編譯之后生成的二進制可執行文件就放在$GOTOOLDIR里面,具體的路徑就在goroot/pkg/tool/(darwin_amd64)/下。
這個變量是在這句話中設置的
eval $(./cmd/dist/dist env -p)
go_bootstrap是什么?
我們可以看到go_bootstrap這個工具是使用dist工具bootstrap生成的。然后再使用go_bootstrap install來編譯go的包。最后又悄悄地把go_bootstrap刪掉。
我們還原一下,進入GOTOOLDIR,調用./dist bootstrap重新生成go_bootstrap
運行下你會發現,原來就是bin/go嘛,但是再看看大小,只有3M多,而完整的bin/go有5.6M。
所以可以推斷go_bootstrap是包含了基本的go代碼編譯能力的工具。
整個make的流程是什么樣的?
其實也是幾句話就能說清楚:
1 先gcc編譯出dist
2 dist編譯出go代碼基本編譯器go bootstrap
3 用go bootstrap編譯出go的src中的其他go源碼
4 將其他所有工具生成放在src/cmd下供bin/go使用