這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
概述
最近使用golang開發項目時, 發現有時需要同時進行多個golang項目.
在這種情況下, 如果把所有的項目都放在 GOPATH 之下,
不僅管理麻煩(因為各個項目需要提交到不同的程式碼程式庫), 而且編譯的時候也不方便(如果不指定項目, 就會編譯所有的項目).
於是, 就想如何將各個項目在物理上就隔離開. 我是用emacs開發golang項目的, 所以隔離之後, 還要考慮如何讓emacs的golang外掛程式能夠正常工作.
使用 gb 隔離各個 golang 項目
gb 是用來管理golang項目的一個工具, 使用gb, 可以將golang項目建立在任意的位置, 不一定要放在 GOPATH 中.
gb 的 官方地址 中有詳細的使用說明, 主要就幾個參數, 使用起來很簡單.
安裝
go get github.com/constabulary/gb/...
gb 安裝到 GOPATH 中, 安裝後, 如果你的 $GOPATH/bin 在系統 $PATH 中的話, 命令列中就可以使用 gb 命令了.
使用介紹
建立項目: http://getgb.io/docs/project/
gb 命令的參數: http://getgb.io/docs/usage/
簡單使用方式: http://getgb.io/examples/getting-started/
GOPATH 的設定
系統中設定的 GOPATH 在emacs中並沒有自動識別出來, 所以必須在 emacs 中設定 GOPATH 環境變數.
設定方法如下:
(setenv "GOPATH" (concat "" "/path/to/PROJECTA:" "/path/to/PROJECTA/vendor:" "/path/to/GOPATH"))
上例中, 加入了我的項目 PROJECTA 的路徑到 GOPATH 中, vendor 檔案夾是 gb 工具安裝第三方包時產生的.
如果有多重專案, 這裡也可以配置多重專案的路徑到 GOPATH 中.
go-oracle scope 設定
上面的 GOPATH 設定正確之後, emacs 中和多 golang 的工具都可以使用了, 比如 goimports, godef 等.
使用這些工具, 可以實現函數定義的跳轉, 自動 import package等, 使得編輯器更像一個 IDE.
但是, 如果想要使用 go-oracle, 只有 GOPATH 的設定還不行, 還要設定 go-oracle-scope
go-oracle 文檔: https://godoc.org/golang.org/x/tools/cmd/oracle
go-oracle 的設定可以參考: http://yousefourabi.com/blog/2014/05/emacs-for-go/
這個文檔中, go-oracle 的下載路徑是舊的, 目前位置安裝 oracle 的方法如下:
go get golang.org/x/tools/cmd/oracle
go-oracle 常用快速鍵:
C-c C-o < go-oracle-callersC-c C-o > go-oracle-calleesC-c C-o c go-oracle-peersC-c C-o d go-oracle-definitionC-c C-o f go-oracle-freevarsC-c C-o g go-oracle-callgraphC-c C-o i go-oracle-implementsC-c C-o p go-oracle-pointstoC-c C-o r go-oracle-referrersC-c C-o s go-oracle-callstackC-c C-o t go-oracle-describe
go-oracle-scope 和 GOPATH 一樣, 也是可以設定多個的, 它是以 package 為單位進行設定的.
可以僅僅設定一個package, 比如:
(setq go-oracle-scope "lib/log")
那麼, 運行 go-oracle-callers 時, 它會在之前定義的 GOPATH 中尋找這個package(lib/log), 找到後分析它.
然後就可以使用上述快速鍵來查詢這個包中函數的各種分析結果.
你也可以指定這個項目中main函數的位置, 這樣 oracle 就會分析整個項目了, 而不是項目中的一個package, 比如:
(setq go-oracle-scope "xxcmd")
如上設定的話, oracle 會從
/path/to/PROJECTA/src/xxxcmd /path/to/PROJECTA/vendor/src/xxxcmd /path/to/gopath/src/xxxcmd
3個路徑中尋找package並分析的.
所有配置結合起來
上面的配置很簡單, 可以直接全部配置到 .emacs 中.
但是我在使用中發現, 如果項目數多的話, 首先, GOPATH 中配置路徑太多, 每次在 go-oracle 的分析會很慢.
而且如果 GOPATH 中多重專案的 package 名稱一樣的話, 比如, PROJECTA 和 PROJECTB 中都有 lib/ssh 庫,
而這個庫在 PROJECTA 和 PROJECTB 中的實現不一樣, 其中包含的函數不一樣.
那麼, godef 之類的只會在第一個出現在 GOPATH 中的路徑中尋找, 找不到就報錯, 而不會依次去每個路徑中去尋找.
所以, 根據我的情況, 目前採用如下方式配置:
建立一個 el 檔案, 比如 go-projects.el, 用於管理多個 golang 項目的配置
touch /path/to/go-projects.el
在 go-projects.el 中設定 GOPATH
(setenv "GOPATH" (concat "" "/path/to/PROJECTA:" "/path/to/PROJECTA/vendor:" "/path/to/PROJECTB:" "/path/to/PROJECTB/vendor:" "/path/to/GOPATH"))
追加 go-oracle 的 scope 配置
(setq go-oracle-scope "xxxcmd")
假設 main 函數在 /path/to/PROJECTB/src/xxcmd 中
.emacs 中load go-projects.el
(load "/path/to/go-projects.el")
使用過程中, 在 go-projects.el 中隨時調整 GOPATH 中的項目路徑, 不用的項目刪除或者注釋.
go-oracle-scope 也可以隨時根據情況調整.
調整後, M+x load-file /path/to/go-projects.el 即刻生效.
這樣就不用修改 .emacs 檔案, 因為重新load .emacs 非常慢, 甚至會出現錯誤.
golang 目前管理多重專案的方式還比較少, 上述的方式也只能湊合著使用. 僅供參考! :)