Emacs中多个golang项目的配置方法

概述

最近使用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-callers
C-c C-o > go-oracle-callees
C-c C-o c go-oracle-peers
C-c C-o d go-oracle-definition
C-c C-o f go-oracle-freevars
C-c C-o g go-oracle-callgraph
C-c C-o i go-oracle-implements
C-c C-o p go-oracle-pointsto
C-c C-o r go-oracle-referrers
C-c C-o s go-oracle-callstack
C-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 中的路径中查找, 找不到就报错, 而不会依次去每个路径中去查找.

所以, 根据我的情况, 目前采用如下方式配置:

  1. 新建一个 el 文件, 比如 go-projects.el, 用于管理多个 golang 项目的配置

    touch /path/to/go-projects.el
  2. 在 go-projects.el 中设置 GOPATH

    (setenv "GOPATH" (concat ""
    "/path/to/PROJECTA:"
    "/path/to/PROJECTA/vendor:"
    "/path/to/PROJECTB:"
    "/path/to/PROJECTB/vendor:"
    "/path/to/GOPATH"))
  3. 追加 go-oracle 的 scope 配置

    (setq go-oracle-scope "xxxcmd")

    假设 main 函数在 /path/to/PROJECTB/src/xxcmd 中

  4. .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 目前管理多个项目的方式还比较少, 上述的方式也只能凑合着使用. 仅供参考!

上一篇:为什么static方法中不可以调用非static方法


下一篇:P1638 逛画展(直尺法)