python3用とpython2用のmultipleなdebパッケージを作るubuntuパッケージの作り方

debパッケージの作るのにはdebianディレクトリ以下の記述ファイルが多く必要で、その管理のためにコマンドやツールを多用したりするため、(rpmのspec作成がコピペから始められるのに比べると、)最初のものを用意するまでに多くの知識を得る必要があります。
そして、pythonパッケージを作る、python2系だけじゃなくpython3系でも使えるようにするパッケージの作るための情報というのは特に少なく、他の構成でのやり方をいろいろ試していきながらうまくいく方法を得ました。
この記事では、python-helloソースから、python2系用のpython-helloパッケージと、python3系用のpython3-helloパッケージを同時に作成することを想定したもので、応用可能な方法を記述していきます。

パッケージ対象

debの元となるパッケージは、python2でもpython3でも、同一のsetup.pyでbuild/installできるpythonパッケージである必要があります。

こうになっていればpure pythonモジュールでも、dllモジュールでも基本は同じやり方でdebパッケージ化できます。

例題: python-helloのdebパッケージ化

以下のような簡単な3ファイルだけで構成されたpythonパッケージを例に、debの作り方を説明します。

def world():
    return "Hello World!"
from distutils.core import setup

setup(
    name="hello",
    version="1.0.0",
    py_modules=["hello"],
    )
module example: hello

dh_makeによるdebianディレクトリ雛形作成

まずディレクトリ名をpackagename-versionとなるように変更し、その中でdh_makeします。

