配置 1.13+ 的 golang 環境

以前寫過《配置 Golang 開發環境》(go < 1.13, win64)。然後 1.13 是一個重大變更,大到需要原有的依賴管理要做遷移的程度(《golang 1.13 - 依賴管理從 dep 到 mod 踩坑》)。

1.13 讓原來的配置方式有了變化,撇開語言特性不談,僅說和配置相關的,最大的變化,是 go module 的轉正,和 GOPATH 和 vendor 的邊緣化(1.13 仍然給你選擇的餘地,但是推薦選擇 module,停用 GOPATH 和 vendor)。

那麼如果你從 1.13 之後纔剛剛開始接觸 go, 那麼前面兩篇文章對你來說並不友好。

所以我找到了理由又水一篇。

配置

之前的文章講的 Win64 環境的配置,正好新版本重寫,這次寫 Linux 環境下。

0x00 下載解壓

1
2
# 爲免你無腦複製黏貼,強迫你走一趟流程,也確保你下載最新版本,這不是有效的下載鏈接,請自行到官網找最新版本,替換掉版本號 x.y.z
~ wget https://dl.google.com/go/gox.y.z.linux-amd64.tar.gz

找下載鏈接請到官網 golang.org/dl ,如果國內不能訪問,請到官方鏡像站 golang.google.cn/dl 。

然後解壓

1
2
3
# 記得改文件名裏的 x.y.z
~ tar -zxvf gox.y.z.linux-amd64.tar.gz
mv -t /opt/ go

個人習慣放到 /opt/ 下。

0x01 系統環境變量

然後將可執行文件加入系統路徑。

在 /etc/profile 末尾加上,保存之後記得 source 一下:

1
2
3
# manually added
GOROOT=/opt/go
export PATH=$PATH:$GOROOT/bin:$HOME/go/bin

我是想全局生效所以丟這裏,如果你只是想當前賬戶生效,可以加在 ~/.bashrc

慣例地檢查一下是否配置正確

1
2
~ go version
go version go1.13.6 linux/amd64

如果不能正確執行 go version ,把當前版本輸出,請回頭檢查哪裏出錯。

跟老版本不同的是,只要把 go 本身的可執行路徑 和 go bin 的安裝路徑加入 PATH 就可以了,剩下的 go env 自行管理了。

0x02 go env

執行 go env,就會看到 go 內置的環境變量,以及部分默認值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/jaycechant/.cache/go-build"
GOENV="/home/jaycechant/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/jaycechant/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build089244508=/tmp/go-build -gno-record-gcc-switches"

必改

1
2
~ go env -w GO111MODULE=on
~ go env -w GOPROXY=https://goproxy.cn,direct

GO111MODULE :

  • auto : 自 1.11 實驗性加入之後就是默認值。auto 意味着由工具鏈自動判斷是否啓用 go modules。在 1.13 以前的啓用條件是『項目根目錄有 go.mod 且項目不在 GOPATH 內』,1.13+ 去掉了 『不在 GOPATH 內的限制』,也就是隻要有 go.mod 就會啓用。
  • on : 如果你覺得上面這段話太長懶得看,或者害怕以後啓用條件還會變,那麼 1.13 已經準備好全面啓用 go modules,直接設爲 on 就好了。設爲 on 之後無條件啓用 go modules。
  • off : 關閉 go modules,回到 GOPATH 時代。

GOPROXY :

國內環境必備,原因你懂的。甚至可以說這是新版本爲中國開發者做出的最大改進之一也不爲過。在 dep 的時代是靠自建的代理熬過來的,那麼不會代理的朋友就很麻煩了。改用鏡像就友好太多了。

目前國內最早最好的代理是 七牛雲提供的 https://goproxy.cn 。如果團隊內部還有搭建私有代理,可以用 , 隔開,go 會依次嘗試。最後記得加上 direct ,讓鏡像上找不到的依賴回源查找。(包括但不限於 鏡像還沒同步,私有倉庫 等情況)

目前自建代理的開源方案貌似有以下幾個。由於我暫時沒有自建代理的需要,沒有實測,請自行對比選擇。

推薦改

1
~ go env -w GOBIN=$HOME/go/bin

GOBIN 如果沒有設置,默認值爲 $GOPATH/bin ,是通過 go get 或 go install 安裝的可執行文件的存放目錄。不設並不影響使用,但考慮到 GOPATH 正在被邊緣化,未來不知道哪個版本就取消了,所以建議還是單獨設置一下比較好。我爲了保持使用習慣,設置了跟默認相同的目錄(因爲 GOPATH 默認值是 $HOME/go),區別只是這個值不依賴 GOPATH 的值。

值得 提醒 的是,這個目錄也需要加入系統 PATH ,並且我已經在 系統環境變量 里加入(最後一個),如果你根據自己的習慣修改了 GOBIN 的位置,那麼 0x01 裏的配置也得相應修改。

更多的變量,推薦參考 《乾貨滿滿的 Go Modules 和 goproxy.cn》。

0x03 cgo 和 build tool

