はじめに
debパッケージは利用するには便利だが作るとなると途端に面倒くさくなる。Debianの長い歴史の中で数々のユーティリティが作られ、新しいツールも置換することを目的とせず多くの歴史的スクリプトに依存しつつ補完しているからだ。またDebianコミュニティはdebパッケージをDebianのみ使うことを想定しており、ユーティリティにはDebianポリシーに適合するかといったDebian固有の要求事項が一緒くたになっている。信頼出来る唯一の情報源であるDebian文書も同様であり、debパッケージのビルドシステムは広範なLinuxディストリビューションにパッケージを提供するために設計されていない。
※もっともこれはDebianに後乗りした派生ディストロが解決すべき課題なのだが。
とはいってもdebパッケージはDebian系ディストロでのソフトウェア/データ運搬手段として優れている。SnapとかAppImageといったサンドボックス系パッケージシステムはまだ版図が決まりきっていない印象があり、現実的にはdebパッケージを使わざるを得ない。
本文では飽くまでリポジトリへのアップロードを目的とせず、個人もしくは組織内部で使うためのdebパッケージの作成方法について取り扱う。
Debian/Ubuntuリポジトリでリリースする為の正当な方法についてはそれらの公式ドキュメントを参照してほしい。
簡易版バイナリパッケージ作成方法
バージョン管理もコンパイルもせず、本当にデータの集合をまとめて*.debファイルだけ作りたい場合はdpkg-dev --build
を実行する方法が簡便だ。以下が分かりやすい。
社内利用のための deb パッケージング入門 - Cybozu Inside Out
この方法はdebのビルド過程の上では最終出力物の梱包だけを行っている状態だ。通常含まれているchangelogやcopyright等のファイルは手動で管理する必要があるし、アーキテクチャ毎にディレクトリを用意しなければならない。1回のリリースだけで終わらず変更を管理する必要があるならソースパッケージを作成してツールによる補助を利用したい。
ソースパッケージの概要
最近のdebビルドシステムでは次の2つのモデルケースがある。
上流ソースが存在するケース
独自にバージョン管理する上流ソースが存在し、それをDebian(系)にポーティングするケース。これらはポーティング後の独自変更を区別するために、quilt
というパッチ管理ツールを介してソースへの変更を記録する。またこのケースにによるフォーマット自体もquiltと呼ばれ、基本的にこのquiltフォーマットがデフォルトである。
debビルドシステムはソースを保全するために、パッチファイルやパッケージングのために必要な情報の全てをソースツリー直下のdebian/ディレクトリに配置する。同様にバージョン番号も区別し、例えば上流ソースのバージョンが1.2.1であれば、Debianへのポーティングの際にはそこにDebianでのパッチバージョンを追加して1.2.1-1の様になる。
このフォーマットにおけるソースパッケージの実体は以下の様になる。ここでPACKAGEはパッケージ名、VERSIONは上流ソースのバージョン、そしてDEBVERはDebianでのパッチバージョンとする。
- PACKAGE_VERSION.orig.tar.gz
オリジナルソースのアーカイブ - PACKAGE_VERSION-DEBVER.tar.xz
Debian変更部分。上述のdebian/ディレクトリが格納される - PACKAGE_VERSION-DEBVER.dsc
ソースパッケージのメタデータファイル・概要やチェックサムが記述される
(Debian)オリジナルのケース
最初からDebian(または他のディストロ)に向けて開発されており、上流とDebianで変更を区別する必要がないケース。この場合はquilt
は使われず、このフォーマットはnativeと呼ばれる。
このフォーマットにおけるソースパッケージの実体は以下の様になる。
- PACKAGE_VERSION.tar.xz
- PACKAGE_VERSION.dsc
Debianコミュニティからしてみればdebパッケージの作成動機はほとんどの場合OSSのポーティングであり、従って各種ツールのデフォルトやDebian文書もquiltフォーマットに合わせられている。しかし本文のターゲットである内部使用の場合、恐らく上流ソースと独自変更の区別は無いだろう。従って以降はnativeフォーマットを中心に話を進めていく。quilt
の使い方まで含めると話が複雑になるし、quiltフォーマットはDebian文書のカバー範囲だ。
ツール類
ツールが多く、また機能の置換やラッパーの関係が複雑だったので一端整理。本文で使うツールは太字で示す。
セットアップ
- dh_make
dhと付くがdebhelperではないらしい、紛らわしい。以前のデファクトスタンダード。 -
debmake
dh_makeの後継らしくDebian文書でプッシュされている
変更管理
- dquilt
所定の操作によりソースの変更をパッチファイル(debian/patches/*)に反映してくれる -
debchange(dch)
変更ログ(debian/changelog)の編集
ビルド
- dpkg-buildpackage
ソースパッケージからのビルド -
debuild
dpkg-buildpackage + lintian + α
パッケージングヘルパー
-
debhelper
基本的にはdebian/rulesで使うスクリプト群 - CDBS
debhelperの後継を目指したが置き換わらなかった? -
dh
複数のdebhelperを現在のターゲットを認識してまとめて呼び出すラッパー
※dh_make以前に更に別のdebmake(deb-make?)があったらしく、英語ですら外部サイトだと「dh_makeがあるのでdebmakeは非推奨だよ」と書かれていたりする。
その他
- devscripts
debパッケージングのための小規模なスクリプト群・debchangeやdebuildを含む -
lintian
debパッケージがDebianのポリシー沿っているかをチェックする
内部用なら必ずしも全て従う必要は無いが「らしさ」を確認するのに有用
インストール
本文で使うツール類は基本的に以下でインストール出来る。
$ sudo apt update
$ sudo apt install build-essential devscripts debmake
また、ツールの幾つかは共通して環境変数DEBEMAIL及びDEBFULLNAMEを参照する。従って次に様に~/.bashrc
に記述しておくといい。
DEBEMAIL=`liqsuq@example.com`
DEBFULLNAME="liqsuq"
export DEBEMAIL DEBFULLNAME
手順
概要
基本的なフローは時期やプロジェクトによって大きく異なるが現時点で1からパッケージングするなら次の様に行う模様。
- debmakeでセットアップ
- debianディレクトリを編集
- (dquiltで編集)
- debchangeでバージョンを切る
- debuildでビルド
- パッケージの確認(内容/インストール)
ビルドの際には裏でパッケージングヘルパーが動いてパッケージングに関する雑多な処理をある程度は自動で行ってくれる。
ワークスペースの構築
debパッケージングではソースツリーの親ディレクトリに成果物を出力するのでまずワークスペース(用語がなかったので独自定義)を作成する。
$ mkdir ws-deb
$ cd ws-deb
そしてソースのtarballを展開するなりコピーするなりしてソースツリーとなるディレクトリを作成する。この時ディレクトリ名はPACKAGE-VERSION/とする。
セットアップ
PACKAGE-VERSION/に移動しdebmake -n
を実行。するとdebian/ディレクトリが生成されるためこれを調整していく。
debianディレクトリを編集
debmakeをデフォルト(-x1)で実行すると以下の様なファイル構成になる。
$ tree debian/
debian/
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── rules
├── source
│ ├── format
│ └── local-options
└── watch
各ファイルの詳細は以下を参考にして欲しいが軽く触れておく。
- 第4章 debian/ ディレクトリー以下に無くてはならないファイル - Debian 新メンテナーガイド
- 第5章 debianディレクトリーにあるその他のファイル - Debian 新メンテナーガイド
必須ファイル
-
debian/chagelog
更新履歴を記録・パッケージのバージョンはここから参照される -
debian/control
ソース/バイナリパッケージのメタデータを記述 -
debian/rules
ビルドレシピ・中身はMakefile形式だがdhを介してdebhelperを呼ぶ -
debian/copyright
著作権表記ないしライセンスを統合して記述
準必須ファイル
本来はdebパッケージング必須ではなかったが、現在ではパッケージングヘルパーが参照しているためほぼ必須なファイル。とりあえずdebmake
の出力のまま置いておく。
- debian/source/format
ソースパッケージのフォーマットを定義・3.0 (native/quilt)
無くても良いファイル
- debian/compat
debhelper
の互換性を定義…なのだが現在はdebian/controlのBuild-Depandsに書くのが推奨らしいじゃあそっちをテンプレにしてくれよ - debian/README.Debian
パッケージングの際の通知事項を記述・無ければ削除 - debian/watch
Debianの上流ソース監視サービス等が使う・nativeの場合不要(lintianが警告する) - debian/source/local-options
DebianのVCSで管理する時に使うらしい
生成されないけど重要なファイル
- debian/conffiles
上書き確認する必要がある設定ファイル(/etc/以下除く)を記述 - debian/install
画像や設定ファイル等ビルドシステムによってインストールされないファイルを記述 - debian/PACKAGE.manpages
インストールするmanページを記述・「PACKAGE.」は省略可 - debian/{pre,post}{inst,rm}
{インストール,削除}{前,後}に実行されるスクリプト - debian/PACKAGE.symbols
symlinkを貼る必要のあるライブラリで記述・「PACKAGE.」は省略可
既に何らかの仕組みがあるのに{pre,post}{inst|,rm}ファイルにスクリプトを書くべきでは無いだろう。まずはdebian/以下のファイルで出来ることはないか調べてみよう。
バージョンを切る
debian/changelogは任意のエディタでも書けるがdebchange
というコマンドが用意されている。
ビルド
debuild
を実行してみる。dpkg-buildpackage
とlintian
が実行される。dpkg-buildpackage
がうまくいかなければdebian/rulesを中心に確認していく。lintian
がうまくいかなければまずlintian -i ../*.changes
を実行してポリシー違反の詳細を確認していく。
パッケージの確認
コンパイルを必要としないファイルを含む場合、debian/installに書かないと出力されたdebパッケージからファイルが漏れる。そうしたことが無い様に一度debパッケージを展開してみて漏れがないか確認した方が良い。dokg-deb -R debファイル 出力ディレクトリ
でdebパッケージを展開出来る。前述のdpkg-dev --build
で簡易的にパッケージを作成する場合と同じ構成をしている。
例
シェルスクリプト
「Hello!!」と出力するだけのシンプルなシェルスクリプトexampleをdebパッケージ化してみよう。
先述の通りワークスペースとソースツリーを作り、scripts/ディレクトリにexampleスクリプトを格納する。
~$ mkdir -p ws-sh/example-0.1/scripts
~$ cd ws-deb/example-0.1
~/ws-sh/example-0.1$ cat >example <<EOF
> #!/bin/bash
> echo "Hello
> EOF
~/ws-sh/example-0.1$ tree ..
..
└── example-0.1
└── scripts
└── example
2 directories, 1 file
そしてdebmake
を実行。シェルスクリプトである旨を-b
オプションで伝える。
~/ws-sh/example-0.1$ debmake -n -b "example:sh"
~/ws-sh/example-0.1$ tree ..
..
└── example-0.1
├── debian
│ ├── README.Debian
│ ├── changelog
│ ├── compat
│ ├── control
│ ├── copyright
│ ├── rules
│ ├── source
│ │ ├── format
│ │ └── local-options
│ └── watch
└── scripts
└── example
4 directories, 10 files
先述の通りdebian/compat、debian/README.Debian、debian/watch及びdebian/source/local-optionsは必要ないので削除する。
~/ws-sh/example-0.1$ rm debuan/compat debian/README.Debian debian/watch debian/source/local-options
まずはdebian/controlから。Sectionをとりあえずmiscとし、Homepage行を(無いので)削除し、Descriptionを適当に編集する。debian/compatを削除したのでBuild-Dependsも書き換える。
~/ws-sh/example-0.1$ vim debian/control
:
~/ws-sh/example-0.1$ cat debian/control
Source: example
Section: misc
Priority: optional
Maintainer: liqsuq <liqsuq@example.com>
Build-Depends: debhelper-compat (=11)
Standards-Version: 4.1.4
Package: example
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Description: completely example command
example command is completely example command.
This outputs "Hello" message.
This is not intended for anything other than use in the example.
今回の場合Make等のインストールを行う機構が無いのでdebian/installを作成する。exampleスクリプトは/usr/bin/以下にインストールする。
~/ws-sh/example-0.1$ cat >debian/install <<EOF
> scripts/example usr/bin
> EOF
debian/copyrightも編集する。今回はライセンス条文が短いという理由で軽率にMITライセンス(Expatライセンス)を使用する。
~/ws-sh/example-0.1$ vim debian/copyright
:
~/ws-sh/example-0.1$ cat debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: example
Files: *
Copyright: 2022 liqsuq <liqsuq@example.com>
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
概ね必要な編集は済んだのでdebchange
を使ってバージョンを切る。debmake
が生成したテンプレートを削る。
~/ws-sh/example-0.1$ debchange
:
~/ws-sh/example-0.1$ cat debian/changelog
example (0.1) UNRELEASED; urgency=low
* Initial release.
-- liqsuq <liqsuq@example.com> Fri, 29 Jul 2022 09:40:29 +0900
ここで一旦debuild
してみる。
~/ws-deb/example-0.1$ debuild
dpkg-buildpackage -us -uc -ui
dpkg-buildpackage: info: source package example
dpkg-buildpackage: info: source version 0.1
dpkg-buildpackage: info: source distribution UNRELEASED
dpkg-buildpackage: info: source changed by liqsuq <liqsuq@example.com>
:
Now running lintian example_0.1_amd64.changes ...
W: example: binary-without-manpage usr/bin/example
Finished running lintian.
lintian
の警告が1件出てきた。詳細メッセージを確認する。
~/ws-sh/example-0.1$ lintian -i ../example_0.1_amd64.changes
W: example: binary-without-manpage usr/bin/example
N:
N: Each binary in /usr/bin, /usr/sbin, /bin, /sbin or /usr/games should
N: have a manual page
N:
N: Note that though the man program has the capability to check for several
N: program names in the NAMES section, each of these programs should have
N: its own manual page (a symbolic link to the appropriate manual page is
N: sufficient) because other manual page viewers such as xman or tkman
N: don't support this.
N:
N: If the name of the man page differs from the binary by case, man may be
N: able to find it anyway; however, it is still best practice to make the
N: case of the man page match the case of the binary.
N:
N: If the man pages are provided by another package on which this package
N: depends, Lintian may not be able to determine that man pages are
N: available. In this case, after confirming that all binaries do have man
N: pages after this package and its dependencies are installed, please add
N: a Lintian override.
N:
N: Refer to Debian Policy Manual section 12.1 (Manual pages) for details.
N:
N: Severity: warning
N:
N: Check: documentation/man
N:
「実行ファイルなのにmanページないじゃん」とのお叱り。Debianポリシーでは実行ファイルにはmanページが存在することを義務付けている。無視しても良いがdebパッケージ「っぽく」なるので追加してみる。
man/example.1にroff形式で簡単なmanページファイルを作成する。※今回はnativeフォーマットなので直接ソースツリーにmanページファイルを書きますが、上流ソースにmanページが無いのでDebian修正としてmanページを作成するためにdebian/以下でmanページを作成する仕組みもある。
~/ws-sh/example-0.1$ mkdir man
~/ws-sh/example-0.1$ cat >man/example.1 <<EOF
> .TH EXAMPLE 1 "2022-07-28" rkgknet.org "Example Manual"
>
> .SH NAME
> example \- copletely example command
>
> .SH SYMPOSIS
> \fBexample\fR
>
> .SH DESCRIPTION
> \fBexample\fR is a completely example command.
> This outputs "Hello" message.
> This is not intended for anything other than use in the example.
>
> .SH AUTOR
> Written by liqsuq <liqsuq@example.com>
> EOF
debian/manpagesを作成し、man/example.1の存在を指示する。
~/ws-sh/example-0.1$ cat >debian/manpages <<EOF
> man/example.1
> EOF
debuild
してlintian
が警告しないことを確認する。
~/ws-sh/example-0.1$ debuild
dpkg-buildpackage -us -uc -ui
dpkg-buildpackage: info: source package example
dpkg-buildpackage: info: source version 0.1
dpkg-buildpackage: info: source distribution UNRELEASED
dpkg-buildpackage: info: source changed by liqsuq <liqsuq@example.com>
:
Now running lintian example_0.1_amd64.changes ...
Finished running lintian.
debパッケージを展開して意図したファイルが含まれている事を確認する。debian/changelogやdebian/copyright、manページはDebianが想定するディレクトリに格納される。
~/ws-sh/example-0.1$ cd ..
~/ws-sh$ dpkg-deb -R example_0.1_all.deb example-extracted
~/ws-sh$ tree example-extracted/
example-extracted/
├── DEBIAN
│ ├── control
│ └── md5sums
└── usr
├── bin
│ └── example
└── share
├── doc
│ └── example
│ ├── changelog.gz
│ └── copyright
└── man
└── man1
└── example.1.gz
8 directories, 6 files
システムにインストールしてみて動作を確認する。
~/ws-sh$ sudo apt install -y ./example_0.1_all.deb
:
~/ws-sh$ which example
/usr/bin/example
~/ws-sh$ example
Hello!!
最後に中間ファイルの削除を行ってからワークスペース全体を見てみよう。
~/ws-sh$ cd example-0.1/
~/ws-sh/example-0.1$ debuild -- clean
~/ws-sh/example-0.1$ cd ../
~/ws-sh$ rm -rf ../example-extracted/
~/ws-sh$ tree
.
├── example-0.1
│ ├── debian
│ │ ├── changelog
│ │ ├── control
│ │ ├── copyright
│ │ ├── install
│ │ ├── manpages
│ │ ├── rules
│ │ └── source
│ │ └── format
│ ├── man
│ │ └── example.1
│ └── scripts
│ └── example
├── example_0.1.dsc
├── example_0.1.tar.xz
├── example_0.1_all.deb
├── example_0.1_amd64.build
├── example_0.1_amd64.buildinfo
└── example_0.1_amd64.changes
5 directories, 16 files
ワークスペース直下にソースパッケージでもバイナリパッケージでも無いファイルが残っているので触れておく。
- example_0.1_amd64.build
ビルドログ - example_0.1_amd64.buildinfo
ビルド時の情報が記述される - example_0.1_amd64.changes
バイナリパッケージのメタデータファイル
シングルバイナリ(Makefile)
今度は「Hello!!」と出力するだけのC++コードexample.cppをdebパッケージ化してみよう。
まずワークスペースとソースツリーを作り、src/ディレクトリにexample.cppを格納する。
~$ mkdir -p ws-single/example-0.1/src
~$ cd ws-single/example-0.1
~/ws-single/example-0.1$ cat >example.cpp <<EOF
> #include <iostream>
> using namespace std;
> int main(int argc, char **argv) {
> cout << "Hello!!" << endl;
> }
> EOF
このコードをビルドするためにMakefileを作成する。ここでMakefileはGNUコーディング標準に準拠している必要があるらしい。とは言ってもパッケージングで重要なのは以下の1つだけの模様。
- インストール/アンインストールパスにDESTDIR変数を付加すること
distcleanやuninstallといったターゲットは無いとGNUコーディング標準に合わないが、debhelperは無いなら無いでよしなにやってくれる様だ。ただしmake
でビルド、make install
でインストールといった最低限の作法は必要。
~/ws-single/example-0.1$ vim Makefile
:
~/ws-single/example-0.1$ cat Makefile
.PHONY: all clean install
all: src/example
install: src/example
install -D src/example $(DESTDIR)/usr/bin/example
clean:
-rm -f src/example
debmake
を実行。-b
オプションでコンパイル言語によるバイナリコードパッケージであることを指示する(デフォルトなので省略可)。
~/ws-single/example-0.1$ debmake -n -b "example:bin"
~/ws-single/example-0.1$ tree ..
..
└── example-0.1
├── debian
│ ├── README.Debian
│ ├── changelog
│ ├── compat
│ ├── control
│ ├── copyright
│ ├── rules
│ ├── source
│ │ ├── format
│ │ └── local-options
│ └── watch
└── src
└── example.cpp
4 directories, 10 files
テンプレートファイルの編集はシェルスクリプト版と同様なのでdebian/conpat、debian/README.Debian、debian/watch及びdebian/source/local-optionsを削除してdebian/control、debian/copyright及びdebian/changelogを編集する。man/example.1とdebian/manpagesも作成する。ただし今回はmakeによってexampleバイナリが自動でインストールされるはずなのでdebian/installは不要。
~/ws-single/example-0.1$ rm debian/compat debian/README.Debian debian/watch debian/source/local-options
~/ws-single/example-0.1$ vim debian/control
:
~/ws-single/example-0.1$ cat debian/control
Source: example
Section: misc
Priority: optional
Maintainer: liqsuq <liqsuq@example.com>
Build-Depends: debhelper-compat (=11)
Standards-Version: 4.1.4
Package: example
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: completely example command
example command is completely example command.
This outputs "Hello" message.
This is not intended for anything other than use in the example.
~/ws-single/example-0.1$ vim debian/copyright
:
~/ws-single/example-0.1$ debchange
~/ws-single/example-0.1$ cat >man/example.1 <<EOF
: # 省略
~/ws-single/example-0.1$ echo "man/example.1" >debian/manpages
debmake
で-b "example:bin"
としてコンパイルが必要なことを通知したため、debian/controlのArchitectureセクションがallからanyに変わったことは認識しておく。ソースパッケージからビルドすることで"どれか"のアーキテクチャに対応するバイナリパッケージが作成されることを示唆している。Debianのリポジトリでは各アーキテクチャで自動でバイナリパッケージをビルドするそうだ。
次にdebuild
してみる。ここで一応debian/controlの#export DH_VERBOSE = 1
のコメントアウトを外し、dh
が詳細ログを出力する様にしておく。
$ debuild
dpkg-buildpackage -us -uc -ui
dpkg-buildpackage: info: source package example
dpkg-buildpackage: info: source version 0.1
dpkg-buildpackage: info: source distribution UNRELEASED
dpkg-buildpackage: info: source changed by liqsuq <liqsuq@example.com>
dpkg-source --before-build .
dpkg-buildpackage: info: host architecture amd64
fakeroot debian/rules clean
dh clean
dh_auto_clean
make -j8 clean
make[1]: ディレクトリ '/home/liqsuq/ws-single/example-0.1' に入ります
rm -f src/example
make[1]: ディレクトリ '/home/liqsuq/ws-single/example-0.1' から出ます
dh_clean
rm -f debian/debhelper-build-stamp
rm -rf debian/.debhelper/
rm -f -- debian/example.substvars debian/files
rm -fr -- debian/example/ debian/tmp/
find . \( \( \
\( -path .\*/.git -o -path .\*/.svn -o -path .\*/.bzr -o -path .\*/.hg -o -path .\*/CVS -o -path .\*/.pc -o -path .\*/_darcs \) -prune -o -type f -a \
\( -name '#*#' -o -name '.*~' -o -name '*~' -o -name DEADJOE \
-o -name '*.orig' -o -name '*.rej' -o -name '*.bak' \
-o -name '.*.orig' -o -name .*.rej -o -name '.SUMS' \
-o -name TAGS -o \( -path '*/.deps/*' -a -name '*.P' \) \
\) -exec rm -f {} + \) -o \
\( -type d -a -name autom4te.cache -prune -exec rm -rf {} + \) \)
dpkg-source -b .
dpkg-source: info: using source format '3.0 (native)'
dpkg-source: info: building example in example_0.1.tar.xz
dpkg-source: info: building example in example_0.1.dsc
debian/rules build
dh build
dh_update_autotools_config
dh_autoreconf
dh_auto_configure
dh_auto_build
make -j8 "INSTALL=install --strip-program=true"
make[1]: ディレクトリ '/home/liqsuq/ws-single/example-0.1' に入ります
g++ -g -O2 -fdebug-prefix-map=/home/liqsuq/ws-single/example-0.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro src/example.cpp -o src/example
make[1]: ディレクトリ '/home/liqsuq/ws-single/example-0.1' から出ます
dh_auto_test
create-stamp debian/debhelper-build-stamp
fakeroot debian/rules binary
dh binary
dh_testroot
dh_prep
rm -f -- debian/example.substvars
rm -fr -- debian/.debhelper/generated/example/ debian/example/ debian/tmp/
dh_auto_install
install -d /home/liqsuq/ws-single/example-0.1/debian/example
make -j8 install DESTDIR=/home/liqsuq/ws-single/example-0.1/debian/example AM_UPDATE_INFO_DIR=no "INSTALL=install --strip-program=true"
make[1]: ディレクトリ '/home/liqsuq/ws-single/example-0.1' に入ります
install -D src/example /home/liqsuq/ws-single/example-0.1/debian/example/usr/bin/example
make[1]: ディレクトリ '/home/liqsuq/ws-single/example-0.1' から出ます
dh_installdocs
install -d debian/example/usr/share/doc/example
install -d debian/.debhelper/generated/example
install -p -m0644 debian/copyright debian/example/usr/share/doc/example/copyright
dh_installchangelogs
install -p -m0644 debian/changelog debian/example/usr/share/doc/example/changelog
dh_installman
install -d debian/example/usr/share/man/man1/
install -p -m0644 ./man/example.1 debian/example/usr/share/man/man1/example.1
man-recode --to-code UTF-8 --suffix .dh-new debian/example/usr/share/man/man1/example.1
mv debian/example/usr/share/man/man1/example.1.dh-new debian/example/usr/share/man/man1/example.1
chmod 0644 -- debian/example/usr/share/man/man1/example.1
dh_perl
dh_link
dh_strip_nondeterminism
dh_compress
cd debian/example
chmod a-x usr/share/doc/example/changelog usr/share/man/man1/example.1
gzip -9nf usr/share/doc/example/changelog usr/share/man/man1/example.1
cd '/home/liqsuq/ws-single/example-0.1'
dh_fixperms
find debian/example -true -print0 2>/dev/null | xargs -0r chown --no-dereference 0:0
find debian/example ! -type l -a -true -a -true -print0 2>/dev/null | xargs -0r chmod go=rX,u+rw,a-s
find debian/example/usr/share/doc -type f -a -true -a ! -regex 'debian/example/usr/share/doc/[^/]*/examples/.*' -print0 2>/dev/null | xargs -0r chmod 0644
find debian/example/usr/share/doc -type d -a -true -a -true -print0 2>/dev/null | xargs -0r chmod 0755
find debian/example/usr/share/man -type f -a -true -a -true -print0 2>/dev/null | xargs -0r chmod 0644
find debian/example -type f \( -name '*.so.*' -o -name '*.so' -o -name '*.la' -o -name '*.a' -o -name '*.js' -o -name '*.css' -o -name '*.scss' -o -name '*.sass' -o -name '*.jpeg' -o -name '*.jpg' -o -name '*.png' -o -name '*.gif' -o -name '*.cmxs' -o -name '*.node' \) -a -true -a -true -print0 2>/dev/null | xargs -0r chmod 0644
find debian/example/usr/bin -type f -a -true -a -true -print0 2>/dev/null | xargs -0r chmod a+x
dh_missing
dh_strip
install -d debian/.debhelper/example/dbgsym-root/usr/lib/debug/.build-id/32
objcopy --only-keep-debug --compress-debug-sections debian/example/usr/bin/example debian/.debhelper/example/dbgsym-root/usr/lib/debug/.build-id/32/9c6502e560058ad8453db9b3da47e97ee0dbb0.debug
chmod 0644 -- debian/.debhelper/example/dbgsym-root/usr/lib/debug/.build-id/32/9c6502e560058ad8453db9b3da47e97ee0dbb0.debug
chown 0:0 -- debian/.debhelper/example/dbgsym-root/usr/lib/debug/.build-id/32/9c6502e560058ad8453db9b3da47e97ee0dbb0.debug
strip --remove-section=.comment --remove-section=.note debian/example/usr/bin/example
objcopy --add-gnu-debuglink debian/.debhelper/example/dbgsym-root/usr/lib/debug/.build-id/32/9c6502e560058ad8453db9b3da47e97ee0dbb0.debug debian/example/usr/bin/example
install -d debian/.debhelper/example/dbgsym-root/usr/share/doc
ln -s example debian/.debhelper/example/dbgsym-root/usr/share/doc/example-dbgsym
dh_makeshlibs
rm -f debian/example/DEBIAN/shlibs
dh_shlibdeps
install -d debian/example/DEBIAN
dpkg-shlibdeps -Tdebian/example.substvars debian/example/usr/bin/example
dh_installdeb
dh_gencontrol
echo misc:Depends= >> debian/example.substvars
echo misc:Pre-Depends= >> debian/example.substvars
install -d debian/.debhelper/example/dbgsym-root/DEBIAN
dpkg-gencontrol -pexample -ldebian/changelog -Tdebian/example.substvars -Pdebian/.debhelper/example/dbgsym-root -UPre-Depends -URecommends -USuggests -UEnhances -UProvides -UEssential -UConflicts -DPriority=optional -UHomepage -UImportant -UBuilt-Using -DAuto-Built-Package=debug-symbols -DPackage=example-dbgsym "-DDepends=example (= \${binary:Version})" "-DDescription=debug symbols for example" -DBuild-Ids=329c6502e560058ad8453db9b3da47e97ee0dbb0 -DSection=debug -DPackage-Type=ddeb -UMulti-Arch -UReplaces -UBreaks
chmod 0644 -- debian/.debhelper/example/dbgsym-root/DEBIAN/control
chown 0:0 -- debian/.debhelper/example/dbgsym-root/DEBIAN/control
dpkg-gencontrol -pexample -ldebian/changelog -Tdebian/example.substvars -Pdebian/example
chmod 0644 -- debian/example/DEBIAN/control
chown 0:0 -- debian/example/DEBIAN/control
dh_md5sums
cd debian/example >/dev/null && xargs -r0 md5sum | perl -pe 'if (s@^\\@@) { s/\\\\/\\/g; }' > DEBIAN/md5sums
chmod 0644 -- debian/example/DEBIAN/md5sums
chown 0:0 -- debian/example/DEBIAN/md5sums
cd debian/.debhelper/example/dbgsym-root >/dev/null && xargs -r0 md5sum | perl -pe 'if (s@^\\@@) { s/\\\\/\\/g; }' > DEBIAN/md5sums
chmod 0644 -- debian/.debhelper/example/dbgsym-root/DEBIAN/md5sums
chown 0:0 -- debian/.debhelper/example/dbgsym-root/DEBIAN/md5sums
dh_builddeb
dpkg-deb --build debian/example ..
dpkg-deb: building package 'example' in '../example_0.1_amd64.deb'.
install -d debian/.debhelper/scratch-space/build-example
dpkg-deb --build debian/.debhelper/example/dbgsym-root debian/.debhelper/scratch-space/build-example
dpkg-deb: building package 'example-dbgsym' in 'debian/.debhelper/scratch-space/build-example/example-dbgsym_0.1_amd64.deb'.
Renaming example-dbgsym_0.1_amd64.deb to example-dbgsym_0.1_amd64.ddeb
mv debian/.debhelper/scratch-space/build-example/example-dbgsym_0.1_amd64.deb ../example-dbgsym_0.1_amd64.ddeb
dpkg-genbuildinfo
dpkg-genchanges >../example_0.1_amd64.changes
dpkg-genchanges: info: including full source code in upload
dpkg-source --after-build .
dpkg-buildpackage: info: full upload; Debian-native package (full source is included)
Now running lintian example_0.1_amd64.changes ...
Finished running lintian.
ビルドもlintianも問題なく終了しているが、実に多くのことをやっている。
先述した様にdebuild
を実行するとdpkg-buildpackage
が実行され、dh clean
・dh build
・dh binary
等の各ターゲットがdebhelperスクリプト群(dh_*)を呼び出している。例えばdh_auto_cleanはソースのMakefileにdistcleanターゲットがあればdistclean、無ければcleanを実行する様だ。この様にソースのビルドシステムや設定に合わせてある程度はデフォルトで柔軟にビルド出来る様になっている。
今回の単純なソースではビルドが失敗しなかったがもし失敗する場合は、override_dh_*ターゲットを追加してdebhelperの挙動を変更する等、debian/rulesに対して変更を行っていく。
さて、ここでワークスペースを見てみる。
~/ws-single/example-0.1$ debuild -- clean
~/ws-single/example-0.1$ tree ..
..
├── example-0.1
│ ├── Makefile
│ ├── debian
│ │ ├── changelog
│ │ ├── control
│ │ ├── copyright
│ │ ├── manpages
│ │ ├── rules
│ │ └── source
│ │ └── format
│ ├── man
│ │ └── example.1
│ └── src
│ └── example.cpp
├── example-dbgsym_0.1_amd64.ddeb
├── example_0.1.dsc
├── example_0.1.tar.xz
├── example_0.1_amd64.build
├── example_0.1_amd64.buildinfo
├── example_0.1_amd64.changes
└── example_0.1_amd64.deb
5 directories, 17 files
example-dbgsym_0.1_amd64.ddebというファイルが生成されている。これは自動ビルドに組み込まれたデバッグシンボルパッケージだそうで、以前は*-dbgというパッケージ命名方針は共通なもののメンテナによってやったりやらなかったりした物と同じ立ち位置だ。Ubuntuでも存在するが滅多に使われないということで別リポジトリに隔離され、利用するにはソースパッケージよりもやや手間な手順が必要になる。
Debug Symbol Packages - Ubuntu Wiki
マルチバイナリ(CMake)
ここではバイナリ、共有ライブラリ、ヘッダファイルを擁するソースパッケージをexample、libexample、libexample-devという3つのバイナリパッケージに分けて作成する方法を例示する。
本題に入っていく前にシングルバイナリと異なる幾つかの注意点を列挙する。
- 一時インストール結果はdebian/PACKAGE/でなくdebian/tmp/に格納される
- どのパッケージに格納するかはdebian/PACKAGE.installで制御する必要がある
- 互換性のためにライブラリはlib*.so->lib*.so.0->lib*.so.0.1の様なsymlinkにする
- MultiArchサポートに伴いライブラリは/usr/lib/x86_64-linux-gnu/といったアーキテクチャ毎のパスに格納する
5.22. マルチアーキ - Debian メンテナー用ガイド
特に4項のMultiArchサポートが曲者で、ビルドシステムでアーキテクチャを検知してインストールパスを切り替える様な仕組みが必要。本来単独ではマルチアーキ/マルチOSの機構を持たないMakefileでこれに対応するには厄介なのでCMakeを使用していく。適切にCMakeを設定すれば3項も自動的にやってくれる。
Multiarch/Implementation - Debian Wiki
いつも通りワークスペースとソースツリーを作り、include/、lib/、man/及びsrc/ディレクトリを作成してソースファイルを配置していく。
~$ mkdir -p ws-multi/example-0.1/
~$ cd ws-multi/example-0.1
~/ws-multi/example-0.1$ mkdir include lib man src
~/ws-multi/example-0.1$ cat >include/example.h <<EOF
> #pragma once
> void example();
> EOF
~/ws-multi/example-0.1$ cat >lib/libexample.cpp <<EOF
> #include <iostream>
> #include <example.h>
> using namespace std;
> void example() {
> cout << "example() was called!!" << endl;
> }
> EOF
~/ws-multi/example-0.1$ cat >man/example.1 <<EOF
: # これまでと同じなので省略
> EOF
~/ws-multi/example-0.1$ cat >src/example.cpp <<EOF
> #include <iostream>
> #include <example.h>
> using namespace std;
> int main(int argc, char **argv) {
> cout << "Hello!!" << endl;
> example();
> }
> EOF
各ディレクトリにCMakeLists.txtを配置していく。ポイントはinclude(GNUInstallDirs)
をインクルードして事前定義された変数CMAKE_INSTALL_*
を使用することと、ライブラリに対してVERSION
及びSOVERSION
プロパティを与えること。SOVERSION
は通常はライブラリバージョンのメジャーバージョン。
install — CMake 3.24.0-rc5 Documentation
GNUInstallDirs — CMake 3.24.0-rc5 Documentation
それとlibexample.so.0.1ならライブラリターゲット名はexampleにすること。バイナリターゲット名と被るので以下を参考にした。
cmakeでライブラリ名と実行ファイル名を同じにする - Qiita
~/ws-multi/example-0.1$ cat >CMakeLists.txt <<EOF
> cmake_minimum_required(VERSION 3.16)
> project(example VERSION 0.1)
> include(GNUInstallDirs)
> add_subdirectory(lib)
> add_subdirectory(src)
> add_subdirectory(include)
> add_subdirectory(man)
> EOF
~/ws-multi/example-0.1$ cat >lib/CMakeLists.txt <<EOF
> add_library(example SHARED libexample.cpp)
> set_target_properties(example PROPERTIES VERSION ${PROJECT_VERSION})
> set_target_properties(example PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
> target_include_directories(example PUBLIC "${PROJECT_SOURCE_DIR}/include")
> install(TARGETS example)
> EOF
~/ws-multi/example-0.1$ cat >src/CMakeLists.txt <<EOF
> add_executable(example-bin example.cpp)
> set_target_properties(example-bin PROPERTIES OUTPUT_NAME example)
> target_link_libraries(example-bin example)
> install(TARGETS example-bin)
> EOF
~/ws-multi/example-0.1$ cat >include/CMakeLists.txt <<EOF
> install(FILES example.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
> EOF
~/ws-multi/example-0.1$ cat >man/CMakeLists.txt <<EOF
> install(FILES example.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
> EOF
~/ws-multi/example-0.1$ tree ..
..
└── example-0.1
├── CMakeLists.txt
├── include
│ ├── CMakeLists.txt
│ └── example.h
├── lib
│ ├── CMakeLists.txt
│ └── libexample.cpp
├── man
│ ├── CMakeLists.txt
│ └── example.1
└── src
├── CMakeLists.txt
└── example.cpp
5 directories, 10 files
debmake
する。ライブラリパッケージのパッケージ名の末尾にはメジャーバージョンを付けるのが慣習らしく、無いと上手くビルド出来なかったりした。
~/ws-multi/example-0.1$ debmake -n -b "example:bin,libexample0:lib,libexample-dev:dev"
:
~/ws-multi/example-0.1$ tree ..
..
├── CMakeLists.txt
├── debian
│ ├── README.Debian
│ ├── changelog
│ ├── clean
│ ├── compat
│ ├── control
│ ├── copyright
│ ├── example.doc-base
│ ├── example.docs
│ ├── example.examples
│ ├── example.info
│ ├── example.install
│ ├── example.links
│ ├── example.manpages
│ ├── example.postinst
│ ├── example.postrm
│ ├── example.preinst
│ ├── example.prerm
│ ├── libexample-dev.install
│ ├── libexample0.install
│ ├── libexample0.symbols
│ ├── rules
│ ├── source
│ │ ├── format
│ │ └── local-options
│ └── watch
├── include
│ ├── CMakeLists.txt
│ └── example.h
├── lib
│ ├── CMakeLists.txt
│ └── libexample.cpp
├── man
│ ├── CMakeLists.txt
│ └── example.1
└── src
├── CMakeLists.txt
└── example.cpp
6 directories, 33 files
どうもマルチバイナリだとより多くのテンプレートファイルが生成されるらしい(-x2
)。後で使うファイル以外は削除していく。今回はCMakeでmanページ含めてdebian/tmp/にインストールしているためdebian/manpages等は不要。その代わりにdebian/PACKAGE.installを使用していく。
~/ws-multi/example-0.1$ rm debian/README.Debian debian/clean debian/compat debian/example.doc-base debian/example.docs debian/example.examples debian/example.info debian/example.links debian/example.manpages debian/example.postinst debian/example.postrm debian/example.preinst debian/example.prerm debian/source/local-options debian/watch
~/ws-multi/example-0.1$ tree ..
..
└── example-0.1
├── CMakeLists.txt
├── debian
│ ├── changelog
│ ├── control
│ ├── copyright
│ ├── example.install
│ ├── libexample-dev.install
│ ├── libexample0.install
│ ├── libexample0.symbols
│ ├── rules
│ └── source
│ └── format
├── include
│ ├── CMakeLists.txt
│ └── example.h
├── lib
│ ├── CMakeLists.txt
│ └── libexample.cpp
├── man
│ ├── CMakeLists.txt
│ └── example.1
└── src
├── CMakeLists.txt
└── example.cpp
7 directories, 18 files
これまでと同様に基本的なdebianファイルを書き換える。
~/ws_multi/example-0.1$ vim debian/control
:
~/ws_multi/example-0.1$ cat debian/control
Source: example
Section: misc
Priority: optional
Maintainer: liqsuq <liqsuq@example.com>
Build-Depends: cmake, debhelper-compat (=11)
Standards-Version: 4.1.4
Package: example
Architecture: any
Multi-Arch: foreign
Depends: libexample0 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
Description: completely example command
example command is completely example command.
This outputs "Hello" message.
This is not intended for anything other than use in the example.
Package: libexample0
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: library package of example command
This package contains the shared library.
Package: libexample-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libexample0 (= ${binary:Version}), ${misc:Depends}
Description: developmant package of example command
This package contains the development files.
~/ws_multi/example-0.1$ vim debian/copyright
:
~/ws_multi/example-0.1$ debchange
:
PACKAGE.installを記述していく。何を記述すればいいか分からなければ一度debuild
してみて(多分失敗するが)、debian/tmp/の中身を選り分けていけばいいだろう。注意したいのはlibexample.so.0とlibexample.so.0.1はlibexample0パッケージの物だがlibexample.soはlibexample-devパッケージの物だということ。
debian/libexample0.symbolsはひとまずそのまま置いておく。
~/ws_multi/example-0.1$ cat >debian/example.install <<EOF
> usr/bin/*
> usr/share/man/*
> EOF
~/ws_multi/example-0.1$ cat >debian/libexample0.install <<EOF
> usr/lib/*/*.so.*
> EOF
~/ws_multi/example-0.1$ cat
> usr/include/*
> usr/lib/*/*.so
> EOF
debuild
を実行する。分かりづらいがlintian以外の部分で警告を吐いている。
~/ws_multi/example-0.1$ debuild
:
dpkg-gensymbols: warning: new libraries appeared in the symbols file: libexample.so.0
dpkg-gensymbols: warning: debian/libexample0/DEBIAN/symbols doesn't match completely debian/libexample0.symbols
--- debian/libexample0.symbols (libexample0_0.1_amd64)
+++ dpkg-gensymbols5H1eKZ 2022-08-03 17:34:06.747563164 +0900
@@ -0,0 +1,3 @@
+libexample.so.0 libexample0 #MINVER#
+ _Z7examplev@Base 0.1
+ _ZNKSt5ctypeIcE8do_widenEc@Base 0.1
dh_shlibdeps
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
:
この生成されたsymbolsファイルをdebian/libexample0.symbolsに使うそうだ。コピーしてもう一度debuild
。
A.2. debian/package.symbolsの管理 - Debian メンテナー用ガイド
~/ws_multi/example-0.1$ cp debian/libexample0/DEBIAN/symbols debian/libexample0.symbols
~/ws_multi/example-0.1$ debuild
:
警告を吐かなくなった。debuild -- clean
して全体を見ておこう。
~/ws_multi/example-0.1$ tree ..
..
├── example-0.1
│ ├── CMakeLists.txt
│ ├── debian
│ │ ├── changelog
│ │ ├── control
│ │ ├── copyright
│ │ ├── example.install
│ │ ├── libexample-dev.install
│ │ ├── libexample0.install
│ │ ├── libexample0.symbols
│ │ ├── rules
│ │ └── source
│ │ └── format
│ ├── include
│ │ ├── CMakeLists.txt
│ │ └── example.h
│ ├── lib
│ │ ├── CMakeLists.txt
│ │ └── libexample.cpp
│ ├── man
│ │ ├── CMakeLists.txt
│ │ └── example.1
│ └── src
│ ├── CMakeLists.txt
│ └── example.cpp
├── example-dbgsym_0.1_amd64.ddeb
├── example_0.1.dsc
├── example_0.1.tar.xz
├── example_0.1_amd64.build
├── example_0.1_amd64.buildinfo
├── example_0.1_amd64.changes
├── example_0.1_amd64.deb
├── libexample-dev_0.1_amd64.deb
├── libexample0-dbgsym_0.1_amd64.ddeb
└── libexample0_0.1_amd64.deb
その他の例
以下にはより多くのユースケースをカバーした例がある(quiltフォーマットだが)。
第8章その他の例 - Debian メンテナー用ガイド
Tips
debmakeの-bオプションタイプ一覧
書式は-b "package[:type],..."
でそもそもlibなりlib-devなり*-docなりのpackage引数からtypeは決定出来るのですが一応。
Type | Arch | Multi-Arch | Description |
---|---|---|---|
bin | any | foreign | (C/C++による)ELFバイナリコード |
lib | any | same | ライブラリ |
dev | any | same | 開発用ライブラリ(ヘッダや静的ライブラリ等) |
doc | all | foreign | ドキュメント |
data | all | foreign | データ(フォントや画像等) |
sh | all | foreign | シェルスクリプト |
perl | all | foreign | Perlスクリプト |
python3 | all | foreign | Python3スクリプト |
ruby | all | foreign | Rubyスクリプト |
nodejs | all | foreign | Node.jsスクリプト |
ライブラリファイル名の種類
ライブラリファイルは更新時の都合もあってか概ねこの形態になっている。
Name | Example | Package | Description |
---|---|---|---|
realname | lib*.so.0.1 | lib*0 | 共有ライブラリの実体 |
soname | lib*.so.0 | lib*0 | 互換性のためのrealnameへのsymlink |
linkername | lib*.so | lib*-dev | コンパイラが要求するsonameへのsymlink |
*.orig.tar.gzの挙動
プロジェクトディレクトリはpackage-version
の形で、アーカイブファイルはpackage_version.orig.tar.gz
の形で保存する。アーカイブファイルが異なる命名の場合、debmakeは正規の命名のsymlinkを作成する。
$ wget http://ftp.gnu.org/gnu/gnujump/gnujump-1.0.8.tar.gz
$ tar -xf gnujump-1.0.8.tar.gz
$ cd gnujump-1.0.8
$ debmake
:
$ ls -l ../
合計 2456
drwxr-xr-x 9 liqsuq liqsuq 4096 7月 27 10:17 gnujump-1.0.8
-rw-rw-r-- 1 liqsuq liqsuq 2508641 7月 25 2012 gnujump-1.0.8.tar.gz
lrwxrwxrwx 1 liqsuq liqsuq 20 7月 27 10:23 gnujump_1.0.8.orig.tar.gz -> gnujump-1.0.8.tar.gz
テンプレートファイル生成を制御する
debmake
は-x
オプションでテンプレートファイルの詳細さを指定出来る。デフォルトは多分1。0はDebianポリシーに従わずにdpkg-buildpackage
が通る最低限。3以降はテンプレートファイルが多すぎて使いづらいがパッケージ作り込みの当たりをつけるには便利かも。
例えばdebian/copyrightに使用するライセンスの例は-x4
オプションでdebian/license-examples/以下に生成される。
バイナリのインストール先について
debパッケージングの際のバイナリのインストール先は/usr/bin/
を推奨される。一方で一般的OSSでのインストール先は/usr/local/bin/
だ。以下には「/usr/bin/
はパッケージ管理されたバイナリを格納する」と書いてあり、セルフビルドのOSSからパッケージ管理システムに組み込む時の処理と言える。
debchange
Ubuntuでnativeフォーマットの場合、debchange
で変更ログを追加したらバージョンが「0.1」->「0.2」の様になってくれるのが期待だが、残念ながら自動でそうなってくれるオプションは存在しない模様。debchange -R
を実行すると「0.1build1」となるエントリが生成されるのでそれを「0.2」に直すのが妥当か。
help2man
manページに使われているroff形式は最早昨今では書くのが手間過ぎるのでhelp2manなり他のビルドツールに頼った方が良い。一応、手で書く人のためにroff形式で書いたファイルを整形して表示するためのコマンドを残しておく。
$ cat test.1 | groff -Tutf8 -mandoc -mja | less -s
まとめ
以上のようにソースパッケージからのパッケージングはdpkg-dev --build
を使った方法よりもツール群をフルに活用出来る。また、ツール群はdebian/以下にファイルを集約することで開発領域を分離し、ソースの変更がしやすい作りになってる。
参考
- Debianパッケージ構築のメモ - walf443's blog
- Debian 開発者向けマニュアル
- Debian メンテナー用ガイド
- Debian 新メンテナーガイド
- Debian パッケージングチュートリアル
※文書中にも書かれているが、新メンテナーガイドよりもメンテナー用ガイドの方が新しいことに注意。