Chapter 14. buildlink 方法論

Table of Contents

14.1. パッケージを変換して buildlink3 を使うようにする
14.2. buildlink3.mk ファイルを書く
14.2.1. buildlink3.mk ファイルの分析
14.2.2. buildlink3.mk ファイルの BUILDLINK_API_DEPENDS.pkg を更新する
14.3. builtin.mk ファイルを書く
14.3.1. builtin.mk ファイルの分析
14.3.2. ネイティブおよび pkgsrc のソフトウェアの選択に関する、大域的な設定

buildlink は pkgsrc における枠組のひとつで、パッケージのコンフィギュレーション (configure) および構築 (build) の過程で、どのヘッダーやライブラリーが使われるかを制御するものです。 これは以下の二つの手順によって実現されます。

  1. BUILDLINK_DIR (標準では、 WRKDIR のサブディレクトリー) 内に、 依存するヘッダーやライブラリーを指すシンボリックリンクを作ります。

  2. 通常のコンパイラーツールを置き換えるラッパースクリプトを生成します。 これは、-I${LOCALBASE}/include および -L${LOCALBASE}/lib を、 BUILDLINK_DIR への参照に変換します。 また、オペレーティングシステムによっては、このラッパースクリプトは、 ネイティブのコンパイラーが GCC に見えるようにし、 GCC を要求するパッケージを修正することなく、 ネイティブのコンパイラーで構築できるようにします。

こうすることで、パッケージ構築環境を正規化して、 他にどのようなソフトウェアがインストールされているかにかかわらず、 パッケージを一貫して構築できるようにします。 なお、通常のシステムヘッダーおよびライブラリーのパス、 たとえば /usr/include, /usr/lib などは、すでに探索されていることに注意してください -- buildlink3 は、パッケージの構築を、 システム非標準のソフトウェアから独立させるために設計されたものなのです。

14.1. パッケージを変換して buildlink3 を使うようにする

パッケージが buildlink3 の枠組を使うようにする変換の過程 (bl3ifying - buildlink3 化) は、かなり単純です。 以下のことに注意してください。

  1. 構築の際には、常に、 toolchain 本体ではなくラッパースクリプトが呼ばれるようにしてください。 パッケージによっては巧妙なものがあるので、 ラッパーが呼ばれたかどうかを確実に調べる方法は、 ${WRKDIR}/.work.log を確認することだけです。

  2. たとえば Java VM やスタンドアローンのシェルでは、 パッケージの Makefile で PREFIX を上書きしないでください。${BUILDLINK_DIR} からシンボリックリンクするためのコードは、 pkg_info -qp pkgname からの相対位置にあるファイルを探すからです。

  3. パッケージの依存性として追加されるのは、パッケージの Makefile に列挙した buildlink3.mk ファイルだけ であることを忘れないでください。

あるパッケージのライブラリーやヘッダーに対する依存性が必要な場合は、

DEPENDS+=       foo>=1.1.0:../../category/foo

を、以下のものに置き換えます。

.include "../../category/foo/buildlink3.mk"

通常は、buildlink3.mk ファイルで必要な依存性を定義します。 buildlink3.mk ファイルを使う際に、より新しいバージョンへの依存性が必要な場合は、 そのことを Makefile で定義することができます。たとえば以下のようにします。

BUILDLINK_API_DEPENDS.foo+=   foo>=1.1.0
.include "../../category/foo/buildlink3.mk"

pkgsrc/mk 以下には、 特別なパッケージを扱うための buildlink3.mk ファイルがいくつかあります。

  • bdb.buildlink3.mk は、 BDB_ACCEPTED および BDB_DEFAULT の値にもとづき、 ネイティブまたは pkgsrc の Berkeley DB の実装のどちらかを選択します。

  • curses.buildlink3.mk: システムに Curses も NCurses も附属しない場合に、devel/ncurses パッケージをインストールしてくれます。

  • krb5.buildlink3.mk は、 KRB5_ACCEPTED の値を使って、 Kerberos 5 の実装を必要とするパッケージを Heimdal または MIT-krb5 のどちらに依存させるかを選択します。

  • motif.buildlink3.mk は、 システム附属の Motif がインストールされているかを確認し、 ない場合は、x11/lesstif または x11/openmotif への依存性を追加します。 利用者は、MOTIF_TYPEdt, lesstif または openmotif に設定して、 どの版の Motif を使うかを選択することができます。

  • oss.buildlink3.mk は、 Open Sound System (OSS) API を使うパッケージが使うことがある変数をいくつか定義します。

  • pgsql.buildlink3.mk は、 Postgres 8.0, 8.1 または 8.2 のうち、インストールされているものを受け入れます。 さらなる情報は、このファイルの内容をご覧ください。

  • pthread.buildlink3.mk は、 PTHREAD_OPTS の値を使うとともに、ネイティブの pthread があるか確認し、 ない場合は、必要に応じて devel/pth への依存性を追加します。

  • xaw.buildlink3.mk は、 XAW_TYPE の値を使って、具体的にどの Athena widget ライブラリーを使うかを選択します。

