Ubuntu Weekly Recipe

第487回 ARM向けバックポートパッケージをsbuildでビルドする

この記事を読むのに必要な時間:およそ 10 分

既存のパッケージをそのままバックポートする

パッケージをバックポートしたい場合は,一般的に以下のステップを経ます。

  1. バックポート元のリリースからソースパッケージを取得する
  2. 必要に応じてパッケージの中身を修正する
  3. debian/changelogにバックポートする旨のエントリを追加する
  4. debian/changelogのバージョンをバックポートに即した値にする
  5. ソースパッケージを再構築する
  6. ソースパッケージをビルド・テストする
  7. ソースパッケージをビルドサーバーにアップロードする

このうち「バージョンをバックポートに即した値にする」部分ですが,これは将来的なアップグレードを見越して値を決める必要があります。

たとえばUbuntu 16.04 LTSでv1.0,17.10でv2.0なパッケージがあったとします。v2.0のパッケージを16.04にバックポートする際にバージョンをv2.0に設定しそれをインストールしてしまうと,将来17.10にアップグレードする際に,16.04と17.10の同名のパッケージが同じバージョンになってしまいます。その結果として,そのパッケージは更新されません。

バージョンが大きくなっているので更新される:
  v2.0(16.04用) > v1.0(16.04用)

バージョンが同じなので更新されない:
  v2.0(17.10用) = v2.0(16.04用)

つまり16.04でビルドされたパッケージがそのまま17.10で使われてしまうのです。しかしながら16.04と17.10の間で関連するライブラリなどが変更されている場合,本来であればこのパッケージも更新されないといけません。そこでバックポートのパッケージにバージョンを付ける場合は,⁠バックポート先のパッケージより新しいけれども,バックポート元のパッケージよりは古いと判定されるバージョン」を付ける必要があるのです。

もしバックポート対象のソースパッケージをそのままバックポートできるのであれば,backportpackageコマンドを使うのが便利です。上記の2.と6.や7.以外の作業はすべて自動的に行ってくれます。さらに6.や7.についてもオプションで対応可能です。たとえばtmuxパッケージはUbuntu 16.04 LTSだと2.1ですが,開発中の17.10だと2.5になっています。これをそのままバックポートしてみましょう。

$ mkdir -p ~/backport/tmux && cd $_
$ backportpackage -s artful -d xenial -w . tmux
backportpackage: Downloading tmux_2.5.orig.tar.gz from archive.ubuntu.com (0.454 MiB)
backportpackage: Downloading tmux_2.5-3build1.debian.tar.xz from archive.ubuntu.com (0.012 MiB)
dpkg-source: info: extracting tmux in tmux-xenial
(中略)
dpkg-buildpackage: source package tmux
dpkg-buildpackage: source version 2.5-3build1~ubuntu16.04.1
dpkg-buildpackage: source distribution xenial-backports
(中略)
次のユーザの秘密鍵のロックを解除するには
パスフレーズがいります:"Mitsuya Shibata <shibata@example.com>"
(中略)
Successfully signed dsc and changes files

これだけです。-s artfulが取得元のリリース名(artfulは17.10のリリース名)であり,-d xenialがバックポート先のリリース名です。-w .で作業ディレクトリを指定し,最後にパッケージ名を指定します。

実行ログを眺めると,ソースパッケージを取得し,changelogエントリを追加し,バージョンを設定し,ソースパッケージを再構築してくれていることがわかります。ソースパッケージを公式のビルドサーバーにアップロードする際は,⁠その人が作った」ことを確実に保証するためにGPG鍵で署名を行う必要があります。dscファイルとchangesファイルにそれぞれ署名しますので,gpg-agentを使っていない環境であれば2回パスフレーズの入力が必要です。

実際には以下のようなファイルが生成されます。

$ ls
tmux_2.5-3build1.debian.tar.xz
  => artfulのパッケージデータ
tmux_2.5-3build1.dsc
  => artfulのソースパッケージ情報ファイル
tmux_2.5-3build1~ubuntu16.04.1.debian.tar.xz
  => xenialにバックポートしたパッケージデータ
tmux_2.5-3build1~ubuntu16.04.1.dsc
  => xenialにバックポートしたソースパッケージ情報ファイル
tmux_2.5-3build1~ubuntu16.04.1_source.build
  => ソースパッケージの構築ログ
tmux_2.5-3build1~ubuntu16.04.1_source.changes
  => ソースパッケージの変更情報
tmux_2.5.orig.tar.gz
  => tmuxオリジナルのソースコードアーカイブ

Debianパッケージのソースパッケージは,パッケージの情報を記載したdscファイルと,オリジナルのソースコードであるorig.tar.gz,さらにはオリジナルからの変更点やパッケージビルドに必要なスクリプトなどを格納したdebain.tar.xzファイルから構成されます。changesファイルは新しいソースパッケージ一式のリストを記載したファイルです。

dscファイルのファイル名から,artfuのバージョンは2.5-3build1だったことがわかります。さらに今回作ったバックポートパッケージは2.5-3build1~ubuntu16.04.1になっています。この~がポイントです。Debianパッケージのバージョンルールでは~は特殊な扱いとなっており,2.5-3build1より古いバージョン」という意味を持たせたかったら,2.5-3build1~FOOのような付け方ができるのです。

さらにbackportpackageはUbuntu 16.04 LTS向けの最初のバックポートということで,ubuntu16.04.1というバージョンを後置しています。このバックポートパッケージを大元のバージョンを変えずに更新する場合は,ubuntu16.04.2ubuntu16.04.3と変更していくというわけです。