go 語言的 cgo 特性允許 C 語言 和 go 語言互調,達到 複用已有的 C/C++ 龐大代碼資源 的目的;又或者用 C 編寫程序的一部分以達到某些 底層語言才能達到的目標。而要使用 cgo 特性,就需要有 C/C++ 的構建工具鏈 gcc 。

另一方面,隨着項目規模變大,你會逐漸需要一個 構建工具 (build tools)幫你管理構建細節,就像 ant / maven / gradle 之於 Java。由於 go 本身的構建比較簡單(或者說 go 的構建規則比較清晰,自帶的 build 命令夠用),又有了現成的依賴管理(之前的 vgo / glide / dep,現在官方的 go modules),官方並沒有一個專用的構建工具。這部分,因爲依賴管理已有,管理額外的構建細節, Makefile (make) 足矣 。

gcc 和 make 在多數 Linux 發行版是自帶的,你可以通過 gcc -v 和 make -v 來確認安裝的版本。即使沒有,視乎不同的包管理器,也就是一兩句命令的事。Windows 下稍微麻煩一些,但仍然有解決方案,我在《配置 Golang 開發環境》#2. gcc 和 make 部分有提及,go 的重大升級不影響這部分內容依然有效。

0x04 安裝 VCS

在使用 go get 命令之前,需要安裝依賴託管服務對應的 VCS (Version Control System)。go get 會根據依賴所託管的網站反饋的信息,調用對應的工具 (git / hg / svn)拉取依賴。

就我的個人實踐而言,絕大多數的第三方依賴都是基於 git 發佈的(或者說直接就是放在 github 上),所以 直接安裝 git 就好 ,後面遇到基於其他工具的依賴,再安裝不遲。

由於 git 本身就是一個大話題,基本的安裝使用教程不難搜到,有時間時會另起文章討論,這裏只是提醒安裝,不再展開。

0x05 開始一個項目

終於把環境都配置好了,然後就可以開始第一個 go 的項目了。由於 go modules 不再依賴 GOPATH,所以項目可以放在任何地方——這個 『任何』,是指可以不是 GOPATH ,但是要是習慣了,繼續放在 $GOPATH/src 也沒問題。

好了,不管放在哪,現在新建一個項目的根目錄

1
2
~ mkdir testproj
~ cd testproj

然後執行 go mod init <module_path> ,生成 go.mod ,這個項目就算初始化完了,接下來就該敲代碼了。隨着開發的進行,還會自動生成 go.sum 文件,記錄依賴的校驗信息。注意 go.sum 不是 lock 文件 ,重現構建的信息已經包含在 go.mod 裏,go.sum 屬於 checksum 文件 ,用來 確保下載的依賴沒有被篡改 。 go.mod 和 go.sum 需要一起提交參與版本控制 。關於 go mod 的詳細用法,可以直接 go help mod 獲取幫助信息,不展開。

關於 module path 的內容,以及 module 與 package 之間的關係,原本是在這篇文章裏接着繼續寫;結果發現這部分內容讓字數足足翻了一番。爲了避免讓本文又臭又長,就另起了一篇文章,請看《golang 1.13 - module VS package》。

go 語言開發不是(篇幅上也不可能是)本文的話題,另起系列展開。

題外話

在寫這篇文章時,留意到 gradle 的一個插件 gogradle,可以爲 gradle 添加對 go 的支持。由於我沒有使用過這個插件,所以不好評價;不過基於以下理由,我認爲除非有什麼困難只有它能解決,不然 make 足以完成絕大多數的任務,不推薦嘗試:

  • go 除了某些特性(如 cgo)編譯時依賴某些二進制工具(如 gcc,二進制是區別於基於虛擬機的工具),基本是一個完全自給自足的語言,環境配置簡單且基本一勞永逸,編譯結果可以單執行文件零依賴部署,在某些情況下簡直是殺手級的特性。(想想 C/C++ 以外多少語言能做到)而 gradle 是基於 groovy (一種 JVM 上的腳本語言),等於 給 go 的開發環境引入了 JVM 依賴 。即使我作爲一個長期寫 Java 的人,環境裏一定有 JVM,仍然覺得這種依賴是彆扭的。
  • gogradle 官方文檔自薦的理由,是 make 學習曲線陡峭,和 make 基於 bash 的跨平臺性不好。make 和 gradle 的學習曲線見仁見智,但是由於 go 自帶的 build 已經完成了構建的大多數工作(包括依賴推導和文件新舊比較),也不需要處理依賴管理,make 的 工作任務非常輕 , 不會涉及太複雜的規則編寫。至於跨平臺,引入 MinGW-w64 已經可以解決大多數的問題。
  • go 1.13 自帶 go modules 作爲依賴管理,大方向是 淡化 GOPATH 和 vendor;而 gogradle 受 glide 啓發,自帶依賴管理,自稱相當於 glide + make,依然使用 GOPATH 和 vendor,這 跟官方的發展方向衝突 。這可能是最關鍵的一點,如果你習慣了 gradle 的工作方式,有一天這種工作方式可能跟官方的最新版本不兼容。

參考:https://jaycechant.info/2020/setup-golang-env-for-1-13-and-above/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章