Makefileの作成は非常に単純です. 繰り返しになりますが, 始める まえに, すでにある例を見てみることをお奨めします. またこのハ ンドブックには Makefileのお手本 があります. それを見て, Makefile内の変数の順番や空行を入れると ころなどの参考にしてください. そうすると他の人々にも読みやすい ものとなります.
では, Makefileをデザインするときに問題となるところを順に追っ て見てみましょう.
ソースは${DISTDIR}に, 標準的なgzipされた
tarファイルとして置かれていますか? そうであれば, 次のステッ
プに進めます. そうでなければ, 変数
${EXTRACT_CMD},
${EXTRACT_BEFORE_ARGS},
${EXTRACT_AFTER_ARGS},
${EXTRACT_SUFX},
${DISTFILES}を適当に書き換えないといけません.
どれだけ変更しないといけないかは, あなたのportの
配布ファイルがどの程度標準からかけはなれているかによりま
す. (最もよくある場合は, gzipではなく普通のcompressコマンド
でtarファイルが圧縮されている場合で,
`EXTRACT_SUFX=.tar.Z' とするだけです.)
最悪の場合には, 自分で `do-extract' ターゲットを作
成して, デフォルトを上書きすることもできます. しかし, そこま
でする必要があることはめったにないでしょう.
${DISTNAME}にはportの名前の基幹部分を入れ
ます. デフォルトのルールでは, 配布ファイルのリスト
(${DISTFILES}) は
${DISTNAME}${EXTRACT_SUFX}という名前
になっています. 例えば, `DISTNAME=foozolix-1.0'の場
合, 通常のtarファイルだと,
foozolix-1.0.tar.gz
のようになります.
さらにデフォルトのルールでは, tarファイルは
work/${DISTNAME}というサブディレクトリ
に展開されることを仮定しています, 例えば
work/foozolix-1.0/
といった具合いです.
これらの動作はもちろんすべて変更可能です. デフォルトのルー
ルは最も標準的な場合を仮定しているだけです. まず, portが複
数の配布ファイルを必要とするときには, 単に明示的に
${DISTFILES}を設定してください. もし,
${DISTFILES}の一部だけが実際に展開される場合
には, それらを${EXTRACT_ONLY} に設定してくだ
さい. この変数が定義されている場合には, 展開時に
${DISTFILES}に優先して利用されます. 残りのファ
イルも${DISTDIR}に取ってきますが, 展開時に
はなにもせずに後で使うためにそのまま置いておかれます.
もし, ${DISTNAME} が我々の
packageの名前についてのガイドライン
に沿ったものでない場合には, ${PKGNAME} にもっと良い
名前を設定してください. 詳細は上記のガイドラインを参照してください.
完成したpackageの実体は/usr/ports/packages/All
に置かれます. また, 1つかそれ以上の
/usr/ports/packagesのサブディレクトリからのシンボリッ
クリンクが作られます. それらのサブディレクトリの名前が
${CATEGORIES}という変数によって指定されます.
これは, ユーザがFTPサイトやCD-ROMのpackageの山を渡り歩
くことを容易にするためです. 現在存在する
カテゴリを見て, そ
のportに適したもを選んでください.
このリストは, この port が port tree のどこに import されるかも決定します. 2つ以上のカテゴリを指定した場合には 最初のカテゴリで指定されるサブディレクトリに置かれること になります. 適切なカテゴリを選ぶ方法については, カテゴリの節を 参照してください.
もしそのportが本当に現在存在するすべてのものとは異なって
いる場合には, 新しいカテゴリ名を作ることもできます.
その際には, FreeBSD 移植ソフトウエアメーリングリスト
<freebsd-ports@FreeBSD.ORG> 宛てに新しいカテゴリ名を提案する
メールを送ってください.
カテゴリ名については, なんのエラーチェックも行なわれません.
ミスタイプがあっても`make package' はなにも考えずに
新しいディレクトリを作ってしまいますので, 注意してください.
オリジナルの配布ファイルを指し示すFTPまたはHTTPのURLのディ
レクトリ部分までを${MASTER_SITES}に記録しま
す. スラッシュ (/) を最後につけることをお忘れなく.
配布ファイルがシステム上に存在しないときに, makeマクロは
${FETCH}でこの変数に指定されたサイトから取っ
てきます.
複数の, できれば異なる大陸のサイトをこのリストに入れておく ことが推奨されています. これによって, 広域ネットワークにトラ ブルがあった場合でも成功する可能性が高くなります. 私たちはさら に, 自動的に最も近いマスタサイトを検出して, そこから取って くるメカニズムの導入を計画しています.
オリジナルのtar ファイルが, X-contrib, GNU, Perl CPAN, TeX CTAN または Linux Sunsite などの有名なアーカイブにある場合には, MASTER_SITE_XCONTRIB, MASTER_SITE_GNU, MASTER_SITE_PERL_CPAN, MASTER_SITE_TEX_CTAN および MASTER_SITE_SUNSITE を利用することで, 簡単にこれらのサイトを 指定することができます. あとは MASTER_SITE_SUBDIR にアーカイ ブ内でのパスを指定するだけです. 以下に例を示します.
MASTER_SITES= ${MASTER_SITE_XCONTRIB}
MASTER_SITE_SUBDIR= applications
ユーザは/etc/make.conf中で MASTER_SITE_* 変数を設定
することによって, デフォルトの FTP サイトではなく, これらの
有名なアーカイブのミラーの中で好みのものを使用することが可能
です.
もし, オリジナルの配布ファイル以外にもFTPかHTTPで手に入る
パッチが必要な場合には, ${PATCHFILES}にファ
イル名を, ${PATCH_SITES}にサイトとディレクト
リの名前を${MASTER_SITES}と同様に設定してく
ださい.
そのパッチ内のファイル名ががソースツリーの一番上のディレク
トリ (${WKRSRC}) からの相対パスになっていな
い場合には, ${PATCH_DIST_STRIP}を指定してく
ださい. 例えば, パッチ内のファイル名にすべて余計な
`foozolix-1.0/' がついている場合には,
`PATCH_DIST_STRIP=-p1'としてください.
これらのパッチは圧縮されていても大丈夫です. ファイル名が
`.gz' か `.Z' で終わる場合には自動的に復元
されるようになっています.
もしパッチが, 文書などその他のファイルと一緒にgzipされた
tarファイルで配布されている場合には,単純に
${PATCHFILES} を使うことはできません.
このような場合には, このパッチの tar ファイルの名前と場所を
${DISTFILES} と ${MASTER_SITES}
に加えます. それから, pre-patch ターゲットで,
パッチコマンドを走らせるか, パッチファイルを
${PATCHDIR} ディレクトリに
patch-<xx>という名前でコピーするかして,
パッチを適用するようにします.(普通の gzip か compress された
tar ファイルであれば,通常のソースファイルと一緒にその時までに
展開されていますので,明示的に展開する必要はありません.)
もし,後者の方法を使用する場合には,すでにそのディレクトリにある
なにかを上書きしないように, 注意する必要があります.
さらに, pre-clean ターゲットにコピーしたパッチファイル
を削除するコマンドを追加するのを忘れないでください.
あなたのメールアドレスをここに入れてください. お願いします.
:)
保守担当者(maintainer)の責任についての詳細は, Makefile 中の MAINTAINER の節をご覧ください.
このプログラムが他のportに依存する場合には, 必要なものが 自動的に作られるようにすることができます. そのために, 以下の 5つの変数が用意されています. よくあるケースのために あらかじめ設定された依存変数や, いくつかの依存関係の制御のため の変数があります.
Portが必要とする非標準の共有ライブラリをこの変数で指定
します. これは `lib:dir[:target]' という組のリストで,
lib が共有ライブラリの名前, そしてdir
がそのライブラリが見つからない場合にインストールするport
のあるディレクトリで, target はそのディレクトリで
呼ばれるターゲットです. 例えば,
LIB_DEPENDS= jpeg.9:${PORTSDIR}/graphics/jpeg:install
と指定してあれば, まずメジャーバージョンが9のjpegライブ
ラリがあるかどうか確認し, ない場合にはportsツリーの中の
graphics/jpeg というサブディレクトリに移動し, そこ
でコンパイルとインストールを行ないます. `:target' の
部分は, ${DEPENDS_TARGET} (デフォルトは
`install') と等しいときには省略できます.
前半のlib 部分は `ldconfig -r | grep -wF'
への引数になります. この変数には正規表現を入れられません.
この依存関係は2度チェックされます. まず extract
ターゲットで, 次に install でチェックされます.
(これは, その port を作成するマシンとインストールする
マシンが違う場合でも, きちんとそのライブラリが利用できる
ことを確認するためです.) また, 依存するもの名前は package
の中にも含まれますので, ユーザのシステムに存在しなければ,
pkg_add が自動的にインストールします.
Portを使用する際に必要となるファイルまたはプログラムがある
ときにはこの変数で指定します. これは`path:dir[:target]'
という組のリストで, path がファイルまたはプログラムの
名前, そしてdir がそれが見つからない場合に作成する
ためのディレクトリ名で, 'target' はそのディレクトリで
呼ばれるターゲットです. Path の最初の文字がスラッ
シュ (/) の場合にはファイルかディレクトリとみなし,
その存在を `test -e' でチェックします; そうでない
場合には実行可能であると仮定し, `which -s' を使って
そのプログラムがユーザのサーチパス上にあるかどうか確認します.
例えばMakefileに以下のように書いてあるとします.
RUN_DEPENDS= ${PREFIX}/etc/innd:${PORTSDIR}/news/inn \
wish8.0:${PORTSDIR}/x11-toolkits/tk80
まず, `/usr/local/etc/innd' というファイルか
ディレクトリが存在するか確認し, ない場合にはportsツリーの中の
news/inn というサブディレクトリから作られます. ま
た, `wish8.0' というプログラムがユーザのサーチパス中
にあるかどうか探し, ない場合には同じくportsツリーの
x11-toolkit/tk80 というサブディレクトリから作られます.
(この例で, `innd' は実際にはプログラムです; この
ように, プログラムであっても標準のサーチパス以外のところに
あるようなものの場合には, 絶対パスで指定してください.)
この依存関係はinstall ステージのはじめでチェック
されます. また, packageを作る際に必要となるportのpackage名
が記録され, pkg_addを使用するとユーザのシステム
に存在しない場合には自動的にそちらのpackageもインストール
されるようになります. `:target' の部分は,
${DEPENDS_TARGET} と同じ場合には省略可能
です.
Portのコンパイルに必要なファイルまたはプログラムがある
ときは, この変数で指定してください. RUN_DEPENDSと同
様に, これは `path:dir[:target]' という組のリストです.
例えば,
BUILD_DEPENDS= unzip:${PORTSDIR}/archivers/unzip
は `unzip' という名前のプログラムを探し, 見つから
ない場合にはarchivers/unzip サブディレクトリで作
れという意味になります.
ここでは「コンパイル」と一口にいいましたが, この変数は実際
にはファイルの展開から実際のコンパイル・リンクまで全部をま
とめて面倒を見てくれます. この依存関係はextract
ステージからチェックされます. `:target' の部分は
${DEPENDS_TARGET} と同じ場合には省略可能です.
この変数は, portを取ってくるのに必要なファイルまたはプロ
グラムを指定するのに使います. 上の二つと同様に, これは
`path:dir[:target]' という組のリストです. 例えば,
FETCH_DEPENDS= ncftp2:${PORTSDIR}/net/ncftp2
としておけば, `ncftp2' という名前のプログラムを探
し, 見つからない場合にはnet/ncftp2 サブディレク
トリにいってインストールします.
この依存関係はfetchステージからチェックされます.
`:target' の部分は ${DEPENDS_TARGET}
と同じ場合には省略可能です.
上記の四つのいずれにもあてはまらないような依存関係がある場
合, または他の port がインストールされれているだけではなく,
ソースが展開されている必要がある場合にはこの変数
を使います. これは `dir[:target]' という形式のリスト
になります. 上記の四つと違って特に「確認」するものがありませ
んので.
もし ports が X Window System を必要とするのであれば,
`USE_XLIB=yes' を定義してください. (これは
USE_IMAKE も意味します) BSD make の代りに
GNU make を必要とする場合には, `USE_GMAKE=yes'
を定義. 動作するのに GNU autoconf を必要とする場合には,
`USE_AUTOCONF=yes' を定義. 最新の qt toolkit を使用
する場合には `USE_QT=yes' を定義. perl 言語の
バージョン5 を必要とする場合には, `USE_PERL5=yes'
を定義してください. (特に最後のは重要で, FreeBSD のいくつかの
バージョンでは基本システムに perl5 を含みますが, 他のものは
含んでいません.)
上で述べたように, 依存する ports が必要になったときに
呼ばれるデフォルトのターゲットは
${DEPENDS_TARGET} で, そのデフォルトは
`install' です. これは, ユーザの使用する変数で,
port の Makefile で定義されるものではありません.
もし, あなたのportが特別な方法で, 依存関係を扱う必要が
ある場合には, ${DEPENDS_TARGET} を再定義
するのではなく, *_DEPENDS 変数の `:target'
の部分を利用してください.
`make clean' とタイプしたときには, 依存する
port も自動的に clean されます. もしそうしたくない場合
には, NOCLEANDEPENDS を環境変数として設定してください.
無条件に他の port に依存させるには, 特別に `nonexistent'
という文字列を BUILD_DEPENDS あるいは RUN_DEPENDS
の最初のフィールドに使用してください. これは, 他の port の
ソースが必要なときのみ使用してください. target も指定すること
によって, コンパイルの時間を節約することができます. 例えば,
BUILD_DEPENDS= /nonexistent:${PORTSDIR}/graphics/jpeg:extract
これは, 常に JPEG port の directory に行きソースの展開
を行ないます.
あなたがやりたいことが他の方法ではできない場合以外は,
`DEPENDS' を使わないでください. これは常に
他の port の作成を行い(さらにデフォルトでインストール
を行い), package も作成します. もし本当にこれがあなたの
やりたいことでしたら, 代りにこれを BUILD_DEPENDS と
RUN_DEPENDS で書くことをお勧めします -- 少なくとも
意図が明確になります.
GNUのmakeを使う場合には, `USE_GMAKE=yes'
と指定してください. Portに GNU configureが含まれ
ている場合には, `GNU_CONFIGURE=yes' を使います
(これは, HAS_CONFIGURE も意味します).
configureに追加の引数 (デフォルトでは, GNU の
configure では `--prefix=${PREFIX}',
GNUでないconfigure では空) を渡したい場合には追加部分
を${CONFIGURE_ARGS}で指定してください.
そのパッケージが autoconf を使用する場合には,
`USE_AUTOCONF=yes' を使います. これは,
GNU_CONFIGURE も意味し, configure の前に
autoconf を実行します.
X Window Systemのアプリケーションなど, imakeを
使ってImakefileからMakefileを作成するportの場合には
`USE_IMAKE=yes' を指定してください. コンフィグレー
ションステージで自動的にxmkmf -a が実行されます. も
し `-a' フラグが問題をもたらすなら, さらに
`XMKMF=xmkmf'としてください.
もし, port が imake を使用するけれども, `install.man'
ターゲットがない場合には, `NO_INSTALL_MANPAGES=yes'
を指定してください. ついでに, その port のオリジナルの
作者を探し出して八つ裂きにするといいでしょう. :>
PortのMakefileが `all' 以外のものをメインのター
ゲットとしている場合には, ${ALL_TARGET} でそ
れを指定してください. `install' と
${INSTALL_TARGET} も同様です.
もし, port の元の Makefile が `all' 以外のターゲット
をメインのターゲットとしている場合には,
${ALL_TARGET} をそれに合わせて設定してください.
`install' と ${INSTALL_TARGET} に
ついても同様です.