それぞれの buildlink3.mk ファイルのコメントに、 適切な使い方に関するより詳しい説明があります。

14.2. buildlink3.mk ファイルを書く

パッケージの buildlink3.mk ファイルは、 そのパッケージに附属するヘッダーファイルやライブラリーをコンパイルしたりリンクしたりする必要があることを示すために、 Makefile からインクルードされます。 buildlink3.mk ファイルは、 適切な種類の依存関係を追加したり、 さらに必要となるヘッダーやライブラリーを使うために別の buildlink3.mk をインクルードしたりするために必要な情報を、 いつでも提供できるように作ります。

編集するための元となる buildlink3.mk ファイルを作るには、Rene Hexel の pkgtools/createbuildlink パッケージを使うことを強くおすすめします。ほとんどのパッケージに対しては、 以下のコマンドを使うと、buildlink3.mk ファイルのよい出発点となるものを作ってくれます。

% cd pkgsrc/category/pkgdir
% createbuildlink >buildlink3.mk
    

14.2.1. buildlink3.mk ファイルの分析

以下に掲げるのは、 pkgsrc/graphics/tiff における buildlink3.mk の実例です。

# $NetBSD: buildlink3.mk,v 1.16 2009/03/20 19:24:45 joerg Exp $

BUILDLINK_TREE+=	tiff

.if !defined(TIFF_BUILDLINK3_MK)
TIFF_BUILDLINK3_MK:=

BUILDLINK_API_DEPENDS.tiff+=	tiff>=3.6.1
BUILDLINK_ABI_DEPENDS.tiff+=	tiff>=3.7.2nb1
BUILDLINK_PKGSRCDIR.tiff?=	../../graphics/tiff

.include "../../devel/zlib/buildlink3.mk"
.include "../../graphics/jpeg/buildlink3.mk"
.endif # TIFF_BUILDLINK3_MK

BUILDLINK_TREE+=	-tiff

ヘッダーとフッターで、 BUILDLINK_TREE の値を操作しています。 この変数は、パッケージの依存関係を辿るために、 すべての buildlink3.mk ファイルの間で、 共通に使われます。

本体の節では、多重のインクルードを防いだうえで、 pkg への依存性をどのように追加するかを制御しています。 いくつもの重要な変数がこの節で設定されます。

  • BUILDLINK_API_DEPENDS.pkg は、インストールされるパッケージに対して、実際に記録される依存性です。 この変数の既存のリストを残したまま追加するために、 かならず += を使って設定します。 この変数の設定値は、 パッケージの API が現行のものになった以降の最初 (最古) のバージョンにします。

  • BUILDLINK_PKGSRCDIR.pkg は、pkgsrc における pkg のディレクトリーです。

  • BUILDLINK_DEPMETHOD.pkg (上の例には出てきません) は、 pkg への依存性として BUILD_DEPENDSDEPENDS のどちらを使うかを制御します。 BUILDLINK_DEPMETHOD.pkgbuild にすれば、 構築時の依存性となります。この変数を設定しなかった場合は、 完全な依存性となります。

  • BUILDLINK_INCDIRS.pkg および BUILDLINK_LIBDIRS.pkg (上の例には出てきません) は、ヘッダーおよびライブラリーの検索パスに追加するための、 ${BUILDLINK_PREFIX.pkg} のサブディレクトリーです。設定しなかった場合は、それぞれ include および lib となります。

  • BUILDLINK_CPPFLAGS.pkg (上の例には出てきません) は、CPPFLAGS に追加するためのプリプロセッサー用のフラグで、このフラグは configure および build の段階に渡されます。-I オプションは使わずに、上述の BUILDLINK_INCDIRS.pkg を使って処理するようにしてください。

