你真的不用再設置 GOROOT 了

你真的不用再設置 GOROOT 了

如何設置 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/


分享到:


相關文章: