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

目次

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

Here are some hints and pointers for advanced packaging topics that you are most likely to deal with. You are strongly advised to read all the references suggested here.

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

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

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

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

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

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

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

  • Shared libraries export symbols, which represent compiled objects such as variables, functions, and classes; and enable access to them from the linked executables.

  • 共有ライブラリー 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: the debugging symbols package that contains the debugging symbols for the shared library package libfoo1.

  • libfoo-dev: the development package that contains the header files etc. for the shared library libfoo.so.1.[92]

  • Debian packages should not contain *.la Libtool archive files in general.[93]

  • Debian packages should not use RPATH in general.[94]

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

When you package a shared library, you should create a debian/package.symbols file to manage the minimal version associated with each symbol for backward-compatible ABI changes under the same SONAME of the library for the same shared library package name.[95] You should read the following primary references in detail:

Here is a rough example of how to create the libfoo1 package from the upstream version 1.3 with the proper debian/libfoo1.symbols file:

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

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

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

    • If the previous upstream version 1.2 was not packaged with debian/libfoo1.symbols, create it as the symbols file from all available binary packages of the same shared library package name containing the same SONAME of the library, for example, versions 1.1-1 and 1.2-1. [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
      
  • Make trial builds of the source tree with tools such as debuild and pdebuild. (If this fails due to missing symbols etc., there were some backward-incompatible ABI changes that require you to bump the shared library package name to something like libfoo1a and you should start over again.)

    $ 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
    ...
    
  • If you see the diff printed by the dpkg-gensymbols as above, extract the proper updated symbols file from the generated binary package of the shared library. [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]

Here are some typical multiarch package split scenario examples for the following:

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

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

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

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

You can build a Debian library package enabling multiarch support using dh(1) as follows:

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

All files installed simultaneously as the multiarch package to the same file path should have exactly the same file content. You must be careful of differences generated by the data byte order and by the compression algorithm.

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

You can make the upstream tarball by excluding the debian/* files and package it as a non-native Debian package as in 「Debian パッケージビルドのワークフロー」. This is the normal way, which some people encourage using.

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

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

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

    • package_version_arch.deb

For example, if you have source files in ~/mypackage-1.0 without the debian/* files, you can create a native Debian package by issuing the dh_make command as follows:

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

Then the debian directory and its contents are created just like in 「最初のノンネイティブ Debian パッケージ」. This does not create a tarball, since this is a native Debian package. But that is the only difference. The rest of the packaging activities are practically the same.

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

  • mypackage_1.0.tar.gz

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

  • mypackage_1.0.dsc

    This is a summary of the contents of the source code, as in the non-native Debian package. (There is no Debian revision.)

  • mypackage_1.0_i386.deb

    This is your completed binary package, as in the non-native Debian package. (There is no Debian revision.)

  • 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] Old special purpose library paths such as /lib32/ and /lib64/ are not used anymore.

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