バージョンの関係:
  2.5-3build1 > 2.5-3build1~ubuntu16.04.2 > 2.5-3build1-ubuntu16.04.1 > 2.5-3build0

作られたソースパッケージを展開してみましょう。ソースパッケージはdpkg-source -xで展開できます。

$ dpkg-source -x tmux_2.5-3build1~ubuntu16.04.1.dsc
$ head tmux-2.5/debian/changelog
tmux (2.5-3build1~ubuntu16.04.1) xenial-backports; urgency=medium

  * No-change backport to xenial

 -- Mitsuya Shibata <shibata@example.com>  Fri, 01 Sep 2017 23:03:28 +0900

tmux (2.5-3build1) artful; urgency=medium

  * No-change rebuild against libevent-2.1-6

きちんと新しいchangelogエントリが追加されていることがわかりますね。これでソースパッケージの作成は完了です。もしソースパッケージの内容も変更したいのであれば,展開したあとに適切な対応を行った上で,dpkg-buildpackageコマンドなどでソースパッケージを生成することになります。変更対象や変更内容によっては,git-buildpackageのようなbackportpackage以外のパッケージングツールとも組み合わせたほうがいいかもしれません。このあたりの話はまた別の機会に。

ちなみにリポジトリからバイナリパッケージをダウンロード・展開したい場合はapt download PACKAGE && dpkg-deb -x PACKAGE_VERSOION.deb DIRECTORYを実行します。単にパッケージの中のファイルのリストを取得したければless PACKAGE_VERSION.debでもかまいません。lesspipeが適切に展開してくれます。

パッケージをビルドする

さてソースパッケージも無事に作られたので,これをビルドしてバイナリパッケージとしましょう。先ほど構築したsbuildの環境を使います。といっても,コマンドをひとつ実行するだけです。

$ sbuild -A --arch=armhf --dist=xenial tmux_*ubuntu16*.dsc
sbuild (Debian sbuild) 0.67.0 (26 Dec 2015) on ubuntu-desktop

+==============================================================================+
Wide character in print at /usr/share/perl5/Sbuild/Base.pm line 90.
| tmux 2.5-3build1~ubuntu16.04.1 (armhf)                     01  9月 2017 23:45 |
+==============================================================================+

Package: tmux
Version: 2.5-3build1~ubuntu16.04.1
Source Version: 2.5-3build1~ubuntu16.04.1
Distribution: xenial-armhf
Machine Architecture: amd64
Host Architecture: armhf
Build Architecture: armhf
(中略)
Build Architecture: armhf
Build-Space: 11816
Build-Time: 374
Distribution: xenial-armhf
Host Architecture: armhf
Install-Time: 91
Job: tmux_2.5-3build1~ubuntu16.04.1.dsc
Machine Architecture: amd64
Package: tmux
Package-Time: 680
Source-Version: 2.5-3build1~ubuntu16.04.1
Space: 11816
Status: successful
Version: 2.5-3build1~ubuntu16.04.1
--------------------------------------------------------------------------------
Finished at 20170901-2356
Build needed 00:11:20, 11816k disc space

とっても簡単ですね。-Aを指定すると設定ファイルなどのアーキテクチャーに依存しないファイルだけが含まれたパッケージも一緒にビルドします。--arch--distは構築時と同じようにアーキテクチャーとリリース名です。最後にビルドするパッケージのdscファイルを渡します。

amd64マシンでarmhf用のパッケージを構築する場合,qemu-user-staticを使うためにビルド時間はそれなりにかかります。ビルドに成功すれば,次のようなファイルがカレントディレクトリに追加されるはずです※5)⁠

※5
ビルド環境や対象パケッケージによってはデバッグシンボルパッケージ.ddebファイル)も自動生成されるかもしれません。
tmux_2.5-3build1~ubuntu16.04.1_armhf-20170828-1445.build
  => ビルドログ
tmux_2.5-3build1~ubuntu16.04.1_armhf.build
  => 上記ファイルへのシンボリックリンク
tmux_2.5-3build1~ubuntu16.04.1_armhf.changes
  => バイナリパッケージの変更情報
tmux_2.5-3build1~ubuntu16.04.1_armhf.deb
  => バイナリパッケージ

ビルドエラーが発生した場合は,.buildのログを随時確認することになります。

本来必要なのは.debファイルなのですが,⁠リポジトリにアップロードする」のであれば.changesファイルを指定することになるでしょう。.changesファイルには作成したバイナリパッケージの情報と.debファイルのハッシュが記載されています。ソースパッケージと同様に,.changesに作成者のGPG鍵で署名することで,バイナリパッケージ一式の正当性を担保するわけです※6)⁠

※6
UbuntuやDebianの一般的な開発フローにおいて,⁠バイナリパッケージをどこかにアップロードする」ことは原則としてありません。基本的に開発者はソースパッケージ一式を提供しするだけです。その後,適切な権限を持った人がビルドサーバーに配置し,ビルドサーバーがビルドしたバイナリパッケージが自動的・半自動的にリポジトリに配置されることになります。

このようにすでに存在するパッケージをビルドするだけなら,とてもかんたんです。もちろん「きちんと動く」ようにするまでにはトライアンドエラーを繰り返すことになるのですが,バックポートパッケージであればより新しいリリースでは動作した実績があるパッケージですので,新規に作るよりは手間は少ないでしょう。

また第311回でも言及しているように,作成したソースパッケージやバイナリパッケージに対してlintianやpiuparts,autopkgtestを用いたパッケージのテストを行っておくと,パッケージ品質を保証できますし,余計なトラブルを防止できます。こちらも合わせて使い方を覚えておくと良いでしょう。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。

コメント

コメントの記入