mv python-hello python-hello-1.0.0
cd  python-hello-1.0.0
dh_make --createorig -b -c bsd
rm debian/*.ex debian/*.EX
rm debian/docs
rm debian/README.source

(以下、このカレントディレクトリから、すべてコマンドを実行していきます)

man dh_makeで出てくるオプションをつけることで、例えば"-c bsd"とすることでライセンス情報なども含んだ雛形が作れます。
dh_makeをすると、いっぱいファイルが出来ますが、生成されるファイルのうち*.exや*.EXは追加処理用のテンプレートであり、不要なので全部消します。docsファイルもmultipleパッケージでは、バイナリパッケージごとに用意することになるので消します。
また、debian/README.sourceも特に書く事がないのであれば消します。すると、以下のファイルだけが残ることになります。

以下これらのファイルが適切なものになるよう編集していくことになります。

まず、debian/README.Debiandebian/copyrightを適切に編集します。"<"と">"で括られた箇所は何か書けと書いてある部分であり、そこを埋めるか削るかします。

comaptファイルは、このdebianディレクトリ下ファイルの仕様バージョン(debhelperのバージョン)です。ふつうそのままでOKです。

debian/changelog の編集

changelogファイルは生成バイナリパッケージのバージョン情報となるので、適切に編集していく必要があります。
changelogを編集するためのコマンドdchがあるので、それを使うのがいいでしょう。

最初のdebian/changelogを編集します。

dch -v 1.0.0-1nmu1

このコマンドでは、雛形が埋められてエディタが立ち上がります。そのまま編集してから、保存終了させます。changelogエントリは、たとえば以下のように書きます。

python-hello (1.0.0-1nmu1) lucid; urgency=low

  * packaging for ubuntu

 -- bellbind <bellbind@gmail.com>  Wed, 28 Jul 2010 23:58:57 +0900

"nmu"とはNone Maintainers Updateの略で、野良パッケージではこれをパッケージバージョンに入れておけば、チェックでいろいろ警告がでるのを抑えることができます。

debian/rules の編集

debian/rulesは、本来ビルドやインストールの方法を書くファイルです。

標準では以下の3行にします。

#!/usr/bin/make -f
%:
	dh $@


pythonパッケージで、setup.pyが使える場合、debian/rulesは以下の五行にしておけば良いです。

#!/usr/bin/make -f
DEB_PYTHON_SYSTEM=pysupport
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/python-distutils.mk
DEB_COMPRESS_EXCLUDE := .py

debian/control の編集

このファイルには、ソースパッケージとバイナリパッケージの説明や依存関係等の情報を記述します。
このソースパッケージの情報をもとにビルドし、インストール時は、その下のバイナリパッケージの情報に基づいて管理されます。

python-helloのcontrolファイルの全体を書いておきます。
このファイルだけは、パッケージ化するpythonモジュールがpure pythonだけか、native moduleを含むかで若干記述が変わるので、両方載せておきます。

pure python module用 debian/control
Source: python-hello
Section: python
Priority: extra
Maintainer: bellbind <bellbind@gmail.com>
Build-Depends: debhelper (>= 7),  python-support,
 python-setuptools, python3-setuptools
Standards-Version: 3.8.4
XS-Python-Version: 2.6, 3.1
Homepage: http://example.com/python-hello

Package: python-hello
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python
Description: Example python module pakage
 Usage:
 .
      import hello
      print(hello.world())
 .

Package: python3-hello
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python3
Description: Example python module pakage
 Usage:
 .
      import hello
      print(hello.world())
 .

重要なポイントは、XS-Python-Versionにpython2とpython3の両方のバージョンを書くことです。Build-DependsとDependsも適切なものを指定する必要があります。

native module用debian/control
Source: python-hello
Section: python
Priority: extra
Maintainer: bellbind <bellbind@gmail.com>
Build-Depends: debhelper (>= 7),  python-support,
 python2.6-dev, python3.1-dev, python-setuptools, python3-setuptools
Standards-Version: 3.8.4
XS-Python-Version: 2.6, 3.1
Homepage: http://example.com/python-hello

Package: python2.6-hello
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, python2.6
Description: Example python module pakage
 Usage:
 .
      import hello
      print(hello.world())
 .

Package: python3.1-hello
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, python3.1
Description: Example python module pakage
 Usage:
 .
      import hello
      print(hello.world())
 .

pure python版との違いは、以下3点だけです(debian/rules, .install等も変更不要です)。

  • バイナリパッケージをPythonのバイナリバージョンごとに用意する(python2系でもpython2.6とpython2.7で別パッケージにする必要がある)
  • Archtecture: allを Archtecture: any にする(もしくは特定のアーキテクチャ名をリストアップ)
  • Build-Depends に python2.6-dev, python3.1-devを入れる


2.6系と3.1系バイナリでメジャーパッケージのProvidesを設定してもよいでしょう。

Package: python2.6-hello
Provides: python-hello
...

将来、2.7系がpythonのメジャーパッケージに変わったらReplacesを設定して置き換えることになります。たとえば、1.0.1からpython2.7系をpython-helloのメインにする場合以下のようになります。

Package: python2.7-hello
Provides: python-hello
Replaces: python-hello (<< 1.0.1)
...

追加ファイル: packagename.install

マルチバイナリパッケージの場合、debian/tmp以下にinstall後のファイル構造が作られます。
その中にあるファイルを各バイナリパッケージに振り分ける必要があります。
それを指定するのが、*.installファイルです。ディレクトリトップからのファイルglobパターンで記述します。

この例では、バイナリパッケージは、python-helloとpython3-helloがあるので、

debian/tmp/usr/lib/python2.6/*
  • debian/python3-hello.install
debian/tmp/usr/lib/python3.1/*

を用意します。

追加ファイル: packagename.docs

同様に、パッケージの追加ドキュメントになるファイルは、*.docsファイルで指定します。

README.txt
README.txt

確認

ここまでできていれば、ファイル構成は以下のようになっているはずです。

パッケージビルド

この記述でバイナリパッケージを生成できるかチェックします。

debuild -uc -us

作成時、多くのlintianのエラーや警告が出ますが、上のディレクトリにはpython-helloとpython3-helloの二つのdebファイルが生成できているはずです。debファイルの生成確認を持って、ここで終わりとします。launchpadのppa等に公開するためには、このlintianエラーや警告が消えるように頑張っていくことになります。

応用

  • binaryモジュールは、必要なライブラリをcontrolに書く必要があります。
  • /etc等どっちのモジュールでも使うものはpackagename-commonパッケージをつくるようにし、それを各バイナリパッケージのDependsに入れておけばいいでしょう。
  • ソースがpython3とpython2でsetupファイルが別の場合、sys.versionでimportするsetupファイルを切り替えるsetup.pyを用意します。
  • debian/rulesのpysupportでだめなら、pycentralを使う

おまけ: debファイル中のファイルリスト一覧を取り出すには

dpkg-deb -c ../python-hello_1.0.0-1nmu1_i386.deb

おまけ: lintianメッセージを詳細情報つきで出すには

lintian -i ../python-hello_1.0.0-1nmu1_i386.changes | lv

トラブルシューティング

  • ログで「XS-Python-Versionはdeprecateで、debian/pyversionを使え」のようなメッセージが出るが、lucidではこのやり方ではmulti packageではエラーになってしまい、debian/pyversionsは使えなかった
  • python3パッケージのモジュールが、debian系でsys.pathが通っているdist-packagesではなく、site-packages下に入る。python2では同じ記述でpyshared下に入るので、まだpython-support/python-centralがpython3向けにうまく機能していないのだろう。これはsys.pathにsite-packagesへのPATHを追加すれば使うことはできるが...
    • debian/rulesを(cdbsではなく)dhで書く