Golang
发展迅速,代码迭代非常快,想要在同一环境调试和梳理不同项目进程就成了一件相对棘手的事情。二进制文件的管理比较简单,通过链接使用不同版本的程序即可。实际上主要是一些环境变量和标准库的设置问题,偶然间发现了 GVM - Go Version Manager
,GVM
实际上就是帮助我们完成这些配置工作,这算是找到了调试切换版本的福音了。
什么是 GVM
Go
语言版本管理器(GVM
)是管理 Go
语言环境的开源工具。GVM 「pkgsets」
支持安装多个版本的 Go
并管理每个项目的模块。它最初由 Josh Bussdieker
开发,GVM
与 Ruby RVM
类似,允许你为每个项目或一组项目创建一个开发环境,分离不同的 Go
版本和包依赖关系,来提供更大的灵活性,以防不同版本造成的问题。GVM
主要有以下几个特性:
- 管理
Go
的多个版本,包括安装、卸载和指定使用Go
的某个版本 - 查看官方所有可用的
Go
版本,同时可以查看本地已安装和默认使用的Go
版本 - 管理多个
GOPATH
,并可编辑Go
的环境变量 - 可将当前目录关联到
GOPATH
- 可以查看
GOROOT
下的文件差异 - 支持
Go
版本切换
安装 GVM
GVM
本质上就是一个 SHELL
脚本,它背后做的事情是先把源码下载下来,再用 C
做编译。所以,安装 GVM
前你需要先安装一些依赖包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Debian/Ubuntu $ sudo apt-get install curl git mercurial make binutils bison gcc build-essential # Redhat/Centos $ sudo yum install curl $ sudo yum install git $ sudo yum install make $ sudo yum install bison $ sudo yum install gcc $ sudo yum install glibc-devel # macOS $ xcode-select --install $ brew update $ brew install mercurial |
注意:
Centos
官方仓库没有mercurial
软件包,如果你需要可以在mercurial
官网https://www.mercurial-scm.org/downloads
下载后安装。
安装好依赖环境后, GVM
的安装也很简单。官方提供了一键安装脚本,你只需直接运行就行了。
1 | $ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) |
如果你使用的是 zsh
的话将前面的 bash
改为 zsh
即可,这条命令主要是检查相关依赖环境并下载 GVM
相关的文件,然后创建所需目录,并且在 .bashrc
或者 .zshrc
中加入:
1 | [[ -s "/Users/lanyulei/.gvm/scripts/gvm" ]] && source "/Users/lanyulei/.gvm/scripts/gvm" |
使每次登录 Shell
时都可以自动生效。
使用 GVM 安装和管理 Go 版本
一旦安装了 GVM
,就可以开始使用它来安装和管理不同版本的 Go
。首先,你可以用 gvm listall
命令显示可以下载和编译可用的 Go
版本。
1 2 3 4 5 6 7 8 9 | $ gvm listall gvm gos (available) go1 go1.0.1 go1.0.2 go1.0.3 ... |
安装特定的 Go
版本只需运行 gvm install <version>
命令,其中 <version>
是表示要安装的版本。假设你正在处理一个使用 Go 1.12.8
版本的项目,你就可以使用 gvm install go1.12.8
命令来安装这个版本。
1 2 3 4 | $ gvm install go1.12.8 Installing go1.12.8... * Compiling... go1.12.8 successfully installed! |
安装完成后,输入 gvm list
命令后,你会看到 Go 1.12.8
版本与系统自带的 Go
版本(使用操作系统的软件包管理器打包的版本)都同时存在。
1 2 3 4 | $ gvm list gvm gos (installed) go1.12.8 => system |
不过,这时 GVM
仍然默认使用系统的 Go
版本,通过它旁边的 =>
符号来表示。你可以使用 gvm use
命令来切换到新安装的 go 1.12.8
版本。
1 2 3 4 | $ gvm use go1.12.8 Now using version go1.12.8 $ go version go version go1.12.8 linux/amd64 |
如果不想每次敲 gvm use
指令来切换版本,你可以加上 --default
参数来指定默认使用这个版本。
1 | $ gvm use go1.12.8 --default |
是不是,很容易呢!GVM
使管理已安装的 Go
版本变得极其简单,但它不止如此!
由于
Go 1.5
使用了自举(用Go
编译Go
),如果在系统环境完全没有Go
命令的情况下,直接使用gvm install go
会报错。所以,你必须先安装Go 1.4
。
1 2 3 4 5 6 | # 先安装 1.4 版本的,-B 表示只安装二进制包。 $ gvm install go1.4 -B $ gvm use go1.4 $ export GOROOT_BOOTSTRAP=$GOROOT # 再安装 1.5+ 版本的 $ gvm install go1.12.8 |
使用 GVM pkgset
默认情况下,如果你通过 go get
获取一个包,它会被下载到 $GOPATH
目录中的 src
和 pkg
目录下。然后你可以使用 import
将其引入到你的 Go
程序中。然而,在不同的项目中管理相同包的不同版本就会变得困难。
GVM
通过使用「pkgsets
」将项目的新目录附加到 Go
安装版本的默认 $GOPATH
,类似 Linux
系统上的 $PATH
,这样就可以很好地完成了项目之间包的管理和隔离。我们来看一个实例,安装一个新版本的 Go 1.12.9
。
1 2 3 4 5 6 7 8 | $ echo $GOPATH /home/chris/.gvm/pkgsets/go1.12.8/global $ gvm install go1.12.9 Installing go1.12.9... * Compiling... go1.12.9 successfully installed $ gvm use go1.12.9 Now using version go1.12.9 |
当 GVM
被告知使用一个新版本时,它将会更换一个新的 $GOPATH
,gloabl pkgset
将默认使用该版本。
1 2 3 4 5 | $ echo $GOPATH /home/chris/.gvm/pkgsets/go1.12.9/global $ gvm pkgset list gvm go package sets (go1.12.9) => global |
尽管默认情况下没有安装额外的包,但是
global pkgset
中的包对于使用这个特定版本Go
的任何项目都是可用的。
现在,假设你正在启动一个新项目,它需要一个特定的包。首先,使用 GVM
创建一个名为 introToGvm
的新的 pkgset
。
1 2 3 4 5 6 7 | $ gvm pkgset create introToGvm $ gvm pkgset use introToGvm Now using version go1.12.9@introToGvm $ gvm pkgset list gvm go package sets (go1.12.9) global => introToGvm |
如上所述,一个与 pkgset
同名的新目录 introToGvm
被添加到 $GOPATH
。
1 2 | $ echo $GOPATH /home/chris/.gvm/pkgsets/go1.12.9/introToGvm:/home/chris/.gvm/pkgsets/go1.12.9/global |
接下来,验证下新目录 introToGvm
中的目录结构。
1 2 3 4 5 | $ cd $( awk -F':' '{print $1}' <<< $GOPATH ) $ pwd /home/chris/.gvm/pkgsets/go1.12.9/introToGvm $ ls overlay pkg src |
注意:新目录看起来很像普通的
$GOPATH
,新的Go
包会被Go get
命令下载并且被添加到pkgset
中。
最后,使用以下命令获取一个 gorilla/mux
包,然后检查 pkgset
下的内容。
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 34 35 | $ go get github.com/gorilla/mux $ tree . ├── overlay │ ├── bin │ └── lib │ └── pkgconfig ├── pkg │ └── linux_amd64 │ └── github.com │ └── gorilla │ └── mux.a src/ └── github.com └── gorilla └── mux ├── AUTHORS ├── bench_test.go ├── context.go ├── context_test.go ├── doc.go ├── example_authentication_middleware_test.go ├── example_cors_method_middleware_test.go ├── example_route_test.go ├── go.mod ├── LICENSE ├── middleware.go ├── middleware_test.go ├── mux.go ├── mux_test.go ├── old_test.go ├── README.md ├── regexp.go ├── route.go └── test_helpers.go |
如上所示,gorilla/mux
按照预期添加到了 pkgset
的 $GOPATH
目录,现在你就可以与使用该 pkgset
的项目一起使用该模块了。
卸载 GVM 或指定版本 Go 语言
如果你只是想卸载某个安装好的 Go
版本,可以使用以下指令。
1 | $ gvm uninstall go1.12.8 |
如果你想完全卸载掉 GVM 和 所有安装的 Go 版本,可以使用以下指令。
1 2 | # 需谨慎操作 $ gvm implode |
总结
GVM
是以一种直观的、非侵入性的方式来管理 Go
版本和包的工具。它可以单独使用,也可以使用 GVM
的 Go
版本管理功能与其他 Go
模块管理技术结合使用。GVM
通过对 Go
版本和包依赖关系的隔离使项目开发更加容易,并减少了管理版本冲突的复杂性。
参考文档
- https://www.google.com
- https://bingohuang.com/go-gvm/
- https://learnku.com/articles/35269
- https://dryyun.com/2018/11/28/how-to-use-gvm/
- https://laucyun.com/ff3bc3db699464aa76756e41be780712.html
- https://opensource.com/article/19/10/go-introduction-gvm
- http://blog.fatedier.com/2016/07/25/use-different-go-version-by-gvm/
本文为转载文章,贵在分享,版权归原作者及原出处所有,如涉及版权等问题,请及时与我联系。
原文出处:奇妙的 Linux 世界
原文链接:https://www.hi-linux.com/posts/20165.html