pybind11を使ってC++で書いたライブラリをPythonから使えるようにする記事は沢山あるが、
作ったものをどうやって公開するかという話はあまりされていないように感じた。
この記事ではpybindが公式提供しているcmake_example
というテンプレートをベースに、公開できる状態のGithubリポジトリをちゃちゃっと作成する手順を述べる。この手順を最後まで踏むと、ユーザーが2,3コマンドを打つだけでインストールして使い始めることができる状態のリポジトリが出来上がる。
1. cmake_exampleをクローンする
cmake_exampleはCMakeを使ってビルドを行うようにセットアップされた公式のテンプレートである。まずはこれを入手する。
cd work # なんか適当な作業ディレクトリに入る
git clone https://github.com/pybind/cmake_example.git
2. 自分のGithubリポジトリを作成してクローンする
リポジトリの作り方は省略する。仮にリポジトリ名はmylib
とする。.gitignoreは自由に作って構わないが、あとでcmake_exampleのものと合成する必要があるので注意。public・privateも好きに設定してよい。出来たらクローンしておく。
git clone https://github.com/*****/mylib.git
3. 自分のGithubリポジトリにpybind11をサブモジュールとして追加する
cd mylib
git submodule add -b master https://github.com/pybind/pybind11.git pybind11
pybind11/
ディレクトリ以下にいろいろダウンロードされ、また.gitmodules
が生成される。
4. 最低限必要なファイルをコピーする
cmake_example/
ディレクトリから必要なファイル&ディレクトリをmylib/
にコピーしてくる。最低限必要なものは以下の通り。
- .gitignore
- CMakeLists.txt
- MANIFEST.in
- LICENSE
- setup.py
- src/
LICENSE
はLICENSE.pybind
のように改名して、別途自分のプロジェクト用のLICENSE
を用意する。前述したとおり、.gitignore
についてはcmake_exampleのものと自分のものをうまくマージする。
5. CMakeLists.txtを編集する
cmake_example
と記載されている箇所を自分のライブラリ名に変更する。
cmake_minimum_required(VERSION 2.8.12)
project(mylib) <--
add_subdirectory(pybind11)
pybind11_add_module(mylib src/main.cpp) <--
6. setup.pyを編集する
一番下のsetup
呼び出し部分を自分の情報に書き換える。
setup(
name='mylib', <-
version='1.0.0', <-
author='oreore', <-
author_email='oreore@example.com', <-
description='HogeHoge', <-
long_description='', <-
ext_modules=[CMakeExtension('mylib')], <-
cmdclass=dict(build_ext=CMakeBuild),
zip_safe=False,
)
必要に応じて以下のように外部ライブラリの要件を記述に加える。
...
zip_safe=False,
packages=find_packages(),
install_requires=['pillow']
7. ソースコードを編集する
main.cpp
のPYBIND11_MODULE
の指定のところで、ライブラリ名をmylib
に書き換える。
PYBIND11_MODULE(mylib, m) {
あとは好きにコードを作成し、必要に応じてCMakeLists.txt
に書き足していく。
8. ビルドする
python setup.py build
エラーがでなければOK
9. インストールする
python setup.py install
10. 動作確認する
mylib/
ディレクトリの外に出てpythonを起動し、ライブラリをimportして動作を確認してみる。mylib/
の中で確認すると、ファイル検索順序の影響でインストールしたファイルではなくカレントディレクトリ以下のファイルが使われる可能性があるので、外で行う。
>>> import mylib
>>> mylib.add(1, 2)
>>> 3
11. コミットして公開する
作ったものをユーザーに使用してもらうには、以下の3ステップを踏んでもらう。
11.1. コンパイラとCMakeを用意してもらう
Ubuntuなどの場合は
sudo apt install build-essential cmake
など打ってもらえばいい。Windowsユーザーの場合は……、頑張ってVisual Studio 2019とCMakeを個別にインストールしてもらおう(ついでにCMakeにはパスを通してもらう必要もある。つらい)。
11.2. リポジトリをクローンしてもらう
ユーザーにリポジトリをクローンしてもらう際は以下のコマンドを実行してもらうようにする。
git clone --recursive https://github.com/******/mylib.git
--recursive
を付けないとpybind11
がダウンロードされずにビルドできないのでちゃんと記載する。
11.3. setup.pyを実行してもらう
python setup.py install
と打ってもらう。以上。
補足1. Pythonのコードも含めたい場合
C++のライブラリだけでなく、Pythonのコードも合わせて提供したい場合は、C++のライブラリ名を_mylib
のように変えて、mylib/__init__.py
からimportとして読み込むようにする。
具体的にはまず、CMakeLists.txt
を以下のようにする。
project(_mylib)
...
pybind11_add_module(_mylib src/main.cpp)
次にsetup.py
ext_modules=[CMakeExtension('mylib._mylib')],
これはビルドの成果物をmylib/_mylib****
(.soあるいは.pyd)に置くことを意味している。
次にsrc/main.cpp
PYBIND11_MODULE(_mylib, m) {
最後にPythonのソースコードを置くmylib/
ディレクトリを用意して__init__.py
を書く。
from ._mylib import *
あとはPythonコードを好きなように書き足す。
補足2. Visual Studio 2019で開発する場合
せっかくCMakeを使っているので、Visual Studio用のソリューションファイルを生成する。
build/
ディレクトリを作り、その中でcmakeを実行する。
mkdir build
cd build
cmake .. -G "Visual Studio 16 2019"
build/mylib.sln
が生成されるので、これを使って開発する。なお、build/
ディレクトリは.gitignore
に含まれているので、ソリューションファイル等をリポジトリに登録したい場合はbuild
ではなく違うディレクトリを使おう。