Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
12
Help us understand the problem. What is going on with this article?
@termoshtt

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

More than 1 year has passed since last update.

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で配布できる形にまとめられるのでこれで使ってもらえますね

12
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ricos
FEMによる構造解析、機械学習の専門家集団。計算資源のクラウド提供もしています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
12
Help us understand the problem. What is going on with this article?