Pythonパッケージの配布方法いろいろ

Pythonソースコードでないプログラムを配布しようとするとき、主に次の二つの方法があります。

  • sdist
  • bdist

sdistはソースディストリビューションの略でソースコード状態での配布を、bdistはバイナリディストリビューションの略でバイナリの配布を意味します。bdistの中にも種類があり、wheel形式の配布物を作るときbdist_wheelにします。

これらの形式を指定して配布物を作成するとき、setup.pyを用いて次のようにします。

1
2
3
python3 setup.py sdist
python3 setup.py bdist
python3 setup.py bdist_wheel

また、バイナリ配布は動的ライブラリやライブラリローダの場所が環境依存なのでできるだけ避けたほうがいいと思います。

パッケージに含めるファイルの指定

setup.pyでも指定できますが、ややこしいのと、方法が一貫的じゃないのでMANIFEST.inを使います。C++関係のファイルを追加するには./MANIFEST.inに次の内容を書きます。

1
include *.cpp *.hpp Makefile

詳細はこちら https://docs.python.org/ja/3/distutils/sourcedist.html#specifying-the-files-to-distribute

pip install時コンパイル

pip install時には任意の処理を行うことができます。

関連する処理を抜き出しました。ポイントはsetuptools.setupcmdclass -> build_extを指定しているとこです。pip install時にはpython3 setup.py buildみたいな処理が走るのですが、ここでその処理を上書きしています。ただ、このコードを走らせるためにはcmdclass -> ext_modulesに少なくとも一つExtensionがないといけないので適当に入れています。

hogeのように意味のない文字を入れていますが、my_extbuild_extensionをオーバーライドしていない場合にはsetuptoolsによってビルドが行われ、hoge.cpython-38-x86_64-linux-gnu.soみたいな成果物ができます。しかしこのsetuptoolsのビルドはコンパイラの動作をラッピングしているだけではっきり言っておせっかいなので、自分でMakefileなりスクリプトなりを書くのがおすすめです。)

また、self.build_libにはビルド時の一時的な生成物置き場が指定されており、ここに置いたファイルがインストールされ、アンインストール時には削除されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import subprocess
import glob
import shutil
import os
from setuptools import setup
from setuptools.extension import Extension
from setuptools.command.build_ext import build_ext

class my_ext(build_ext):
def build_extension(self, ext):
# make
subprocess.run(['make'])
# 生成物見つける
bins = glob.glob('*.so')
for bin in bins:
# self.build_libへ移動
outpath = os.path.join(self.build_lib, bin)
shutil.move(bin, outpath)


setuptools.setup(
...
cmdclass={
'build_ext': my_ext,
},
ext_modules=[
Extension('hoge', []),
]
)

私のリポジトリにこのやり方で配布しているプロジェクトがあるので全体を見たい方はどうぞ。 https://github.com/shosatojp/ffcache/blob/master/setup.py

setup.pyのデバッグ

pipsdistで生成されたtar.xzからもインストールできるのでpypiに上げる前に試しておくといいです。

1
2
3
4
rm -rf dist/ build/ *.egg-info/

python3 setup.py sdist
pip3 install sdist/myproject-0.0.1.tar.xz

参考