A Way of Code

興味の赴くままに書き綴っていきます。

Mac OS X 10.7.3 Lionでpythonbrew, virtualenv, pip, buildoutなPython環境を構築する 第2回 pythonbrewとPythonのインストール

前回:http://toggtc.hatenablog.com/entry/2012/02/06/023342

複数バージョンのPython + 仮想環境を実現するために、以下の構成を作っていきます。
今回は、pythonbrewとPythonのインストールです。
f:id:toggtc:20120206003116p:plain

1. 前提環境

  • Mac OS X 10.7.3 (Snow Leopardでもいける気がする)
  • Xcode 4.2.1
  • Apple GCC 4.2.1 (not llvm-gcc)
  • readline 6.2.2 (homebrewからインストール)
  • sqlite 3.7.9 (homebrewからインストール)
  • gdbm 1.10 (homebrewからインストール)
  • ビルドに耐える時間

なお、Pythonインストール時にネットワークを使ったテストコードが走るので、ファイアウォールはOFFにしておきます。

2. pythonbrew本体のインストール

(1) ダウンロード&インストール

$ curl -kL http://xrl.us/pythonbrewinstall | bash

インストール先は~/.pythonbrewにpythonbrewです。
他のインストール先にしたい場合は、本家サイト(https://github.com/utahta/pythonbrew)をご確認ください。

(2) 環境変数の設定

~/.bashrc(もしくは~/.zshrc)に以下の行を追加します。スクリプトのファイル名がbashrcになっていますが、zshでも動くとのこと。

$ vi ~/.bashrc
# 以下を追加
[[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc

(3) パスが通っているかの確認

$ pythonbrew version

バージョンが表示されればOKです。表示されない場合は、Terminalの新規タブか新規ウィンドウを開いて、もう一度実行してみてください。(.bashrcがロードされていない可能性があります)

3. Pythonのインストール

今回は、2.5.6, 2.7.2, 3.2.2の3つのバージョンをインストールします。パッチを当てる作業があるので、以降で示す手順はバージョンが異なるとうまく機能しないかもしれません。

なお、インストールオプションの詳細については、以下を参照してください。
参考:http://toggtc.hatenablog.com/entry/2012/02/05/074212

3.1 Python 2.5.6のインストール

任意のディレクトリで以下のコマンドを実行します。

$ pythonbrew install --verbose --configure="CC=/usr/bin/gcc-4.2 CXX=/usr/bin/g++-4.2 LDFLAGS='-L/usr/local/lib -L/usr/X11R6/lib' --with-bz2 --with-crypt --with-expat --with-md5 --with-ncurses --with-readline --with-sha --with-sqlite3 --with-ssl --with-zlib" 2.5.6

LDFLAGSを設定しておかないと、X11のライブラリを見つけられないので指定しておきます。

ちなみにpythonbrewから2.5.6をインストールすると、いろいろとパッチを当ててくれます。親切です。また、distributeとpipも同時にインストールされます。ありがたいですね。

3.2 Python 2.7.2のインストール

Lion環境の場合、pythonbrewから適用される2.7.2用のパッチだけでは不足なので、一旦、Python 2.7.2のtarボールをダウンロード&展開して、パッチを当ててからpythonbrew経由でインストールします。

手動で適用するパッチの一覧です。

(1) ダウンロード&パッチの適用
# まずはpythonのダウンロードと展開です。
$ cd /private/tmp
$ curl -kLO http://python.org/ftp/python/2.7.2/Python-2.7.2.tgz
$ tar xzf Python-2.7.2.tgz
$ cd Python-2.7.2/
# パッチを格納するディレクトリを作成して...
$ mkdir patches
$ cd patches
# パッチをダウンロードしていきます
$ curl -kLo gdbm-1.9.patch http://hg.python.org/cpython/raw-rev/14cafb8d1480
$ curl -kLO https://raw.github.com/toggtc/python-patch/master/2.7.2/distutils_test_fixup_command_2.7.2.patch
$ curl -kLo test_platform.patch http://hg.python.org/cpython/raw-rev/0a53a978a160
# パッチを当てていきます
$ cd ../
$ patch -p1 < ./patches/gdbm-1.9.patch
patching file Lib/whichdb.py
patching file Misc/NEWS
Hunk #1 FAILED at 76.
1 out of 1 hunk FAILED -- saving rejects to file Misc/NEWS.rej
$ patch -p1 < ./patches/distutils_test_fixup_command_2.7.2.patch
patching file Lib/distutils/tests/test_build_ext.py
$ patch -p1 < ./patches/test_platform.patch
patching file Doc/library/platform.rst
patching file Lib/platform.py
patching file Lib/test/test_platform.py
patching file Misc/NEWS
Hunk #1 FAILED at 101.
1 out of 1 hunk FAILED -- saving rejects to file Misc/NEWS.rej

パッチを当てるとMisc/NEWSのパッチあてに失敗しますが、影響はないので無視します。

これで下ごしらえができました。

(2) インストール

pythonbrewから下ごしらえしたPythonをインストールします。

$ pythonbrew install --verbose --universal --configure="CC=/usr/bin/gcc-4.2 CXX=/usr/bin/g++-4.2 LDFLAGS='-L/usr/local/lib -L/usr/X11R6/lib'" /private/tmp/Python-2.7.2/

Python 2.5.6のときは--with-*をたくさん指定しましたが、2.7.2ではunrecognized optionsとなってしまうので、ここでは指定しません。ビルドログをみると各モジュールがビルドされているようなので、ライブラリを探索して自動的にビルドしているのではないかと思います。

これでPython 2.7.2のインストールが完了しました。

3.3 Python 3.2.2のインストール

2.7.2のときと同じく、事前にtarボールをダウンロード・展開して、パッチを当てておきます。

適用するパッチ: ※2.7.2のときとURLが異なるので注意してください

(1) ダウンロード&パッチの適用

では、pythonのソースをダウンロードしてパッチを当てます。

$ cd /private/tmp
$ curl -kLO http://python.org/ftp/python/3.2.2/Python-3.2.2.tgz
$ tar zxf Python-3.2.2.tgz
$ cd Python-3.2.2
$ mkdir patches
$ cd patches
$ curl -kLo gdbm-1.9.patch http://hg.python.org/cpython/raw-rev/7a41855b6196
$ curl -kLo fixup.patch http://hg.python.org/cpython/raw-rev/6f6100a752ba
$ cd ../
$ patch -p1 < ./patches/gdbm-1.9.patch
patching file Lib/dbm/__init__.py
patching file Misc/NEWS
Hunk #1 FAILED at 55.
1 out of 1 hunk FAILED -- saving rejects to file Misc/NEWS.rej
$ patch -p1 < ./patches/fixup.patch
patching file Lib/distutils/tests/support.py
Hunk #1 succeeded at 189 (offset 1 line).
Hunk #2 succeeded at 203 (offset 1 line).
patching file Misc/NEWS
Hunk #1 FAILED at 113.
1 out of 1 hunk FAILED -- saving rejects to file Misc/NEWS.rej
(2) インストール

下ごしらえができたので、インストールします。
なんとなく3系なので、--with-pydebug付きでビルドします。デバッグメッセージが出たり、なんとなくモッサリ気味になるので不要な場合は外してください。

$ pythonbrew install --verbose --universal --configure="CC=/usr/bin/gcc-4.2 CXX=/usr/bin/g++-4.2 LDFLAGS='-L/usr/local/lib -L/usr/X11R6/lib' --with-pydebug" /private/tmp/Python-3.2.2/

これでpython 3.2.2のインストールが完了しました。

3.4 symlinkを貼る(おまけ)

任意のディレクトリで、以下を実行。

$ pythonbrew symlink

これによって、~/.pythonbrew/bin直下に、py*というリンクが貼られます。

$ ll
py2.5.6 -> /Users/toggtc/.pythonbrew/pythons/Python-2.5.6/bin/python
py2.7.2 -> /Users/toggtc/.pythonbrew/pythons/Python-2.7.2/bin/python
py3.2.2 -> /Users/toggtc/.pythonbrew/pythons/Python-3.2.2/bin/python

pythonbrewインストール時に、~/.pythonbrew/binのパスが環境変数PATHに追加されているので、py2.7.2と打つことで、python 2.7.2のインタプリタを起動できるわけです。

$ py2.7.2
Python 2.7.2 (default, Jan 25 2012, 14:51:41) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

うーん、便利!

3.5 pythonbrewを使ってみた感想

バージョンを指定してインストール・アンインストールできるのがいいですね!homebrewでは細かいバージョンの管理や切り替えは想定していないようなので、Pythonのインストールはpythonbrewで行うことをお勧めします。
ただ、Pythonをインストールするにあたって、2つほど気になったところがありました。

(1) pythonbrewのパッチの仕組みはもう少し柔軟性が欲しい
パッチを当てようとすると、今回のインストールでやったようにソースとパッチをそれぞれダウンロードして、個別にパッチを当てる必要があります。
仕組みとしては~/.pythonbrew/patchesディレクトリがあるので、そこにパッチを格納すれば自動でパッチを当ててくれるか、あるいは、パッチリストのテキストファイルを置いておけば自動でダウンロード&パッチ当てまでしてくれると手間がなくていいですね。

(2) 複数のバージョンをインストールしたときに、最後のビルドログが上書きされてしまう
Pythonのビルドログには、どのモジュールがビルドされなかったか等の重要な情報があるため、Pythonを動かしているときになんらかの不具合があったとき、ビルドに原因があった、なんていうケースが出てくるかもしれません。そんなとき、ログが残っていると嬉しいのですが、pythonbrewはビルドログを上書きしてしまうので、インストール完了時に別名保存しておいたほうがいいですね。

なんにせよ、初心者にとってはシステムのPythonを汚さないサンドボックスかつバージョンが切り替えられる環境が手に入るのは嬉しいことです。今後もユーザ(デベロッパー)フレンドリーなツールが充実してくるといいですね。
次回は仮想環境の構築をしていきます。

次回 仮想環境の構築:http://toggtc.hatenablog.com/entry/2012/02/06/023807