以下の各変数はすべて、二つ目の (多重のインクルードを防いでいる) 節において、 任意に定義されるものであり、どのパッケージのファイルを ${BUILDLINK_DIR} からシンボリックリンクするか、および、 シンボリックリンクによってファイル名をどのように変換するか、 を制御します。

  • BUILDLINK_FILES.pkg (上の例には出てきません) は、 ${BUILDLINK_DIR} からシンボリックリンクされるリンク先の、 ${BUILDLINK_PREFIX.pkg} からの相対位置のシェルのグロブパターンです。 たとえば include/*.h のようになります。

  • BUILDLINK_FILES_CMD.pkg (上の例には出てきません) は、 ${BUILDLINK_PREFIX.pkg}. からの相対位置でのファイルのリストを標準出力に出力する、シェルのパイプラインです。 これにより出力されるファイルは、 ${BUILDLINK_DIR} からシンボリックリンクされます。指定しなかった場合、 pkg+CONTENTS${BUILDLINK_CONTENTS_FILTER.pkg} でフィルターした結果が出力されるようになります。

  • BUILDLINK_CONTENTS_FILTER.pkg (上の例には出てきません) は、+CONTENTS を入力にとり、 ${BUILDLINK_PREFIX.pkg} からの相対位置でのファイルのリストを標準出力に出力するフィルターコマンドです。 指定しなかった場合、overwrite パッケージでは、 BUILDLINK_CONTENTS_FILTER.pkg はパッケージの +CONTENTS から include および lib ディレクトリーの内容を出力し、 pkgviews パッケージでは、lib ディレクトリーにある libtool アーカイブをすべて出力します。

  • BUILDLINK_FNAME_TRANSFORM.pkg (上の例には出てきません) は、元ファイル名から宛先ファイル名への変換用の sed の引数のリストです。たとえば -e "s|/curses.h|/ncurses.h|g" のようになります。

この節では、 pkg のライブラリー依存性として必要な buildlink3.mk をすべてインクルードすることができます。 ここで buildlink3.mk ファイルをインクルードすると、 pkgbuildlink3.mk ファイルがインクルードされる場合はいつも、 これらへの依存性のためのヘッダーやライブラリーも、 ${BUILDLINK_DIR} からシンボリックリンクされることになります。 依存性が追加されるのは、 buildlink3.mk ファイルを直接インクルードした場合だけです。

14.2.2. buildlink3.mk ファイルの BUILDLINK_API_DEPENDS.pkg を更新する

パッケージを更新した際に BUILDLINK_API_DEPENDS.pkg に列挙されている依存性のバージョンを上げる必要があるのは、 その更新で API やヘッダーファイルへのインターフェースが変わった場合です。

このような場合は、 BUILDLINK_API_DEPENDS.pkg を調節して、最低限、新しいパッケージのバージョンを要するようにします。 場合によっては、新しいバージョンに依存するパッケージの PKGREVISION を上げる必要があることがあります。 また、依存しているパッケージに buildlink3.mk ファイルがある場合は、 BUILDLINK_API_DEPENDS.pkg も調節します。これは、pkgsrc が適切なパッケージの依存性を求めるようにして、 ソースからの構築時に古いパッケージに依存したりしないようにするために、 必要なことです。

BUILDLINK_ABI_DEPENDS.pkg を上げるのは、バイナリーインターフェースや、 インストールされている共有ライブラリーのいずれかの soname (ライブラリーのバージョンのメジャー番号) が変わった場合です。 これは、これらを使うバイナリーパッケージが、 適切なパッケージの依存性を求めるようにして、 必要な共有ライブラリーをもたない古いパッケージに依存したりしないようにするために、 必要なことです。

BUILDLINK_ABI_DEPENDS および ABI_DEPENDS の定義を含めた、 他のパッケージへの依存性について、さらなる情報は、 Section 19.1.6, “依存性の処理”をご覧ください。

なお、必要もないのにパッケージを削除したり再構築したりするようなことのないよう、 BUILDLINK_API_DEPENDS.pkgBUILDLINK_ABI_DEPENDS.pkg の調節は、事前に熟考するようにしてください。 多くの場合、新しいバージョンのパッケージは、 従前の依存性のままでも問題なく動作します。

また、 BUILDLINK_ABI_DEPENDS.pkg は、 BUILDLINK_API_DEPENDS.pkg と同じ値となる場合には設定する必要はありません。

14.3. builtin.mk ファイルを書く

pkgsrc のパッケージのなかには、 ベースシステムにも存在するようなヘッダーやライブラリーをインストールするものがあります。 そのようなパッケージでは、 buildlink3.mk ファイルとは別に、 builtin.mk ファイルも含めておきます。 このファイルでは、ベースシステム附属のソフトウェアと pkgsrc のソフトウェアのどちらを使うのが適切かを判断するために必要な確認をおこないます。

pkg 用の builtin.mk ファイルで必要なのは、以下のことだけです。

  1. インクルードされた後に USE_BUILTIN.pkgyes または no のどちらかに設定すること。

  2. builtin.mk ファイルがインクルードされる前から定義されている USE_BUILTIN.pkg を、一切上書きしないこと。

  3. 複数のインクルードができるように書くこと。 これは非常に重要なことであり、 Makefile のコーディングに対する配慮となります。

14.3.1. builtin.mk ファイルの分析

以下に掲げるのは、builtin.mk ファイルの推奨テンプレートです。

.if !defined(IS_BUILTIN.foo)
#
# IS_BUILTIN.foo is set to "yes" or "no" depending on whether "foo"
# genuinely exists in the system or not.
#
IS_BUILTIN.foo?=        no

# BUILTIN_PKG.foo should be set here if "foo" is built-in and its package
# version can be determined.
#
.  if !empty(IS_BUILTIN.foo:M[yY][eE][sS])
BUILTIN_PKG.foo?=       foo-1.0
.  endif
.endif  # IS_BUILTIN.foo

.if !defined(USE_BUILTIN.foo)
USE_BUILTIN.foo?=       ${IS_BUILTIN.foo}
.  if defined(BUILTIN_PKG.foo)
.    for _depend_ in ${BUILDLINK_API_DEPENDS.foo}
.      if !empty(USE_BUILTIN.foo:M[yY][eE][sS])
USE_BUILTIN.foo!=                                                       \
        ${PKG_ADMIN} pmatch '${_depend_}' ${BUILTIN_PKG.foo}            \
        && ${ECHO} "yes" || ${ECHO} "no"
.      endif
.    endfor
.  endif
.endif  # USE_BUILTIN.foo

CHECK_BUILTIN.foo?=     no
.if !empty(CHECK_BUILTIN.foo:M[nN][oO])
#
# Here we place code that depends on whether USE_BUILTIN.foo is set to
# "yes" or "no".
#
.endif  # CHECK_BUILTIN.foo

最初の節では、pkg がベースシステムに実際に存在するかどうかに応じて、 IS_BUILTIN.pkg を設定しています。これは、ベースシステムに pkg 相当の機能のソフトウェアが存在するかどうかではありません。 この変数を yes にするのは、 このパッケージそのものがベースシステムの一部として附属する場合だけです。 この変数は、builtin.mk ファイルの内部でのみ使われます。

二つ目の節では、pkg がベースシステムに存在する場合 (つまり IS_BUILTIN.pkgyes の場合)、 BUILTIN_PKG.pkg をそのバージョンに設定しています。この変数は、builtin.mk ファイルの内部でのみ使われます。

三つ目の節では、 USE_BUILTIN.pkg を設定しており、これはすべての builtin.mk ファイルで必須です。 この節のコードは、ベースシステム附属のソフトウェアが、 BUILDLINK_API_DEPENDS.pkg で列挙されている依存性を満たすのに十分かどうかを判別する必要があります。 この判別は、たいていは、 BUILTIN_PKG.pkg を、 BUILDLINK_API_DEPENDS.pkg の各依存性と比較することでおこなわれます。 USE_BUILTIN.pkg は、builtin.mk ファイルの終わりまでに、 適切な値に設定する必要があります。なお、たとえ IS_BUILTIN.pkgno であっても、 USE_BUILTIN.pkgyes にすることができます。なぜなら、 ベースシステム附属のソフトウェアが依存パッケージに十分似ており、 代替可能であるという判断もできるからです。

最後の節は CHECK_BUILTIN.pkg に守られており、前の節で設定された USE_BUILTIN.pkg の値を使うコードをインクルードします。たいていの場合、ここでインクルードするのは、 たとえば依存性への制約の追加や、${BUILDLINK_DIR} からシンボリックリンクされるファイルのリストの (BUILDLINK_FILES.pkg を使った) 追加などです。

14.3.2. ネイティブおよび pkgsrc のソフトウェアの選択に関する、大域的な設定

パッケージの構築時に、 依存性を満たすソフトウェアとして組み込み (ネイティブ) のものを使うか pkgsrc のものを使うかを、 大域的な設定に応じて切替えることができます。 この制御は、PREFER_PKGSRC および PREFER_NATIVE を設定することでおこないます。 この両変数は、yes, no またはパッケージのリストを値として持ちます。 PREFER_PKGSRC は pkgsrc 版のソフトウェアを使うことを、 PREFER_NATIVE で組み込み版を使うことを、 それぞれ指示します。この設定は、 対象パッケージではどちらを使うのがもっとも適当かに応じて、 PREFER_PKGSRCPREFER_NATIVE のいずれかで指定します。 あるパッケージがどちらにも設定されていない場合、 または両方で設定されている場合は、 PREFER_PKGSRCPREFER_NATIVE より優先します。たとえば、 NetBSD システムの最も基本的な要素を除き、 すべて pkgsrc 版のソフトウェアを使うこととする場合、 以下のように設定することができます。

PREFER_PKGSRC=  yes
PREFER_NATIVE=  getopt skey tcp_wrappers

あるパッケージを PREFER_NATIVE のリストに加えるには、そのパッケージに builtin.mk ファイルがある必要があります。 このファイルがない場合は、リストに加えても単に無視されます。