GOPATHの設定でハマって解決した話

「みんなのGo言語」が話題だから、というつもりでもなかったのだけど、やはり影響はあるかもしれない。

みんなのGo言語【現場で使える実践テクニック】

みんなのGo言語【現場で使える実践テクニック】

どうもGOPATHというやつの理解がぼんやりしていて、これまでも見よう見まねで設定してはいたのだけど、その足元のおぼつかなさゆえにいつ混乱に陥ってもおかしくないという不安がだいぶ募ってきたので整理と理解を試みた。

けっこう前にセットしてそのままだった.bash_profileを見てみると、こんな風になっていた。

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
export GOBIN=$GOPATH/bin

しかしどうもこの最後のGOBINというのは最近見かけない気がするので、いかにも理解してない感じがありそれが怖い。

ということで、とりあえず以前に買って少し読んでいた以下の本を見ながら最新版のGo1.7をMacにインストールし、

スターティングGo言語

スターティングGo言語

そのまま同書の案内にしたがって.bash_profileを以下のように書き換えたのだけど、

export PATH=/usr/local/go/bin:$PATH
export GOPATH=$HOME/go

動かない。

具体的には、第一に毎日毎時間頻用しているmattnさんのchoが動かない。

GitHub - mattn/cho

ぼくは自作のコマンドラインツールでchoをデフォルト的に組み込んでいるので、

choっと作った便利なツール - the code to rock
最近のcarvo: pecoとchoをくっつけた - the code to rock

これにはさすがにゾッとした。ディレクトリ移動、ファイルオープン、不要ファイルの削除などあらゆる面で支障をきたす。

焦りつつ、何がどうなっているのかチェックしてみると、たとえば「$ go get 〜」というふうに外部のパッケージをインストールした際、それがGOPATHで指定した先に入っていくところまでは思惑通り動いているようなのだが、本来ならそれで次の瞬間から有効になるはずのコマンドが効かない。

どうもGOPATHとして設定した「$HOME/go/bin」のバイナリファイルがマシンに認識されていない、無視されている、屍のようだ、という雰囲気を感じる。のだけど、ではそれをどうしたらいいのか……というところで多分4〜5時間ぐらいハマり続けた。

で、結論的にはこれはPATHの設定が駄目で、以下のようにしたら解決した。

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

しかしこれ、よくよく見直すと最初の状態に戻っているだけである。

と同時に、なんとなく自分で当たりをつけた原因がそれほど外れていなかったこと、そしてこれまで数年にわたりどうにも理解しきれずにいた「PATHを通す」という言葉の意味の片鱗が、ようやく腑に落ちてきた気もする。

「PATHを通す」という表現をプログラミングの初心者にまともに解説してくれる人や記事にぼくはいまだに出会ったことがほぼないのだけれど*1、自分なりに言い換えれば、それは「最高権力者であるところのマシンが認める限定的な《コマンドファミリー》の一員に入れてやる」というようなことではないかと思い始めている。
(抽象的すぎて初心者にはむしろ不親切な説明だが)

言い換えると、あるコマンド候補生を正式なコマンド集団の一員に昇格させるためにやることは、そいつが今いる場所をその《ファミリー》が支配する新たな縄張りに加えるか、あるいはすでに縄張りになっている場所にそいつを入れるか、そのどちらかであり、通常言われる「PATHを通す」というのは基本的にその前者なのかなと。
(この説明もきわめて抽象的だが)

そのようなことを考えながら上記の失敗例を見直すと、GOPATHの設定とPATHの設定がバラバラで繋がっていない。
懲りずに上の喩えを用いるならば、こちらの意図としてはGOPATH/binの中身をすでに正式なコマンドの一員だと思いこみ周りにもそう吹聴しているのだけど、最高権力者であるところのマシンはそれをまだ《ファミリー》の一員だと認めていない。

これがもし、GOPATHの設定をしないのであればそのPATH設定でもいいかもしれないが、GOPATHを設定する前提ならそのPATH設定のままでは駄目ではないか、と前掲「スターティングGo言語」を何度か読み返しつつ心の中で呟いた。*2*3

ちなみに、PATH設定については以下のように先頭へ代入するよう説明している本や記事もあったが、

export PATH=$GOPATH/bin:$PATH

どうもこうして先頭に入れるというのは、それなりに意味というか必然性がないとちょっと抵抗があるように感じたので、

export PATH=$PATH:$GOPATH/bin

というふうに後に付けるようにしたがそれでとくに問題なさそうである。

というか、こちらのWeb+DBプレスGo特集にもそのように記述されているので大丈夫だろう。

WEB+DB PRESS Vol.82

WEB+DB PRESS Vol.82

  • 作者: 山口徹,Jxck,佐々木大輔,横路隆,加来純一,山本伶,大平武志,米川健一,坂本登史文,若原祥正,和久田龍,平栗遵宜,伊藤直也,佐藤太一,高橋俊幸,海野弘成,五嶋壮晃,佐藤歩,吉村総一郎,橋本翔,舘野祐一,中島聡,渡邊恵太,はまちや2,竹原,河合宜文,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2014/08/23
  • メディア: 大型本
  • この商品を含むブログ (1件) を見る

というか、このGo特集はその4〜5時間ハマってる間にも何度も目を通していたのだけど、解決した後にあらためて見直したら上記と同じPATH/GOPATH設定の正解がちゃんと載っていて、やっぱり人間、焦ると見落とすな〜とつくづく身に沁みた。

ということで、実りがあるのかどうかよくわからない内容になったが、後になってまた同じようなことで普通にハマりそうなので、そのときの自分のために書いておいた。

追記

「みんGo」のKindle版が出ていたのでサンプルを読んでみたら、第1章の途中まで載っていて好印象*4……と思っていたら上記のGOPATH/GOROOTについても丁寧に触れられており、かつ上記設定で問題なさそうなことを確認できたのでよかった。

みんなのGo言語[現場で使える実践テクニック]

みんなのGo言語[現場で使える実践テクニック]

*1:以前に以下で紹介した「新しいLinuxの教科書」はかなりイイ線行っているが。 http://note103.hateblo.jp/entry/2015/12/17/083000

*2:もしかしたら書中ではきちんと説明されていて、ぼくがそれを見落としているだけかもしれないが。

*3:ちなみに同書じたいはそれこそ初心者向けの丁寧で良いつくりの本だと感じている。

*4:こういったサンプルで前書き&目次までしか載せてないような本も時々あって、売上戦略としては正しいとも感じるが(高額でなければ「本文の方にほしい情報が載っているかもしれない」と考えて焦って買う可能性もあるので)印象は良くない。