18
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

scikit-buildとcmakeでPythonの拡張モジュールをビルドして配布する

Last updated at Posted at 2019-07-15

scikit-buildというPythonの拡張モジュールをビルドするための補助ツールがあります。

Improved build system generator for CPython C, C++, Cython and Fortran extensions
http://scikit-build.org

これを使ってcmakeでビルドされたプロジェクトをPythonの拡張モジュールとして配布する方法についてまとめます。まとめたものは以下にあります:

全体のディレクトリ構成は以下の通りです:

├── CMakeLists.txt
├── hello
│   ├── CMakeLists.txt
│   ├── _hello.cpp      # これを拡張モジュールにコンパイル
│   ├── __init__.py
│   └── __main__.py     # python -m hello で呼ばれたときに実行されるファイル
├── LICENSE
├── pyproject.toml
├── README.md
└── setup.py    

setup.py

まずは通常のPythonのパッケージと同様にビルド用のスクリプトしてsetup.pyを用意しますが、setuptoolsではなく、skbuildsetupを使います:

setup.py
from skbuild import setup

setup(
    name="hello",
    version="1.2.3",
    description="a minimal example package",
    author="Toshiki Teramura <toshiki.teramura@gmail.com>",
    license="MIT",
    packages=["hello"],
)

pyproject.toml

依存関係は requirements.txt ではなく公式のドキュメントに従って pyproject.toml に記述します

pyproject.toml
[build-system]
requires = ["setuptools", "wheel", "scikit-build", "cmake", "ninja"]

最近はpyproject.tomlの制定によってsetup.pyを書かなくてもpip installできるようになってきているらしいですが、今回はまだsetup.pyの拡張として提供されている機能を使用します。またPoetryにはscikit-buildがどうも対応してなさそう(?)なので今回は使いません。

CMakeLists.txt

元のコード(scikit-build/tests/samples/hello-cpp)がCMakeLists.txtを分割していたので分けていますが、特に意味はありません。順番に見ていきましょう。

CMakeLists.txt
cmake_minimum_required(VERSION 3.5.0)
project(hello)
find_package(PythonExtensions REQUIRED)
add_subdirectory(hello)
hello/CMakeLists.txt
add_library(_hello MODULE _hello.cpp)
python_extension_module(_hello)
install(TARGETS _hello LIBRARY DESTINATION hello)

ポイントとしては PythonExtensions を探してきている部分と、python_extension_module(_hello)ですね。中身は調べられていないのですが、Pythonの拡張モジュールとして公開する際には必要のようです。

Build

setup関数がsetuptoolsからskbuildに切り替わっていますが、基本的な使い方は同じで、

python setup.py bdist_wheel

とすればwheelを作成してくれます。wheelはPEP 427で定義された配布形式で拡張子は *.whl となります。whlファイルは実体としてはZIPアーカイブで、コンパイルされた共有ライブラリや他の静的なファイルを含めることができます。
上のコマンドで、dist/hello-1.2.3-cp37-cp37m-linux_x86_64.whlのようなファイルが出来上がっているはずです。これはそのままインストールが可能です

pip install dist/hello-1.2.3-cp37-cp37m-linux_x86_64.whl --user

--userはお好みで)これでGlobalにインストールされたので 別のディレクトリに行って

$ python -m hello
Hello, World! :)  

となると成功です。別のディレクトリに行かないと現在のディレクトリ以下にある hello モジュールを読み込みますが、ここにはcmakeで生成された拡張モジュールがありません…(´・ω・`)

Links

最後に

Pythonユーザーはpip installできないツールは使わないとの噂ですが、scikit-buildのおかげでC++の拡張も簡単にpipで配布できる形にまとめられるのでこれで使ってもらえますね

18
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?