Chapter 11. パッケージコンポーネント - ファイル、ディレクトリー、およびコンテンツ

Table of Contents

11.1. Makefile
11.2. distinfo
11.3. patches/*
11.3.1. 個々のパッチファイルの構造
11.3.2. パッチファイルを作成する
11.3.3. パッチファイルの出どころ
11.3.4. パッチ作成の指針
11.3.5. 作者へのフィードバック
11.4. その他の必須のファイル
11.5. オプションのファイル
11.5.1. バイナリーパッケージに影響をおよぼすファイル
11.5.2. 構築の過程に影響をおよぼすファイル
11.5.3. 何の影響もおよぼさないファイル
11.6. work*
11.7. files/*

パッケージを用意する際にはいつも、以下のセクションで述べられている多くのファ イルが存在します。

11.1. Makefile

構築、インストールおよびバイナリーパッケージの作成は、すべてパッケージの Makefileによりコントロールされます。 Makefile には、パッケージに関するさまざまな情報が記述されています。 たとえば、パッケージをどこで取得するか、 パッケージをどのように構成、構築、インストールするか、などです。

パッケージの Makefile は、 当該パッケージについて記述した、複数の節からなっています。

最初の節には、以下に掲げる変数を書きます。 これらは以下に掲げたままの順で並べるようにします。 このような変数の順序や節へのまとめ方は、ほとんど歴史的なものであって、 それ以上の意味はありません。

  • DISTNAME は、当該パッケージの web サイトからダウンロードされる配布ファイルの 基礎となる名前です。

  • PKGNAME は、 pkgsrc が使うパッケージ名です。これは、 DISTNAME (標準での値) が pkgsrc におけるパッケージ名としてふさわしくない場合のみ書く必要があります。 通常、これはディレクトリー名とバージョン番号を合わせたものになります。 この値は正規表現 ^[A-Za-z0-9][A-Za-z0-9-_.+]*$ にマッチする必要があります。すなわち、使える文字は、 アルファベット・数字・マイナス記号・下線・ピリオド・プラス記号だけであり、 また、最初の文字はアルファベットまたは数字である必要があります。

  • SVR4_PKGNAME は、 PKGNAME が SVR4 のシステムにおいて一意なものにならない場合に、 パッケージファイルを作成する際に使う名前です。標準では PKGNAME であり、これの短縮は pkgtools/gensolpkg を使っておこなうことができます。 SVR4_PKGNAME を使うのは、SVR4 のシステムで PKGNAME から一意なパッケージ名が得られない場合だけです。 SVR4_PKGNAME の長さの上限は 5 文字です。

  • CATEGORIES は、 当該パッケージにふさわしいカテゴリーのリストです。 pkgsrc の最上層にあるディレクトリーから自由に選ぶことができます。

    現在CATEGORIESの値として以下が使用できます。もし複数にまたがる場合、それら の値はスペースで分けられる必要があります:

    archivers     cross         geography     meta-pkgs     security
    audio         databases     graphics      misc          shells
    benchmarks    devel         ham           multimedia    sysutils
    biology       editors       inputmethod   net           textproc
    cad           emulators     lang          news          time
    chat          finance       mail          parallel      wm
    comms         fonts         math          pkgtools      www
    converters    games         mbone         print         x11
    
  • MASTER_SITES, DYNAMIC_MASTER_SITES, DIST_SUBDIR, EXTRACT_SUFX, DISTFILES の各変数については、 Section 17.5, “fetch 相”で詳しく論じます。

二つ目の節には、別途ダウンロードするパッチがある場合に、 そのパッチに関する情報を書きます。

  • PATCHFILES: 配布されているパッチを含んでいる、追加ファイルのファイル名です。 標準の値はありません。pkgsrc はこのファイルを PATCH_SITES から探します。 ファイル名の末尾が .gz または .Z の場合は、 パッチ適用前に自動的に伸長されます。

  • PATCH_SITES: 配布されているパッチファイル (上述の PATCHFILES を参照) がローカルにない場合用の、主な配布場所です。

三つ目の節には、以下に掲げる変数を書きます。

  • MAINTAINER は、 当該パッケージの担当者であることを自覚しており、 send-pr(1) を使って報告された問題や質問の面倒をもっともよく見そうな人の電子メールアドレスです。 他の開発者がパッケージに変更を加える際には、 事前に MAINTAINER に連絡してもかまいませんが、必ずしも連絡する必要はありません。 新しいプログラムをパッケージ化する場合は、 MAINTAINER をあなた自身に設定してください。 そのパッケージを将来の更新に応じて保守することがどうしてもできない場合は、 に設定します。

  • OWNER は、 他の開発者に無断でパッケージを更新されたり変更されたりしたくない場合に、 MAINTAINER のかわりに使うものです。 パッケージの Makefile には、 MAINTAINER または OWNER のいずれか一方を含めるようにしますが、 両方書いてはいけません。

  • HOMEPAGE は、当該パッケージについて、 利用者がより詳しい情報を得られる URL です。

  • COMMENT は、 当該パッケージについての一行説明です (パッケージ名は含めません)。

このほか、構築に影響のある変数としては、以下のものがあります。

  • WRKSRC: 当該パッケージに関連する配布ファイルが置かれるディレクトリーです。 標準では ${WRKDIR}/${DISTNAME} になり、 ほとんどのパッケージはこの標準状態のままで動作します。

    パッケージが専用のサブディレクトリー (たとえば、ほとんどのGNUソフトウェアはこれを作ります) を作らずに、 カレントディレクトリーに展開される場合、 WRKSRC=${WRKDIR} を設定します。

    パッケージが DISTNAME と同名のサブディレクトリーは作らずに、 別の名前のサブディレクトリーを作る場合は、 WRKSRC を設定して、 ${WRKDIR} 内の適切な名前を指すようにします。 たとえば WRKSRC=${WRKDIR}/${DISTNAME}/unix のようにします。 さらに別の例としては lang/tclx11/tk を見てください。

    pkgsrc が作成する作業用ディレクトリーの名前には、 WRKDIR_BASENAME 変数が使われます。この値は、標準では work です。同じ pkgsrc ツリーを複数の異なる種類のバイナリーパッケージの構築用に使いたい場合は、 必要に応じて、この変数の値を変えることができます。 WRKDIR_BASENAME の設定をありがちな方法でおこなうために、 二つの変数をそれぞれ使うことができます。 mk.confOBJHOSTNAME が定義されると、 ホスト名の最初の部分がディレクトリー名に付け加えられます。 OBJMACHINE が定義されると、 work.i386work.sparc のように、プラットフォーム名が付け加えられます。

以下の事柄に気を配ってください。

  • もしパッケージによりマニュアルページが圧縮され た形式でインストールされる場合、MANCOMPRESSEDを追加してください。 パッケージが BSD 形式の makefile を使っており、MANZ の設定に従う場合には、 MANCOMPRESSED_IF_MANZ を使います。

  • すべてのファイルの/usr/local${PREFIX}に変更してください。(後述のパッチ を参照)

  • もし、パッケージがinfoファイルをインストールするのであれば、Section 19.6.7, “infoファイルをインストールするパッケージ”を参照してください。

11.2. distinfo

distinfo ファイルには、パッケージが必要とする各 distfile のメッセージダイジェストあるいはチェックサムが格納されます。 作者が配布した元のファイルに対して、 このメッセージダイジェストが一致することを確認しています。これをもとに、イ ンターネットから取得したdistfileが転送中にファイルが壊れたり、悪意によりセ キュリティーホールを入れられたファイルに変更されていたりしていないことを確 認します。 最近、ダイジェストアルゴリズムの弱さについての噂があるため、 すべての distfile は、ファイルサイズに加えて、 SHA1 と RMD160 の両方のメッセージダイジェストを使って守られています。

patches ディレクトリーに入っているすべてのパッチ (Section 11.3, “patches/*”参照) のチェックサムも、 この distinfoファイルに格納されます。

distinfo ファイルを作り直すには、 make makedistinfo または make mdi コマンドを使います。

パッケージのなかには、プラットフォームによってdistfileの組が異なるものがありま す(たとえば lang/openjdk7)。この情報は単一のdistinfoファイルに 書かれるので、このようなパッケージの更新時には、distfileの情報が失われない ように注意を払ってください。

11.3. patches/*

多くのパッケージは、pkgsrc で対応している各種プラットフォーム上で、 まだ無修正では動きません。このため、そのようなパッケージを動くようにするために、 多数の独自のパッチファイルが必要です。このパッチファイルは、 patches/ ディレクトリーにあります。

patch 相では、WRKSRC 以下にファイルが展開された後に、展開されたファイルに対して、 このパッチファイルがアルファベット 順で適用されます。

11.3.1. 個々のパッチファイルの構造

問題を避けるため、patch-*ファイルは diff -buフォーマットとし、かつ、曖昧 さなしで適用できるようにします。(曖昧さがあっても強制的にパッチを適用させる ため、PATCH_FUZZ_FACTOR=-F2を設定することができます)。 さらに、各パッチファイルは一つのファイルに対する修正だけを含むようにし、 また、一つのファイルを複数のパッチファイルによって修正するようなことはしないようにします。 こうすることで、将来の変更が簡単になります。

各パッチファイルは、以下のような構造となっています: 最初の行には パッチそのものの RCS Id があります。2 行目は、見栄えをよくするため、 空にします。これより後には、そのパッチによる各変更についてのコメントを書きます。 これには標準的な事例がいくつもあります。

  • 一般に知られている脆弱性に対するパッチには、 その脆弱性の ID (CAN, CVE) を記すようにします。

  • ソースコードを変更するパッチには、 そのパッチを必要とするプラットフォームやその他の環境 (たとえばコンパイラー) を記すようにします。

あらゆる事例において、 そのアプリケーションのコードを理解している開発者がパッチを利用できるようにするため、 パッチにはコメントを書くようにします。上流の開発者に対しては特に注意が必要です。 たいていの場合、私たちの将来の作業を減らすために、 上流の開発者にパッチを採用してもらいたいからです。

11.3.2. パッチファイルを作成する

一つ重要なこととして、NetBSD CVSツリーにチェックインした後に問題を引き起こ すので、パッチファイルにRCS IDを含ませないように注意してください。 この問題を避けるため、 pkgtools/pkgdiff パッケージの pkgdiff コマンドを使ってください。

さらに自動化するため、同パッケージのmkpatchesを使ってパッチ一式を作ることを おすすめします。あなたがやらねばならないことは、ファイルの編集前に cp -p filename filename.origのようにするか、あるいはさらに簡単に、同パッケージの pkgviを使って、元のファイルをfilename.origの名前でバックアップしておくだ けです。この方法でパッケージをアップグレードした場合、patchdiffを使って、新 しいパッチと既存のパッチを簡単に比較することができます。 patches 以下のファイルは新しいファイルに置き換えられますので、 変更点が適切かどうかをしっかり確認してください。

パッケージを作り終えたとき、忘れずにmake makepatchsumコマンドでパッチファ イルのチェックサムを生成するようにしてください。Section 11.2, “distinfoを参照してくだ さい。

(たとえば、マニュアルページのインストール先を pkgsrc の流儀に合わせて変えるといったものではなく) distfile の問題を正すパッチを追加した場合は、 そのパッチをバグ報告としてメンテナーに送ってください。 こうすることで、pkgsrc を使っていない利用者も幸せになれますし、 通常は、将来のバージョンでパッチを削除することができるようになります。

パッチファイルのファイル名は、通常は patch-path_to_file__with__underscores.c という形式です。 多くのパッケージでは、以前使われていた patch-[a-z][a-z] という形式をまだ使っていますが、 パッチを新たに作る場合は、ファイル名を含んだ形式にしてください。pkgtools/pkgdiff に含まれている mkpatches は、 パッチファイルのファイル名を自動で処理します。

11.3.3. パッチファイルの出どころ

pkgsrc の複数のパッケージが同じ distfile を使っているなどの理由で、 複数のパッケージの間でパッチを共有したい場合は、 PATCHDIR をパッチファイルのある場所へのパスに設定します。 たとえば以下のようにします。

PATCHDIR= ${.CURDIR}/../xemacs/patches

作者その他のメンテナーが配布しているパッチファイルは、 PATCHFILES に列挙することができます。

置いておきたいパッチがあるがpkgsrcにcommitすべきものではない場合、それを pkgsrcツリーの外の $LOCALPATCHES ディレクトリーに置いておくことができます。こ のディレクトリーツリーはpkgsrcと同様の category/packageの構造を持つように し、パッチを各パッケージのディレクトリー(すなわち$LOCALPATCHES/$PKGPATH)に 置くようになっています。たとえば、 pkgsrc/graphics/pngに私的なパッチを適用す るようにしたい場合は、そのパッチを $LOCALPATCHES/graphics/png/mypatchに置き ます。このディレクトリーにあるファイルはすべてパッチファイルとして扱われ、 pkgsrcのパッチが適用された後に、このパッチが適用されます

11.3.4. パッチ作成の指針

コードの移植性に関する問題を修正する場合は、 プリプロセッサーの細工を使ってオペレーティングシステムやプラットフォームを判別するようなことはしてはいけません。 そのような方法では、各 OS 固有性の詳細が適切に抽象化できないため、 他のオペレーティングシステムに対する移植性を損なってしまいます。

一般的な決めごとは、 アプリケーションを構築しているオペレーティングシステムそのものを検査するのではなく、 必要としている特有の機能を検査する、というものです。 たとえば、kqueue は NetBSD において利用可能であると仮定して __NetBSD__ マクロを kqueue 対応の条件として使う、 ということはせずに、kqueue 自体を検出するようにするのです。 そしてこれは、一般的には configure スクリプトにパッチを適用することになります。 ある OS が他の OS (たとえば kqueue を実装した Linux) のインターフェースを採用してはいけない理由はまったくありませんが、 前述のようにオペレーティングシステムそのものを検査してしまうと、 そのような状況に対応することができません。

もちろん、機能を検査することは、 一般的に、開発者側の負担が多くなります。しかし、 機能を検査するようにすれば、その結果はきれいな変更となり、 他の多くのプラットフォームで動作させられる可能性があります。 また、本家のソースに統合される可能性が高くなることはいうまでもありません。 正しくない限り動かないの哲学を忘れないでください。

典型的な例としては、以下のようなものがあります。

Table 11.1. パッチ適用例

場所
configure スクリプト
case ${target_os} in
netbsd*) have_kvm=yes ;;
*)       have_kvm=no  ;;
esac
AC_CHECK_LIB(kvm, kvm_open, have_kvm=yes, have_kvm=no)
C ソースファイル
#if defined(__NetBSD__)
#  include <sys/event.h>
#endif
#if defined(HAVE_SYS_EVENT_H)
#  include <sys/event.h>
#endif
C ソースファイル
int
monitor_file(...)
{
#if defined(__NetBSD__)
        int fd = kqueue();
        ...
#else
        ...
#endif
}
int
monitor_file(...)
{
#if defined(HAVE_KQUEUE)
        int fd = kqueue();
        ...
#else
	...
#endif
}

さらなる情報は、Making packager-friendly software の記事 (第 1 部第 2 部) をお読みください。この記事では、ソフトウェアをパッケージ化しやすくする方法について、 複数の点での詳細をまとめています。ここで述べられている提案は、いずれも、 私たちが pkgsrc の作業をした経験から集められたものですので、 パッチの作成に際しても役に立つかもしれません。

11.3.5. 作者へのフィードバック

常に、常に、常に、 パッケージに施したあらゆる移植性に関する修正や改良点を、 本家の開発者に還元するようにしてください。 彼らに移植性についての注意を喚起して、将来のバージョンが無修正で NetBSD で構築できるようにするためには、そうするしかないのです。 また、将来のバージョンの配布ファイルの利用者は、 フィードバックされた修正をパッケージのコードから直接利用することができるようになります。

フィードバックをする方法は、一般的には、 パッチをきれいに書き直し (pkgsrc で追加されたパッチは、 時にはクイックハックであることがあるからです)、 フィードバック先のプロジェクト用の適切な追跡システムに対してバグ報告をし、 変更が受け入れられるよう本家の作者とともに作業する、というものです。 フィードバックをすることで、pkgsrc のパッケージを単純なものとし、 さほど労力を割かずに将来の変更ができるようにするということが、 特に重要です。

フィードバックをしたら、上流のバグレポートの URL を パッチのコメントに追加してください。

フリーソフトウェアの理念をサポートして下さい。

11.4. その他の必須のファイル

DESCR

ソフトウェアについての複数行の説明。このファイルには適切なクレジットを含 めておいてください。他人があなたのユーモアのセンス(あるいは変わった綴り) を理解してくれない事、そしてここに書かれたものすべてを他人が読むであろう という事を念頭においておいてください。

PLIST

このファイルは、システムにインストールされるファイルを管理します:すべて のバイナリー、マニュアルページ、その他。ディレクトリーの作成、削除、イン サートされた(inserted)ファイルの位置を管理するための、他のディレクティブ もこのファイルに記述されます。 詳細はChapter 13, PLIST 問題を参照してください。

11.5. オプションのファイル

11.5.1. バイナリーパッケージに影響をおよぼすファイル

INSTALL

このシェルスクリプトはpkg_add(1)によって二度起動されます。 最初は、パッケー ジが展開された後、ファイルが移動される前に、二度目はインストールするファ イルが移動された後。このファイルは、 PLIST内の@execコマンドでは不可能な特 別な処理のために使うことができます。より詳細な情報はpkg_add(1)pkg_create(1)を参照してください。Section 15.1, “インストール用のプレフィックス以外の場所にあるファイルとディレクトリー”もあわせて参照してください。

DEINSTALL

このスクリプトは、ファイルが削除される前後に実行されます。このスクリプト の責任は、パッケージのインストレーションにかかわる雑多なものをきれいにす ることです。なぜなら、pkg_deleteは、オリジナルのディストリビューションで 作成されたファイルをどのように削除するかをすべて知っておかなければならな いからです。より詳細な情報はpkg_delete(1)pkg_create(1)を参照してください。

MESSAGE

パッケージのインストール後にこのファイルの内容が表示されます。 完全にフリーではないソフトウェアについての法的な通知や、 apache, PHP などのモジュールのインストール後の 設定ファイルの更新に関するヒント等に役立ちます。 パッケージのMakefileMESSAGE_SUBSTを使うことで、変数を簡単に変えられる ことに注意してください:

MESSAGE_SUBST+=  SOMEVAR="somevalue"

とすると、MESSAGE中の "${SOMEVAR}" は、 somevalueに置換されます。標準では、置換は PKGNAME, PKGBASE, PREFIX, LOCALBASE, X11PREFIX, X11BASE, PKG_SYSCONFDIR, ROOT_GROUP, ROOT_USER に対しておこなわれます。

MESSAGE_SRC 変数を設定すると、 置換の対象のファイルを変えたり追加したりすることができます。 この変数は、MESSAGE (このファイルが存在する場合) です。

ALTERNATIVES

FIXME: alternatives の枠組に関するドキュメンテーションは、 ありません。

11.5.2. 構築の過程に影響をおよぼすファイル

Makefile.common

このファイルには、Makefile に書くことができることを好きなように含めることができますが、 このファイルの目的は複数のパッケージから利用することです。 このファイルを利用するパッケージがあらかじめわかっている場合に限り、 使うようにします。それ以外の場合には、*.mk ファイルを書いて、 その役割をあらわすファイル名をつけたほうがよいことが多いでしょう。

buildlink3.mk

このファイルには、buildlink3 の枠組 (Chapter 14, buildlink 方法論参照) のための 依存性情報が含まれます。

hacks.mk

このファイルには、コンパイラーのバグや、 それに類する事象への回避策が含まれます。このファイルは pkgsrc の基盤が自動的にインクルードしますので、インクルードのための .include 行は必要ありません。

options.mk

このファイルには、 利用者が選択可能なパッケージ固有のオプション (Chapter 16, オプションの扱い参照) のためのコードが含まれます。パッケージにオプションが一つか二つしかない場合は、 このコードを Makefile 内に直接書いてもかまいません。

11.5.3. 何の影響もおよぼさないファイル

README*

このファイルは、 パッケージの作成に対して何の影響もおよぼさず、 パッケージ開発者向けの情報を記しただけのものです。

TODO

このファイルには、 パッケージを改良するためにおこなう必要があることが含まれます。

11.6. work*

makeとタイプした時に、配布ファイルが WRKDIR で示されたディレクトリーに展開されます。 make clean を実行すれば、これらを削除することができます。 このディレクトリーは、ソースの展開のほか、 さまざまなタイムスタンプファイルを作っておくためにも使用されます。 これらも、clean によって完全に削除されます。 標準では ${.CURDIR}/work (OBJMACHINE が設定されている場合は ${.CURDIR}/work.${MACHINE_ARCH}) です。

11.7. files/*

また、もしあなたがコンフィギュレーションまたは構築するより前に、パッケージ 中に何かファイルを置きたいならば、それらのファイルをfilesディレクトリーに置 くことができますし、pre-configureターゲットで、 ${CP}コマンドによりコピーす ることができます。あるいは、/dev/nullに対するそのファイルの単純なdiffをとり、 パッチメカニズムを使用して、そのファイルを生成することもできます。

files ディレクトリーにファイルを置く方法で、他のパッケージとファイルを共有したい場合は、 FILESDIR 変数を、他のパッケージの files ディレクトリーを指すように設定します。 たとえば以下のようにします。

FILESDIR=${.CURDIR}/../xemacs/files