你再也不用設定 GOROOT 了
為什麼不再需要設定 GOROOT
呢?推薦讀兩篇英文文章,我意譯了下,將它們放在了一篇裡。
第一篇是關於 Go 1.10 之前,怎麼設定 GOROOT
,發表與 2013 年。第二篇是從 Go 1.10 開始,如何處理 GOROOT
,時間是 2018 年,Go 原始碼提交日誌。這篇非常短小。
讀完後,你會發現,大多數情況下,我們都不用手動設定 GOROOT
了。
第一篇
作者:Dave Cheney | 地址:you-dont-need-to-set-goroot-really
一篇小短文,解釋了為什麼在編譯和使用 Go 時,不需要設定 GOROOT
。
概要性介紹
一般來說,在 Go 1.0 之後,編譯和使用 GO 不再需要設定 GOROOT
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 編譯器(儲存在 $GOROOT/pkg/tool/$GOOS_$GOARCH
)和標準庫(在 $GOROOT/pkg/$GOOS_$GOARCH
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
。在官方的 安裝介紹 有相關的描述。
- 如果你是 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。
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
。