你再也不用設置 GOROOT 了
- 2019 年 11 月 29 日
- 筆記
為什麼不再需要設置 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
。事實上,如果你的電腦上存在多個版本的 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 編譯器(保存在 $GOROOT/pkg/tool/$GOOS_$GOARCH
)和標準庫(在 $GOROOT/pkg/$GOOS_$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
。在官方的 安裝介紹 有相關的描述。
- 如果你是 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
。