這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
請注意,本文本文含有大量連結。如果是轉載或者使用某些不支援超連結的閱讀器,就請自行腦補吧。
近期,Go Team 連續放出了幾個大招來介紹即將在八月問世的 Go 1.5 這個劃時代的版本。Rob 和 Andrew 分別在《Go in Go》和《The State of Go》中詳細說明了出現在 Go 1.5 中的重要特性和細節變化。在這個版本中最主要的變化是移除了所有 C 代碼,不論是 runtime 還是編譯器都使用 Go 語言和一小部分的彙編來實現——也就是人們常說的自舉。但是這樣做也就意味著,Go 在 1.5 和以後的版本中,使用原始碼構建 Go
開發環境將面臨“雞生蛋,蛋生雞”的麻煩(當然了,如果你直接“買雞蛋”——使用二進位安裝包——是沒有這個問題的)。
在 Go1.4 及更早的版本中,會使用 GCC 先編譯一個使用 C 語言編寫的,僅具有準系統的小編譯器作為構建 Go 環境的引導工具。也就是說必須要安裝 GCC、make 等 C 語言相關的工具才能從原始碼構建 Go 的開發環境。而據 Rob 的講義和其撰寫的《Go 1.5 Bootstrap Plan》中介紹的,Go 1.5 將不再有 C 語言的參與,反而需要使用 Go 1.4 版本的工具鏈進行編譯。那麼也就意味著,從原始碼開始構建 Go 1.5 需要兩個版本並存。幾年前,有許多人折戟在 GOROOT/GOPATH 的坑裡。現在還需要兩個版本的 Go 並存,想想似乎都是個挺麻煩的事情。
對於 Go 來說,大道至簡!所以通過這篇文章裡我想簡單介紹一下如何使用原始碼構建 Go 1.5 開發環境。由於“雞生蛋,蛋生雞”的緣故,需要從構建 Go 1.4 的開發環境開始講起。
需要說明的是,以下所有內容都是在 Ubuntu 14.04 中示範操作的,但只要是符合 POSIX 標準的系統,以下操作應該都是一致的。Windows 的使用者我強烈建議還是使用二進位包進行安裝。不折騰!
準備工作
一個“乾淨”的系統是必須的,這裡的“乾淨”是指沒有設定過 GOROOT/GOPATH/GOBIN 之類的環境變數。如果之前已經配置過 Go 的環境,那隻能酌情調整或刪除重新設定了。
同時,由於需要編譯 Go 1.4,所以必須安裝 C 相關的工具:
$ apt-get install gcc libc6-dev
##目錄結構
2012 年的時候,我曾經翻譯過一篇文章《GO 環境設定》。雖然那個時候 Go 的代碼還在使用 hg 進資料列版本設定,同時 Go 1 也沒有正式發布,不過那篇文章中介紹的目錄設定方式,我卻一直使用至今,其結構如下:
$HOME/golang/├── 3rdpkg├── go└── own
其中 $HOME/golang/3rdpkg,$HOME/golang/go 和 $HOME/golang/own 目錄應按照順序加入環境變數 GOPATH 中。這樣的好處是在使用 go get 擷取 Go 包的時候會直接匯入到 GOPATH 的第一個路徑,也就是 3rdpkg 這個子目錄中。這樣可以將第三方包,Go 的代碼和自己的工作目錄區分開來。
不過,由於 Go 1.5 需要兩個版本的 Go 並存,那麼這個目錄結構也就需要做相應的調整。最終如下,稍候我會詳細介紹。
環境變數
前面已經提到了 GOPATH 的設定:
GOPATH=$HOME/golang/3rdpkg:$HOME/golang/go:$HOME/golang/own
由於現在有兩個版本的 Go 代碼並存,所以我們需要建立一個軟連結指向所需要的版本的代碼目錄,例如:
$HOME/golang/├── 3rdpkg├── go -> go1.4/├── go1.4└── own
這樣,就 GOROOT 的值就應該設定為:
GOROOT=$HOME/golang/go
有了這兩個環境變數就足夠了(交叉編譯和環境微調不在本文討論範圍內)。
為了能夠方便的使用 go 命令,還需要將 $GOROOT/bin/ 加入 PATH 中:
PATH=$PATH:$GOROOT/bin/
安裝 Go 1.4
使用 git 命令擷取 Go 1.4 的完整代碼。當前最新的 1.4 版本是 1.4.2,所以:
$ cd $HOME/golang/$ git clone -b go1.4.2 https://github.com/golang/go.git go1.4
然後讓 GOROOT 的軟連結目錄指向實際儲存 Go 1.4 代碼的目錄:
$ ln -s go1.4 go
這時目錄結構為:
$HOME/golang/├── 3rdpkg├── go -> go1.4/├── go1.4└── own
環境變數的值為:
GOPATH=$HOME/golang/3rdpkg:$HOME/golang/go:$HOME/golang/ownGOROOT=$HOME/golang/goPATH=$PATH:$GOROOT/bin
進入目錄 $HOME/golang/go/src,運行 all.bash 指令碼。
cd $HOME/golang/go/src./all.bash
經過一個短暫的編譯和一個漫長的測試之後,Go 1.4 應該就部署完成了。
使用 go version 命令可以看到當前 Go 版本為 1.4.2:
$ go version go1.4.2 linux/amd64
安裝 Go 1.5
由於 Go 1.5 需要基於 Go 1.4 構建,所以 Go 1.5 需要一個獨立的目錄放置(實際上用同一個目錄是可以的,不過需要額外的許多設定,不折騰)。
由於已經複製了 Go 的程式碼程式庫,可以直接複製 go1.4 這個目錄到目錄 go1.5,然後用命令:
$ go checkout -b master
切換到 Go 1.5 所在的代碼分支中。
有一點需要特別說明一下:由於 Go 1.5 預計要到八月才正式發布,所以要到那個時候才會有 go1.5 這個標籤出現。因此,當前的 master 分支實際上就是功能凍結的 Go 1.5 的代碼分支。
由於已經將 GOROOT 設定為 $HOME/golang/go,因此只需要這個軟連結重新指向 Go 1.5 代碼所在目錄即可,而無須修改環境變數。
$ cd $HOME/golang$ unlink go$ ln -s go1.5 go
為了能夠編譯 Go 1.5,還需要額外設定一個叫做 GOROOT_BOOTSTRAP 環境變數,指向 Go 1.4 所在的目錄。同時為了能夠向後相容,這個變數也使用軟連結的方式進行指向:
$ ln -s go1.4 go-bootstrap
這時目錄結構為:
$HOME/golang/├── 3rdpkg├── go -> go1.5/├── go-bootstrap -> go1.4/├── go1.4├── go1.5└── own
環境變數的值為:
GOPATH=$HOME/golang/3rdpkg:$HOME/golang/go:$HOME/golang/ownGOROOT=$HOME/golang/goPATH=$PATH:$GOROOT/binGOROOT_BOOTSTRAP=$HOME/golang/go-bootstrap
進入目錄 $HOME/golang/go/src,運行 all.bash 指令碼。
$ cd $HOME/golang/go/src$ ./all.bash
又一個短暫的編譯和一個漫長的測試之後,Go 1.5 應該就部署完成了。
使用 go version 命令可以看到當前 Go 版本為開發編號:
go version devel +6551803 Wed May 27 04:48:29 2015 +0000 linux/amd64
對於持續跟蹤 Go 程式碼程式庫的開發人員來說,保持這樣的一個目錄結構可以讓以後的升級變得更為輕鬆。只需要建立新版本的代碼目錄,並調整軟串連的指向,然後編譯即可得到新版本的開發環境。