付録A 上級パッケージング

目次

A.1. 共有ライブラリー
A.2. debian/package.symbols の管理
A.3. マルチアーチ
A.4. 共有ライブラリーパッケージのビルド
A.5. ネイティブ Debian パッケージ

あなたが出会いそうな上級パッケージング課題に関するヒントや外部参照をいくつか記します。ここに提案されたレファレンス全てに目を通すことを切にお薦めします。

本章で取り上げたトピックをカバーするには dh_make コマンドで生成されたパッケージ用テンプレートファイルではマニュアル編集する必要があるかもしれません。より新しい debmake コマンドはこのようなトピックへの対応が優れています。

共有 ライブラリー をパッケージングする前に、以下の 一次レファレンスを詳細に読むべきです:

以下はあなたが手を付け始めるための少々簡略化しすぎたヒントです:

  • 共有ライブラリーとはコンパイルされたコードを含む ELF オブジェクトファイルです。

  • 共有ライブラリーは *.so ファイルとして頒布されます。(*.a ファイルでも *.la ファイルでもありません)

  • 主に、共有ライブラリーは ld メカニズムを用い複数の実行プログラム間でコードを共有するのに使用されます。

  • 時々、共有ライブラリーは dlopen メカニズムを用いある実行プログラムに複数のプラグインを提供するのに使用されます。

  • 共有ライブラリーは変数や関数やクラスのようなコンパイルされたオブジェクトを表す シンボル をエキスポートし、リンクされた実行プログラムからそれらへのアクセスを可能とします。

  • 共有ライブラリー libfoo.so.1SONAME: objdump -p libfoo.so.1 | grep SONAME [88]

  • 共有ライブラリーの SONAME は通常ライブラリーのファイル名と一致します(例外もあります)。

  • /usr/bin/foo にリンクされた共有ライブラリーの SONAME: objdump -p /usr/bin/foo | grep NEEDED [89]

  • libfoo1: 共有ライブラリー libfoo.so.1 で SONAME ABI バージョンが 1 のライブラリーパッケージ。[90]

  • ライブラリーパッケージのパッケージメンテナースクリプトは SONAME に必要なシンボリックリンクを作成するために特定の環境下で ldconfig を呼ばなければいけません。[91]

  • libfoo1-dbg: 共有ライブラリー libfoo1 のデバッグシンボルを含むデバッグシンボルパッケージ。

  • libfoo-dev: 共有ライブラリー libfoo.so.1 用のヘッダーファイル他を含む開発用パッケージ 。[92]

  • Debian パッケージは一般的に *.la Libtool アーカイブファイルを含んではいけません。[93]

  • Debian パッケージは一般的に RPATH を使うべきではありません。[94]

  • 少々内容が古くなった二次的なレファレンスですが、Debian Library Packaging Guide はまだ有用かもしれません。

共有ライブラリーをパッケージする際には、同一共有ライブラリーパッケージ名のライブラリーの同一 SONAME の下での後方互換性のある変更に関して、各シンボルと関連付けられる最小のバージョンが記された debian/package.symbols ファイルを作成すべきです。[95] 以下の一次的レファレンスを詳細に読むべきです:

