gvmを使って環境を設定していたのだけど、gvmのことを理解できていなかったことがわかったので、備忘録にまとめておく。
gvm自体のインストール
まずgvmをインストールするには brew
を使えるようにして以下実行。
brew update
brew install mercurial
その後更に以下を実行。
zsh < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
Cloning from https://github.com/moovweb/gvm.git to /home/hoge/.gvm
Created profile for existing install of Go at "/usr/lib/go"
Installed GVM v1.0.22
Please restart your terminal session or to get started right away run
`source /home/hoge/.gvm/scripts/gvm`
こうすると、自分の使っているシェルのrcファイル(自分の場合は~/.zshrc)に以下が書き込まれる。
なのでsourceとか別シェルとか開く。
[[ -s "/home/hoge/.gvm/scripts/gvm" ]] && source "/home/hoge/.gvm/scripts/gvm"
インストール可能な一覧の表示
まずgvmとして利用可能な環境を一覧表示する。
以下のような感じでいっぱい表示される。
% gvm listall
gvm gos (available)
go1
go1.0.1
...
go1.10.5
go1.11
go1.11beta1
go1.11beta2
go1.11beta3
go1.11rc1
go1.11rc2
go1.11.1
go1.11.2
...
release.r60.3
go1.10.5 をインストールしてみる
環境のインストールには、 gvm install
を使う。
% gvm install go1.10.5
Installing go1.10.5...
* Compiling...
go1.10.5 successfully installed!
とりあえずgvmで現時点で入れれる最新は 1.11.2
だったので、gvm install go1.11.2
もしておいた。
go1.11.2 をデフォルトの環境にしてみる
まず使える環境を一覧表示する。
% gvm list
gvm gos (installed)
go1.10.5
go1.11.2
go1.9.7
system
デフォルトをセットする場合はこう。
% gvm use go1.11.2 --default
% go version
go version go1.11.2 darwin/amd64
この状態で、別なシェルを開いて go version
してみる。
% go version
go version go1.11.2 darwin/amd64 <-- ちゃんとデフォルトになっている
別な go version に切り替える
デフォルトにしないで使いたい場合、 --default
をしなければいい。
% gvm use 1.10.5
Now using version go1.10.5
% gvm list
gvm gos (installed)
=> go1.10.5
go1.11.2
go1.9.7
system
% go version
go version go1.10.5 darwin/amd64
ちゃんと go1.10.5
に切り替わっているのがわかる。
で、その時のgo環境って実際にはどこにある?
基本的に、 ~/.gvm
に存在する。
% echo $GOPATH
/<$HOME>/.gvm/pkgsets/go1.10.5/global
% echo $GOROOT
/<$HOME>/.gvm/gos/go1.10.5
ここで疑問
僕の場合、この時点で go1.10.5
で、さらに $GOPATH
を切り替えたい場合はどうするのか・・・という疑問が出た
- npmならフォルダで分かれるからndenvでバージョンだけ切り替えれればいいけど・・・
- pyenvならpyenv virtualenv とかでいいけど・・・
そんなときの pkgset
direnvとかで最初やってたんだけど、そもそも、 pkgset
, pkgenv
というものがある。
pkgset の一覧を見てみる
% gvm pkgset list
gvm go package sets (go1.10.5)
global
まだglobalというpkgsetしかない。これがまた僕を混乱させたのだが後述。
pkgsetを作ってみる
% gvm pkgset create unittest
% gvm pkgset list
gvm go package sets (go1.10.5)
global
unittest
unittestというpkgsetが出来たっぽい。
では使ってみる
% gvm pkgset use unittest
Now using version go1.10.5@unittest
% gvm pkgset list
gvm go package sets (go1.10.5)
global
=> unittest
矢印がついた。これを使うことが出来たらしい。
ここでポイント
pkgset list
の結果に、 gvm go package sets (go1.10.5)
と出ている。
つまり今見ているのは、 使っているgoバージョン(=1.10.5)において存在するpkgsetである
ということ。
ためしに、一度goのバージョン自体をgvmで切り替えてみる。
% gvm use go1.11.2
Now using version go1.11.2
% gvm pkgset list
gvm go package sets (go1.11.2)
=> global
僕の場合 go1.11.2がdefaultなので矢印がついていると思われるが、要はこっちのgoバージョンには pkgsetがない
ということになる。
また、go1.10.5
側で gvm pkgset use unittest
をしたときに go1.10.5@unittest
と表示されたのも少し頷ける。
( "@"の日常的な使い方的に unittest@go1.10.5
な気もするが、おそらくgoライブラリの path@version
と同じなのだろう)
またこのようにパッケージを切り替えながらgoの環境を見ていくと、こういう変化が起きている。
% gvm pkgset list
gvm go package sets (go1.10.5)
global
=> unittest <-- 今はunittestを使っている
% echo $GOPATH; echo $GOROOT; echo $PATH <-- GOPATH, GOROOT, PATHは?
/<$HOME>/.gvm/pkgsets/go1.10.5/unittest:/Users/yuzu/.gvm/pkgsets/go1.10.5/global
/<$HOME>/.gvm/gos/go1.10.5
/<$HOME>/.gvm/pkgsets/go1.10.5/unittest/bin: (長いので略)
% gvm pkgset use global
Now using version go1.10.5@global
% echo $GOPATH; echo $GOROOT; echo $PATH
/<$HOME>/.gvm/pkgsets/go1.10.5/global:/Users/yuzu/.gvm/pkgsets/go1.10.5/global
/<$HOME>/.gvm/gos/go1.10.5
/<$HOME>/.gvm/pkgsets/go1.10.5/global/bin: (長いので略)
つまり $GOPATH
と $PATH
が切り替わっている。goのbinaryとかを環境ごとに入れ替えることを想定して $PATH
も切り替わっているのだろう。
環境を更に細かく設定したい場合
pkgenv
を使う。
% gvm pkgenv unittest
export GVM_ROOT; GVM_ROOT="/<$HOME>/.gvm"
export gvm_go_name; gvm_go_name="go1.10.5"
export gvm_pkgset_name; gvm_pkgset_name="global"
export GOROOT; GOROOT="$GVM_ROOT/gos/go1.10.5"
export GOPATH; GOPATH="$GVM_ROOT/pkgsets/go1.10.5/global"
export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX="${GVM_ROOT}/pkgsets/go1.10.5/global/overlay"
export PATH; PATH="${GVM_ROOT}/pkgsets/go1.10.5/global/bin:${GVM_ROOT}/gos/go1.10.5/bin:${GVM_OVERLAY_PREFIX}/bin:${GVM_ROOT}/bin:${PATH}"
export LD_LIBRARY_PATH; LD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${LD_LIBRARY_PATH}"
export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${DYLD_LIBRARY_PATH}"
export PKG_CONFIG_PATH; PKG_CONFIG_PATH="${GVM_OVERLAY_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"
export gvm_pkgset_name="unittest"
export GOPATH; GOPATH="/<$HOME>/.gvm/pkgsets/go1.10.5/unittest:$GOPATH"
export PATH; PATH="/<$HOME>/.gvm/pkgsets/go1.10.5/unittest/bin:$PATH"
# Package Set-Specific Overrides
export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX="${GVM_ROOT}/pkgsets/go1.10.5/unittest/overlay"
export PATH; PATH="/<$HOME>/.gvm/pkgsets/go1.10.5/unittest/bin:${GVM_OVERLAY_PREFIX}/bin:${PATH}"
export LD_LIBRARY_PATH; LD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${LD_LIBRARY_PATH}"
export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${DYLD_LIBRARY_PATH}"
他言語と比較するとgvmってこんな感じ
なので、他の言語と比較すると、こんな感じの対応関係になるかと。
言語 | バージョン自体を変える | その中でさらに環境を分ける |
---|---|---|
python | pyenv install 3.6.6 | pyenv virtualenv 3.6.6 myvenv; pyenv shell(or global) myvenv |
node | ndenv install v11.2.0 | フォルダで分ければOKと思っている(違う?) |
go | gvm install 1.11.2 | gvm pkgset create mypkgset; gvm pkgset use mypkgset |
ということで頭がスッキリしたので、明日から開発が多分もう少し捗ると思う。