Ubuntuのvimで :python と :python3 を同時に有効にする(リベンジ)
Ubuntu 14.04 + Vim 7.4.507 でPythonインターフェイスとPython3インターフェイスを同時に使えるようにします。 筆者はUbuntuを使いましたが、Debian系のディストリであれば同じ方法でできると思います。
この記事は素人がよく理解せずに書いています。色々とアレな方法な気がします。何が起きても自己責任でお願いします。
[2014/11/14 追記] Pyenvを使う方法をコメントで教えていただだきました。 VimのPythonで2/3系両方使えず困っていることがある方は、下記のid:lambdalisueさんの記事をご参照ください。
はじめに
半年ほど前の記事(Debian: vimでPythonとPython3の両方使えるようになってた(ように見えたけどそうでもなかった) - Blank File)で挫折したような内容です。 ちょうどLinuxでPythonをビルドするときの --enable-shared オプションについて - Qiitaという記事が公開されたので、こちらを参考にUbuntuでリベンジしました。
Debian系のディストリではPythonが2系/3系ともに特殊な構成でビルドされているようです *1 。 そのせいで、Debian系のディストリでは単純にはVimからpython2とpython3を同時に使用できません。 UbuntuにデフォルトでインストールされるVimもpython2インターフェイスだけが有効になっています *2 。
というわけで、なんとかUbuntuでPython2/3が両方有効なVimを使ってやろうというのが本記事の趣旨です。 ざっくりとした手順は以下のとおりです。
--enable-shared
オプション付きでビルドされたPython2とPython3を用意する- Vimにパッチを適用する
- パッチはIchizok氏のパッチを使わせていただきました
- 用意したPython2とPython3に PATHを通した状態で Vimをビルド
Python2とPython3のビルド
VimでPython2とPython3を同時に使うためには、両方のバイナリが--enable-shared
オプション付きでビルドされている必要があります。
しかし、Ubuntu(Debian系ディストリ)のシステムデフォルトのPythonはこのオプションなしらしいので、2と3両方を別途自分で用意しなくてはなりません。
まずPythonのソースを適当なディレクトリに持ってきます。
ソースコードは公式サイト(Download Python)から必要なバージョンをダウンロードするか、開発用のリポジトリをローカルにcloneしてくるかの二択になります。
リポジトリを使う場合は、リリースバージョンごとにタグが打たれているのでバージョンを指定してhg update
します。
hg clone https://hg.python.org/cpython cd cpython hg update -r v3.4.2
後述しますが、ここで使うPythonのバージョンはシステムのもの(普段PATHを通しているもの)とマイナーバージョンまで同じものがいいと思います。
Ubuntu 14.04の場合は、通常 Python 2.7.6 と Python 3.4.0 のはずです。
私は今回 Python 2.7.8
と Python 3.4.2
をビルドしました。
ビルドする環境の整え方については以下の記事を参照してください。
私は上記methaneさんのQiitaの記事の「対策1 rpath を設定する」の方法を使いました。
公式のリポジトリをクローンし、そのディレクトリ内で以下のコマンドを実行しました。
--prefix
のパスなどは適宜変更してください。
hg update -r v2.7.8 ./configure \ --prefix=$HOME/Applications/python2.7.8-vim \ --enable-shared \ LDFLAGS=-Wl,-rpath,$HOME/Applications/python2.7.8-vim/lib \ make j -4 make install make distclean hg update -r v3.4.2 ./configure \ --prefix=$HOME/Applications/python3.4.2-vim \ --enable-shared \ LDFLAGS=-Wl,-rpath,$HOME/Applications/python3.4.2-vim/lib \ make j -4 make install
ついでにPython2の方にpipを入れておきます *3 。
curl -kL https://raw.github.com/pypa/pip/master/contrib/get-pip.py | $HOME/Applications/python2.7.8-vim/bin/python
Python3の方は、3.4以上のバージョンであれば勝手にpipが入っているはずです。 もし3.4なのにpipが自動インストールされていない場合は、libssl-devがインストールされているか確認してください。 このライブラリがなくてもビルドは成功してエラーは出ないのですが、pipの自動インストールに失敗します。 なかなかのハマりポイントだと思います。
Vimにパッチを当てる
以下を参考に、Vimをソースコードからビルドする環境整えます。
./configure
を実行する手前までは同じです。
./configure
する前に、Vimのソースコードに
Ichizok氏のパッチ
を当てます。
TortoiseHGを使っている場合は、パッチをクリップボードにコピーし、「リポジトリ」→ 「パッチの取り込み(import)」→ 「クリップボードからインポート」でパッチを読み込み、「パッチの適用先」で「作業領域」を指定すれば適用できます。
一応、適用できない時のために執筆時現在での最新版(7.4.507)用に微調整(行番号変更)したパッチを置いておきます。
最悪、パッチの行番号と前後のコードを参考に手作業でsrc/auto/configure
ファイルを修正してもそんなに手間ではないと思います。
diff -r 9dff716fb9aa src/auto/configure --- a/src/auto/configure Thu Nov 06 10:03:01 2014 +0100 +++ b/src/auto/configure Sat Nov 08 02:04:14 2014 +0900 @@ -6361,6 +6361,8 @@ CFLAGS="$CFLAGS $PYTHON_CFLAGS" ldflags_save=$LDFLAGS LDFLAGS="-ldl $LDFLAGS" + libs_save=$LIBS + LIBS="$LIBS -ldl" if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -6419,6 +6421,7 @@ CFLAGS=$cflags_save LDFLAGS=$ldflags_save + LIBS=$libs_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can do without RTLD_GLOBAL for Python3" >&5 $as_echo_n "checking whether we can do without RTLD_GLOBAL for Python3... " >&6; } @@ -6426,6 +6429,8 @@ CFLAGS="$CFLAGS $PYTHON3_CFLAGS" ldflags_save=$LDFLAGS LDFLAGS="-ldl $LDFLAGS" + libs_save=$LIBS + LIBS="$LIBS -ldl" if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -6485,6 +6490,7 @@ CFLAGS=$cflags_save LDFLAGS=$ldflags_save + LIBS=$libs_save PYTHON_SRC="if_python.c" PYTHON_OBJ="objects/if_python.o"
Vimをビルドする
修正したソースでVimをビルドします。
ポイントは、先ほどビルドした--enable-shared
付きのPythonにPATHを通した状態でビルドすることです。
私は以下のスクリプトをvimのソースの親ディレクトリで実行しました。 python以外のオプションは必要に応じて変更してください。
#!/bin/sh cd vim/src make distclean OLDPATH=$PATH export PATH=$HOME/Applications/python3.4.2-vim/bin:$PATH export PATH=$HOME/Applications/python2.7.8-vim/bin:$PATH ./configure \ --prefix=$HOME/usr \ --with-features=huge \ --enable-multibyte \ --enable-gui=gtk2 \ --enable-pythoninterp=dynamic \ --enable-python3interp=dynamic \ --enable-luainterp=dynamic \ --with-lua-prefix=/usr \ --with-luajit \ --enable-gpm \ --enable-acl \ --enable-xim \ --enable-fail-if-missing export PATH=$OLDPATH
上記のスクリプトでは、一時的にPATHの設定を変え、--enable-shared
オプション付きのpythonとpython3を見に行かせています。
--with-python-config-dir
オプションは指定しなくてもいい感じに処理してくれます。
ログがずらずらと出てきますが、以下のような部分で今回インストールしたpythonを見に行っていれば成功です *4 。
checking ... checking ... checking for python2... /home/[username]/Applications/python2.7.8-vim/bin/python2 checking Python version... 2.7 checking Python is 2.3 or better... yep checking Python's install prefix... /home/[username]/Applications/python2.7.8-vim checking Python's execution prefix... /home/[username]/Applications/python2.7.8-vim checking Python's configuration directory... /home/[username]/Applications/python2.7.8-vim/lib/python2.7/config checking if -pthread should be used... yes checking if compile and link flags for Python are sane... yes checking --enable-python3interp argument... dynamic checking for python3... /home/[username]/Applications/python3.4.2-vim/bin/python3 checking Python version... 3.4 checking Python is 3.0 or better... yep checking Python's abiflags... m checking Python's install prefix... /home/[username]/Applications/python3.4.2-vim checking Python's execution prefix... /home/[username]/Applications/python3.4.2-vim checking Python's configuration directory... /home/[username]/Applications/python3.4.2-vim/lib/python3.4/config-3.4m checking if -pthread should be used... yes checking if compile and link flags for Python 3 are sane... yes checking whether we can do without RTLD_GLOBAL for Python... yes checking whether we can do without RTLD_GLOBAL for Python3... yes checking ... checking ...
エラーがなければ、make
して make install
すれば指定したディレクトリにインストールされます。
確認
新しくインストールしたVimを起動し、確認してみます。
:version
の出力で +python/dyn
と +python3/dyn
が含まれていれば、とりあえず両方使えます。
ただ、:python
してから:python3
した時(逆の順番でも)にエラー(E837)になる事もあるので、両方実行するまで安心できません。
私は以下のようなスクリプトを実行して確認しました。 ついでにバイナリやライブラリのパスを確認しています。
echo "---- Python3 ----" python3 <<EOF from pprint import pprint import sys print(sys.executable) print(sys.prefix) print(sys.exec_prefix) pprint(sys.path) print(sys.version_info) import datetime print(datetime.__file__) EOF echo "\n---- Python2 ----" python <<EOF from pprint import pprint import sys print(sys.executable) print(sys.prefix) print(sys.exec_prefix) pprint(sys.path) print(sys.version_info) import datetime print(datetime.__file__) EOF
出力
---- Python3 ---- /usr/bin/python3 /home/[username]/Applications/python3.4.2-vim /home/[username]/Applications/python3.4.2-vim ['/home/[username]/Applications/python3.4.2-vim/lib/python3.4', '/home/[username]/Applications/python3.4.2-vim/lib/python3.4/plat-x86_64-linux-gnu', '/home/[username]/Applications/python3.4.2-vim/lib/python3.4/lib-dynload', '/home/[username]/Applications/python3.4.2-vim/lib/python3.4/site-packages', '_vim_path_'] sys.version_info(major=3, minor=4, micro=0, releaselevel='final', serial=0) /home/[username]/Applications/python3.4.2-vim/lib/python3.4/datetime.py ---- Python2 ---- /usr/bin/python /home/[username]/Applications/python2.7.8-vim /home/[username]/Applications/python2.7.8-vim ['/home/[username]/Applications/python2.7.8-vim/lib/python2.7', '/home/[username]/Applications/python2.7.8-vim/lib/python2.7/plat-x86_64-linux-gnu', '/home/[username]/Applications/python2.7.8-vim/lib/python2.7/lib-tk', '/home/[username]/Applications/python2.7.8-vim/lib/python2.7/lib-old', '/home/[username]/Applications/python2.7.8-vim/lib/python2.7/lib-dynload', '/home/[username]/.local/lib/python2.7/site-packages', '/home/[username]/Applications/python2.7.8-vim/lib/python2.7/site-packages', '_vim_path_'] sys.version_info(major=2, minor=7, micro=6, releaselevel='final', serial=0) /home/[username]/Applications/python2.7.8-vim/lib/python2.7/lib-dynload/datetime.so
Pythonのバイナリはシステムの/usr/bin
以下のものを使っていますが、ライブラリは今回ビルドしたものを参照しています。
これは標準モジュールも例外ではないので、Pythonのバージョンが異なるとエラーの原因になりかねません。
したがって、Pythonのビルドの説明で書いたように、Pythonのバージョンは揃えておいたほうが無難です。
ちなみに、原因不明ですが、私の場合は:python import pip
はエラーになりました。
マイクロバージョン(三桁目)まで揃えたほうがいいのかもしれません。
また、:python
や:python3
で外部モジュールをimportする場合、今回ビルドしたPythonにインストールしておく必要があります。
そのような必要に迫られる機会は少ないと思いますが、一応方法を書いておくと、今回インストールしたPythonのpipでインストールするだけです。
~/Applications/python2.7.8-vim/bin/pip install [module] ~/Applications/python3.4.2-vim/bin/pip3 install [module]
Virtualenv(miyakogi/vim-virtualenvを利用)の仮想環境内では、:python
はきちんとvirtualenvで指定されたバイナリとライブラリを使っていました。
一方、:python3
の方はバイナリは仮想環境のものでしたが、ライブラリは変わっていませんでした。
これはプラグインの方を修正すれば直るんでしょうか
*5
?
終わりに
この記事は上記の方法でビルドしたVimを使ってMarkdownで書いています。 ついでにPythonインターフェイスを使ったプラグイン(未公開)でライブプレビューもしていますが、今の所不具合なく使えています。
Pythonのバイナリと参照するライブラリの食い違いが非常に気持ち悪いのですが、WindowsやArchLinuxなどではどうなっているんでしょう? 特にArchはシステムデフォルトのPythonが3系なのにVimのPythonインターフェイスではpyhton2.7を使っているので、いい感じに何かしてありそうです。
なお、現状python3インターフェイスを使っているVimプラグインは皆無に等しいので、両方使えてもあまり意味ないと思います。
*1:LinuxでPythonをビルドするときの --enable-shared オプションについて - Qiita の末尾や このあたりの議論 を参照
*2:Vimのpython2とかpython3って何?って方はこちらを参照してください。 - VimとPythonのバージョン — KaoriYa
*3:Python - いつの間にかpipのインストールが楽になってた件 - Qiita
*4:書きながら気づきましたが、この時python2を見に行って実行時にはpythonを使うのってどうなんでしょう?ログがそうなってるだけ?(コード見てない)
*5:簡単な修正では直りませんでした