🙆

gvmでGolangのバージョンをスムーズに切り替える

2020/11/21に公開

Goに限らずですが、プロジェクトによって言語のバージョン要件が異なることがままあるため、
複数バージョンの開発環境を共存させつつ手軽に切り替えたくなることがあります。

そのような場合Pythonではpyenv(+virtualenv)、Rubyだとrbenvなどのツールが存在しますが、
Goだとgoenvやgvmを利用することができます。

今回はGitHubのStar数が比較的多いgvm(Go Version Manager)を試してみることにします。


※本記事はブログからの移行記事です

TL;DR

  • READMEに従ってGo1.4系を事前にインストールせずとも、新しいバージョンのGoはインストール可能
  • gvm install するときは -B オプションを付けた方が良い

検証環境

  • MacOS: Catalina

作業録

今回はkubebuilderの要件にあるGo1.13をインストールしてみます。

  • Macの要件

元々GoはMercurial管理だったものの、とっくの昔にGit管理に変わっています。

https://github.com/moovweb/gvm/issues/111

2020年11月現在でも何故かgvmのREADME.mdは更新されておらず、MacOSの要件としてMercurialを記載し続けています。
Mercurialは特に使っておらず、もしハマるのであればインストール中にハマると思うので、
今回はあえて何も要件を整えないまま進みます。

  • インストール
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
  • 確認
$ gvm version
Go Version Manager v1.0.22 installed at /Users/xxx/.gvm
  • Go1.4のインストール

Go1.5以降をコンパイルする場合、先にGo1.4をインストールしておく必要があるということなので、インストールします。
なお先述の通り、この作業はあとで不要ということが分かりました。

Go 1.5+ removed the C compilers from the toolchain and replaced them with one written in Go. Obviously, this creates a bootstrapping problem if you don't already have a working Go install. In order to compile Go 1.5+, make sure Go 1.4 is installed first.

[https://github.com/moovweb/gvm#a-note-on-compiling-go-15:embed:cite]

$ gvm install go1.4 -B
Installing go1.4 from binary source
$ gvm list

gvm gos (installed)

=> go1.4
   system

  • ダウンロード可能なバージョンリストを確認

現在利用可能なバージョンの一覧は、gvm listall で確認可能です。

$ gvm listall | grep go1.13
   go1.13
   go1.13beta1
   go1.13rc1
   go1.13rc2
   go1.13.1
   go1.13.2
   go1.13.3
   go1.13.4
   go1.13.5
   go1.13.6
   go1.13.7
   go1.13.8
   go1.13.9
   go1.13.10
  • go1.13系のlatestをインストール
$ gvm use go1.4
Now using version go1.4
$ export GOROOT_BOOTSTRAP=$GOROOT
$ gvm install go1.13.10Installing go1.13.10...
 * Compiling...
ERROR: Failed to compile. Check the logs at /Users/ryoichi/.gvm/logs/go-go1.13.10-compile.log
ERROR: Failed to use installed version

コンパイルエラーでハマりました。
エラー文の詳細は異なりましたが、公式Issueによると -B オプションをつけるとバイナリをそのままダウンロードする形でインストールできるようです。

https://github.com/moovweb/gvm/issues/327

今後のデフォルトオプションとなることも示唆されていたので、そちらをつけてリトライしてみます。

  • 再度インストール

-Bオプションを付けたら上手く行きました。
結局のところローカルでコンパイルする代わりに
コンパイル済みのバイナリを持ってくればすんなり動くという、
ありがちな結果に落ち着きました。

$ gvm install go1.13.10 -B
Installing go1.13.10 from binary source
$ gvm list

gvm gos (installed)

   go1.13.10
=> go1.4
   system
  • Goの動作確認
$ gvm use go1.13.10
Now using version go1.13.10
$ go version
go version go1.13.10 darwin/amd64

無事動作確認できました。

ただ、この状態だとログインし直すたびにgvm useする必要があるため、
gvm use <go_version> --defaultオプションでデフォルトバージョンを指定すると、
入り直すたびに叩く必要性が無くなります。

  • 別バージョンのGoをインストールして切り替え

2020年11月現在のlatestであるgo1.15.5をインストールし、
先ほどと同様に切り替えてみます。

# 別バージョンのGoをインストール
$ gvm install go1.15.5 -B
Installing go1.15.5 from binary source
$ gvm use go1.15.5
Now using version go1.15.5
$ go version      
go version go1.15.5 darwin/amd64

# 元のバージョンに戻す
$ gvm use go1.13.10
Now using version go1.13.10
$ go version       
go version go1.13.10 darwin/amd64

このように、installとuseを行うだけで、
非常に手軽にバージョン切り替えが可能でした。

所感

今は公式のGo Modulesでパッケージの依存関係は楽に管理できるため、
gvmでGo本体の管理さえできれば、開発はスムーズに行えそうです。

参考

https://qiita.com/kuntao/items/e75bae225ab5da029252

Discussion