過去バージョン 1.3 のアップストリームバージョンから適切な debian/libfoo1.symbols ファイルを用いて libfoo1 パッケージを作成する概略例は以下です:

  • アップストリームの libfoo-1.3.tar.gz ファイルを用いてDebian 化したソースツリーの骨子を準備します。

    • もし libfoo1 パッケージの最初のパッケージングの場合は、内容が空の debian/libfoo1.symbols ファイルを作成します。

    • もし以前のアップストリームバージョン 1.2libfoo1 パッケージとして適切な debian/libfoo1.symbols を用いてパッケージされていた場合には、それを再び使いましょう。

    • もし過去のアップストリームバージョン 1.2debian/libfoo1.symbols を用いてパッケージされていない場合には、そのライブラリーの同一 SONAME を含む同一共有ライブラリーパッケージ名 の全ての手に入るバイナリーパッケージ、例えば 1.1-11.2-1 バージョンから、それを symbols として生成できます。[97]

      $ dpkg-deb -x libfoo1_1.1-1.deb libfoo1_1.1-1
      $ dpkg-deb -x libfoo1_1.2-1.deb libfoo1_1.2-1
      $ : > symbols
      $ dpkg-gensymbols -v1.1 -plibfoo1 -Plibfoo1_1.1-1 -Osymbols
      $ dpkg-gensymbols -v1.2 -plibfoo1 -Plibfoo1_1.2-1 -Osymbols
      
  • debuildpdebuild 等のツールを使ってソースツリーのテストビルドをします。 (もしシンボルの欠如等でビルドがうまく行かない場合には、共有ライブラリーパッケージ名を libfoo1a 等と繰り上げる必要のある何らかの後方非互換な ABI 変更があったので、最初からやり直す必要があります。)

    $ cd libfoo-1.3
    $ debuild
    ...
    dpkg-gensymbols: warning: some new symbols appeared in the symbols file: ...
     see diff output below
    --- debian/libfoo1.symbols (libfoo1_1.3-1_amd64)
    +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
    @@ -127,6 +127,7 @@
      foo_get_name@Base 1.1
      foo_get_longname@Base 1.2
      foo_get_type@Base 1.1
    + foo_get_longtype@Base 1.3-1
      foo_get_symbol@Base 1.1
      foo_get_rank@Base 1.1
      foo_new@Base 1.1
    ...
    
  • もし上記のように dpkg-gensymbols によって diff がプリントされるのを発見した場合には、生成された共有ライブラリーのバイナリーパッケージから適切な symbols ファイルを抽出しましょう。[98]

    $ cd ..
    $ dpkg-deb -R  libfoo1_1.3_amd64.deb libfoo1-tmp
    $ sed -e 's/1\.3-1/1\.3/' libfoo1-tmp/DEBIAN/symbols \
            >libfoo-1.3/debian/libfoo1.symbols
    
  • debuildpdebuild のようなツールでリリースパッケージをビルドします。

    $ cd libfoo-1.3
    $ debuild clean
    $ debuild
    ...
    

上記の例に加えて、更に ABI 互換性を確認し、必要に応じていくつかのシンボルのバージョンを手作業で繰り上げる必要があります。[99]

二次的なレファレンスではありますが、Debian wiki UsingSymbolsFiles とそこからリンクされているウェブページは有用かもしれません。

Debian wheezy で導入されたマルチアーチ機能は dpkgapt の中でのバイナリーパッケージのアーキテクチャー間サポート (他の組み合わせもありますが、特にi386<->amd64) を統合します。 以下のレファレンスを詳細に読んで下さい:

マルチアーチは共有ライブラリーのインストールパスに i386-linux-gnux86_64-linux-gnu 等のトリプレットを使います。実際のトリプレットパスは、ビルドごとに dpkg-architecture(1) によって動的に $(DEB_HOST_MULTIARCH) 値として設定されます。例えば、マルチアーチライブラリーをインストールするパスは以下のように変更されます: [100]

以下の場合に関する典型的なパッケージ分割シナリオの例を示します。

  • ライブラリーソース libfoo-1.tar.gz

  • コンパイラー用の言語で書かれたツールのソース bar-1.tar.gz

  • インタープリター用言語で書かれたツールのソース baz-1.tar.gz

開発パッケージは関連した共有ライブラリーへのバージョン番号無しのシンボリックリンクを含んでいるべきです。例えば: /usr/lib/x86_64-linux-gnu/libfoo.so -> libfoo.so.1

dh(1) を以下のように使えばマルチアーチをサポートするようにして Debian のライブラリーパッケージをビルドできます:

共有ライブラリーパッケージが期待されるファイルのみを含み、-dev パッケージも依然として動作することを確認しましょう。

