$ brew install boost-python --with-python3
なのだが、すこしハマりどころがある。
brew install boost-python のオプション
brew install
にはオプションを指定できる場合がある。
boost-python の場合は --with-python3
オプションが使える。
brew options
で使用可能なオプションをすべて表示することができる。
$ brew options boost-python
--c++11
Build using C++11 mode
--with-python3
Build with python3 support
--without-python
Build without python 2 support
--HEAD
Install HEAD version
--with-python3
を指定した場合、boost-python
はソースコードからビルドされる。
インストール手順
Homebrew の formula はオプションのあり・なしに関わらず重複インストールできないので、 すでにインストールしている場合ははじめにアンインストールする。
$ # macOS Sierra (10.12) + Homebrew
$ # おこられる
$ brew install boost-python --with-python3
Warning: boost-python 1.65.1 is already installed
$
$ # はじめにアンインストール
$ brew uninstall boost-python
Uninstalling /usr/local/Cellar/boost-python/1.65.1... (457 files, 16MB)
$
$ # ---------------------------------------------------------------------------
$ # * この処理は実際は不要です
$ # オプションなしインストール(参考)。ビルド済みバイナリがインストールされる。
$ brew install boost-python
==> Downloading https://homebrew.bintray.com/bottles/boost-python-1.65.1.sierra.bottle.tar.gz
==> Pouring boost-python-1.65.1.sierra.bottle.tar.gz
🍺 /usr/local/Cellar/boost-python/1.65.1: 457 files, 16MB
$
$ # ふたたびアンインストール
$ brew uninstall boost-python
Uninstalling /usr/local/Cellar/boost-python/1.65.1... (457 files, 16MB)
$ # ---------------------------------------------------------------------------
$
$ # python3 版をビルドしてインストールする
$ brew install boost-python --with-python3
==> Downloading https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.bz2
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.65.1 --libdir=/usr/local/Cellar/boost-python/1.65.1/lib --with-libraries=python --with-python=python --with-python-root=/System/Library/Frameworks/Python.framework/Versions/2.7
==> ./b2 --build-dir=build-python --stagedir=stage-python python=2.7 --prefix=/usr/local/Cellar/boost-python/1.65.1 --libdir=/usr/local/Cellar/boost-python/1.65.1/lib -d2 -j4 --layout=tagged --user-config=user-config.jam threading=multi,single link=shared,static
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.65.1 --libdir=/usr/local/Cellar/boost-python/1.65.1/lib --with-libraries=python --with-python=python3 --with-python-root=/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6
==> ./b2 --build-dir=build-python3 --stagedir=stage-python3 python=3.6 --prefix=/usr/local/Cellar/boost-python/1.65.1 --libdir=/usr/local/Cellar/boost-python/1.65.1/lib -d2 -j4 --layout=tagged --user-config=user-config.jam threading=multi,single link=shared,static
🍺 /usr/local/Cellar/boost-python/1.65.1: 465 files, 28.4MB, built in 7 minutes 21 seconds
Python 2 用と Python 3 用のバイナリが両方ビルドされています。バッチリです。
Python 3 用のライブラリにリンクする(重要)
- Python 2 用の場合は
-lboost_python
,-lboost_numpy
を指定する。 - Python 3 用の場合は
-lboost_python3
,-lboost_numpy3
を指定する。
Python 2 用と Python 3 用のライブラリは名前がことなるため注意が必要です。
$ ls /usr/local/lib | grep libboost_python
libboost_python-mt.a
libboost_python-mt.dylib
libboost_python.a
libboost_python.dylib
libboost_python3-mt.a
libboost_python3-mt.dylib
libboost_python3.a
libboost_python3.dylib
テストとして python-multi-array ライブラリをビルドします。 ビルドスクリプトは setup.py です。
https://github.com/yokaze/python-multi-array
$ # -lboost_python3, -lboost_numpy3 だとちゃんと動く
$ python3
>>> import multi_array
>>>
ここを間違えると結局 Python 2 用のライブラリにリンクされてしまい、拡張モジュールがうまく動きません。
$ # -lboost_python, -lboost_numpy
$ python3
>>> import multi_array
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(multi_array.cpython-36m-darwin.so, 2): Symbol not found: _PyClass_Type
Referenced from: /usr/local/opt/boost-python/lib/libboost_python.dylib
Expected in: flat namespace
in /usr/local/opt/boost-python/lib/libboost_python.dylib
>>>
参考資料
- A python wrapper for boost::multi_array
https://github.com/yokaze/python-multi-array