如何設置 GOROOT 環境變量?推薦讀兩篇英文文章,我意譯了下,放到了一篇中。
第一篇是關於 Go 1.10 之前,怎麼設置 GOROOT,發表與 2013 年。第二篇是從 Go 1.10 開始,如何處理 GOROOT,時間是 2018 年,Go 源碼提交日誌。這篇非常短小。
第一篇
作者:Dave Cheney | 地址:you-dont-need-to-set-goroot-really[1]
一篇小短文,解釋了為什麼在編譯和使用 Go 時,不需要設置 GOROOT。
概要性介紹
一般來說,在 Go 1.0 之後,編譯和使用 GO 不再需要設置 GOROOT。事實上,如果你的電腦上存在多個版本的 Go 語言環境,設置 GOROOT 可能產生一些問題。
GOPATH 仍然需要設置。
從 Go 1.0 開始,GOPATH 就被強烈推薦。隨著 Go 1.1 的發佈,GOPATH 已經是強制性的了。
為什麼不再要設置 GOROOT?
談些 Go 環境變量的歷史吧!
Go 的資深老前輩們可能還記得,曾經的 Go 不僅要設置 GOROOT,還需要設置 GOOS 和 GOARCH。之所以要設置 GOROOT,是因為 Make 在編譯構建的時候,引入了 GOROOT 中的內容,要提前設置 GOROOT 作為了它們的基本路徑。
隨著 go tool 的引入,Go 1.0 之前,$GOOS 和 GOARCH 已經變成可選了,因為構建腳本已經能自動檢測出系統類別和 CPU 架構。在 Go 1.0 的發佈後,引入了 cmd/dist 引導構建工具,GOOS 和 GOARCH 真正意義上是可選項了,僅僅在交叉編譯時才會用到。
不需要設置 GOOS 和 GOARCH,那 GOROOT 呢?
GOROOT 定義為指定安裝 GO 的根目錄。在之前的 Makefile 中,引入其他 Makefile 時,將它作為基礎路徑。而且,Go 1.0 之後,go tool 利用它查找 Go 編譯器(保存在 GOOS*)和標準庫(在GOROOT/pkg/GOARCH)。如果你是一名 Java 開發者,可以將 GOROOT 理解為 JAVA_HOME。
源碼編譯 Go,GOROOT 將自動發現(all.bash 的上級目錄),然後設置到 go 工具鏈。
如下命令查看:
$ echo $GOROOT $ go env /home/dfc/go
從 golang.org 下載的二進制包或者系統方式安裝的 Go 環境,也已在工具鏈中設置了正確的 GOROOT。
一個例子,比如 Ubutun 12.04 下,安裝了 Go 1.0。
$ dpkg -l golang-{go,src} | grep ^ii $ go /usr/bin/go $ go env GOROOT /usr/lib/go
我們可以看出,Go 工具鏈被安裝在了 /usr/bin/go 下,GOROOT 內置為 /usr/lib/go
為什麼不應該設置 GOROOT
我們不應該設置 GOROOT,是因為 Go 工具鏈已經內置了正確的值。
設置 GOROOT 將會覆蓋掉保存在 go 工具鏈中的默認值,可能會導致 go 執行不同版本的編譯器和標準庫文件。
兩種情況下,你需要設置 GOROOT。在官方的 安裝介紹[2] 有相關的描述。
- 如果你是 Linux、FreeBSD 或者 OS X 用戶,下載了 zip 和 tarball 的二進制包安裝環境。這些二進制的默認環境位於 /usr/local/go,建議你將 Go 安裝到這個位置。如果選擇不這麼做,就必須設置到你指定的目錄下。
- 如果你是 Windows 用戶,使用 zip 二進制包安裝,默認的 GOROOT 在 C:\Go 目錄下。如果你將 Go 安裝在其他位置,請設置 GOROOT 到指定的目錄。
其他細節
本文已經介紹了當通過源碼編譯 Go 環境的時候,GOROOT 如何自動發現的。但如果 GOROOT 與 all.bash 所在位置並不匹配呢?比如,在臨時目錄下編譯 Go 環境,如何正確地設置 GOROOT 呢?答案是使用 GOROOT_FINAL,它將被用於覆蓋自動發現的 GOROOT,設置到 GO 工具鏈中。
舉個例子,在 Debian/Ubuntu 上,構建程序會將 GOROOT_FINAL 的值設置為 /usr/lib/go。保持 GOROOT 是未設置狀態,使構建編譯愉快地執行。構建完成後,將 Go 工具鏈安裝到 /usr/bin 目錄下,編譯器、源碼和包安裝到 /usr/lib/go 下。
注意點
如果使用二進制包安裝 Go 環境,有些特殊情況需要處理,本文已經作了相關描述。
雖然構建系統能自動檢測,但如果 all.bash 的父級目錄不滿足 GOROOT 要求,也需要另外處理。
第二篇
翻譯自 Go 的提交日誌,地址:use os.Executable to find GOROOT[3]。
Go 1.10 開始,通過 use os.Executable 查找 GOROOT。
之前,我們是通過 make.sh 編譯構建 GOROOT,但如果將整個目錄移動到新的路徑下,這會使 Go 工具鏈無法正常工作。
如何解決這個問題呢?
一是可以將源碼重新編譯,但如果新位置在其他用戶的目錄下,可能就無法這麼操作了。
二是,通過設置 GOROOT 環境變量的方式解決,但另外設置 GOROOT 是不推薦的,因為它可能使一個環境下 go tool 使用了另一個環境下 compile。
這次的修改,go tool 將通過相對路徑的方式確定 GOROOT,通過使用 os.Execute 函數。同時,還會檢查 $GOROOT/pkg/tool 目錄是否存在,以避免下面的兩種情況。
$ ln -s $GOROOT/bin/go /usr/local/bin/go
和
$ PATH=$HOME/bin:$PATH $ GOPATH=$HOME $ ln -s $GOROOT/bin/go $HOME/bin/go
另外,如果當前的執行路徑並不在 GOROOT 下,將會通過軟連接找到真正的命令的位置,檢查這個路徑是否是 GOROOT。
參考資料
[1]
you-dont-need-to-set-goroot-really: https://dave.cheney.net/2013/06/14/you-dont-need-to-set-goroot-really
[2]
安裝介紹: http://golang.org/doc/install#install
[3]
use os.Executable to find GOROOT: https://go-review.googlesource.com/c/go/+/42533/