マルチアーチパッケージとして同時に同一パスにインストールされる全てのファイルはファイルの内容が完全に同じあるべきです。データのバイトオーダーや圧縮アルゴリズムにより生成される相違に注意すべきです。

もしパッケージが Debian のためだけとか、またローカル使用のために保守されている場合、そのソースファイルは debian/* ファイルすべてをその中に含まれます。それをパッケージするのには2つの方法があります。

debian/* ファイルを除外したアップストリームターボールを作成し、「Debian パッケージビルドのワークフロー」 にあるようにしてノンネイティブ Debian パッケージできます。これが一部の人に推奨される通常の方法です。

この代わりの方法は、ネイティブ Debian パッケージのワークフローです。

  • 全てのファイルが含まれる単一の圧縮された tar ファイルを用いる 3.0 (native) フォーマットでネイティブの Debian ソースパッケージを作成します。

    • package_version.tar.gz
    • package_version.dsc
  • ネイティブ Debian ソースパッケージから、Debian バイナリーパッケージをビルドします。

    • package_version_arch.deb

例えば debian/* ファイルを含まない ~/mypackage-1.0 ソースファイルがあれば、以下のように dh_make コマンドを用いてネイティブ Debian パッケージが作れます:

$ cd ~/mypackage-1.0
$ dh_make --native

すると、debian ディレクトリーとその内容は 「最初のノンネイティブ Debian パッケージ」 とちょうど同じように作成されます。これはネイティブ Debian パッケージなので tar アーカイブを作りません。しかし相違点はこれだけです。他のパッケージング操作は実質的にまったく同じです。

dpkg-buildpackage コマンドを実行した後、親ディレクトリーに以下のファイルが生成します:

  • mypackage_1.0.tar.gz

    これは、dpkg-source コマンドにより mypackage-1.0 ディレクトリーから作られたソースコードのターボールです。(そのサフィックスは orig.tar.gz ではありません。)

  • mypackage_1.0.dsc

    これは、ノンネイティブ Debian パッケージと同様でソースコード内容の要約です。(Debian リビジョンはありません。)

  • mypackage_1.0_i386.deb

    これは、ノンネイティブ Debian パッケージと同様で完成したバイナリーパッケージです。(Debian リビジョンはありません。)

  • mypackage_1.0_i386.changes

    これは、ノンネイティブ Debian パッケージと同様で現パッケージバージョンでの全変更を記述します。(Debian リビジョンはありません。)



[88] もしくは: readelf -d libfoo.so.1 | grep SONAME

[89] もしくは: readelf -d libfoo.so.1 | grep NEEDED

[94] Debian wiki RpathIssue を参照下さい。

[95] 後方非互換な ABI 変更をした場合、通常、ライブラリーの SONAME と共有ライブラリーパッケージ名を新規なものにそれぞれアップデートしないといけません。

[96] C++ ライブラリーや個別シンボルを追跡するのが非常に困難な他の場合には、これに代えて Debian Policy Manual, 8.6.4 "The shlibs system" に従いましょう。

[97] Debian パッケージの過去全てのバージョンは http://snapshot.debian.org/ から得られます。 パッケージのバックポートが楽にできるように Debian リビジョンはバージョンから取り除きます。: 1.1 << 1.1-1~bpo70+1 << 1.1-11.2 << 1.2-1~bpo70+1 << 1.2-1

[98] Debian リビジョンはパッケージのバックポートを容易にすべく外します: 1.3 << 1.3-1~bpo70+1 << 1.3-1

[100] 旧来の /lib32//lib64/ 等の特定目的のライブラリーパスは使われなくなっています。

[101] これに代えて、./configure--libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)--libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) 引数を追加することもできます。注意いただきたいのは、ユーザーではなく他のプログラムによりのみ実行される実行プログラムをインストールするデフォルトパスを --libexecdir は設定します。その Autotools のデフォルトは /usr/libexec/ ですが、Debian デフォルトは /usr/lib/ です。