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}
に
ついても同様です.