フリーソフトウェアの移植

原作: &a.jkh;, &a.gpalmer; &a.asami;. 7 November 1996.

訳: &a.simokawa;, &a.asami;. 10 November 1996.

フリーで手に入るソフトウェアを移植することは, 何かをゼロから自分で 作ることほどは人に感謝されないにしても, どこに手を入れれば動くのかわから ないような人でも使えるようにするという意味で, FreeBSDの発展のためにとて も重要なことです. 移植されたすべてのソフトウェアは「Portsコレク ション」(the Ports Collection) と呼ばれ, 階層的に分類されて集められ ています. これによって, 新しいユーザでも, 何がすぐに簡単にコンパイルで きる状態で手に入るのか, についての概要をつかむことができます. また, 移植されるソー スコードについては, そのほとんどを実際には含まず, FreeBSDで動かすためのほんのちょっ との差分ファイルといくつかの定義ファイルだけをソースツリーに入れることで, かなりのディスクスペースが節約できます.

これから, FreeBSD 2.x用のportを作る際の, いくつかのガイドラインを 説明します. 実際にportをコンパイルするときのほとんどの仕事は /usr/share/mk/bsd.port.mkというファイルでおこないます。 Portsコレクションについてのさらに細かい内部の働きについては, そちらのファイルを 参照してください. 移植を始める前に

注意: ここでは, 変更可能な変数の一部についてのみ記述してい ます. ほとんどの変数はbsd.port.mkの始めに記述があり ます. また、このファイルは非標準のタブの設定になっていま す. Emacsはファイルのロード時にこれを認識しますが, viexでは, ファイルをロードしたら `:set tabstop=4'のようにして正しい値を設定することがで きます.

Portの過程で, 修正や, どのバージョンのUNIXで動くかによる条件 つきコンパイルなどが必要なコードに出会うかもしれません. その ような条件つきコンパイルなどのための変更をおこなうときには, FreeBSD 1.x システムへの移植や, CSRGの4.4BSD, BSD/386, 386BSD, NetBSDなどの他のBSDシステムへの移植が可能なように, でき るだけ普遍的な変更をおこなうことを心がけてください.

4.3BSD/Renoおよびそれより新しいBSD版を古いバージョンと区別す るには `BSD' マクロを利用するのがよいでしょう. これは <sys/param.h>で定義されています. このファイルが すでにインクルードされていればよいのですが, もしそうでない場合 には以下のコードを, その.c ファイルの適当な場所に加 えて, MakefileのCFLAGS-D_HAVE_PARAM_Hを加 えてください. #ifdef _HAVE_PARAM_H #include #endif そして, 次のようにしてそのコードが4.3 Net2コードベース, または それより新しいもの (例: FreeBSD 1.x, 4.3/Reno, NetBSD 0.9, 386BSD, BSD/386 1.1とそれ以前) の上でコンパイルされているかを検出できます. #if (defined(BSD) && (BSD >= 199103)) また, #if (defined(BSD) && (BSD >= 199306)) これは, 4.4コードベース, またはそれより新しいもの (例: FreeBSD 2.x, 4.4, NetBSD 1.0, BSD/386 2.0とそれ以後) の上でコンパイルさ れているかどうかを検出するために使用します.

以下は控え目に使ってください. __FreeBSD__ はFreeBSDのすべての版で定義されてい ます. 変更がFreeBSDだけに適用されるとき以外は使用しないでく ださい. Portでよくある, strerror() ではなく sys_errlist[] を使うなどは, FreeBSDでの変更ではなく, BSDの流儀です. FreeBSD 2.xでは__FreeBSD__が2と定義されていま す. それ以前の版では1になっています. もし, FreeBSD 1.xシステムとFreeBSD 2.xシステムを区別 する必要があれば, 上で述べたBSDマクロを使用するのが, 大抵の場合において正しい答です. もし, FreeBSD特有の変更であ れば (`ld' を使うときのシェアードライブラリ用のな オプションなど), __FreeBSD__を使い `#if __FreeBSD__ > 1' のようにFreeBSD 2.x システムを検出するのはかまいません. もし, 2.0-RELEASE以降のFreeBSDシステムを細かく検出したけれ ば, 以下を使用することができます. #if __FreeBSD__ >= 2 #include # if __FreeBSD_version >= 199504 /* 2.0.5+ release specific code here */ # endif #endif __FreeBSD_version の値は以下の通りです: 2.0-RELEASE: 199411 2.1-current's: 199501, 199503 2.0.5-RELEASE: 199504 2.2-current (2.1以前): 199508 2.1.0-RELEASE: 199511 2.2-current (2.1.5以降): 199512 2.1.5-RELEASE: 199607 2.2-current (1996年7月12日現在): 199608 (リリースが出る毎に変わります) 見ての通り、これは年・月というフォーマットになっています.

これまで, 何百ものportが作られてきましたが, __FreeBSD__が正しく使われたのは, 1つか2つの場合だけで しょう. 以前のportが誤った場所でそのマクロが使っているからと いって, それをまねする理由はありません. 3分porting

この節では, 簡単なportの方法について説明します. 多くの場合これ では不十分ですが, まあうまくいくかどうか試してみて損はないでしょ う.

まず, 元のtarファイルを${DISTDIR}に置きます. デフォルトは/usr/ports/distfilesです.

注: 以下では, ソフトウェアはそのままコンパイルされるとします. つまり, FreeBSDのマシンで動かすために, 変更がまったく必要ない とします. もしなにか変更が必要な場合には次の節も参照する必要 があります. Makefileの作成

最小限のMakefileは次のようなものです: # New ports collection makefile for: oneko # Version required: 1.1b # Date created: 5 December 1994 # Whom: asami # # $Id$ # DISTNAME= oneko-1.1b CATEGORIES= games MASTER_SITES= ftp://ftp.cs.columbia.edu/archives/X11R5/contrib/ MAINTAINER= asami@FreeBSD.ORG USE_IMAKE= yes .include

おわかりになりますでしょうか. $Id$があ る行の内容については, 気にしないでください. これはこのファイル がportsツリーに書き込まれるときにCVSによって自動的に書 き込まれます. もっと詳しい例が見たければ, の節をご覧ください. Package記述ファイルの作成

どのようなportでも, packageにするしないに関わらず, 3つ の記述ファイルが必要です. pkgサブディレクトリにある, COMMENT, DESCR, それにPLISTです. COMMENT

これには, そのportについての説明を1行で書きます. Package の名前, バージョン番号等は含めないでください. たとえば, こんな具合です: A cat chasing a mouse all over the screen DESCR

これは, そのソフトウェアについての, すこし長い説明を記述しま す. そのportが何をするのかについての数段落程度の簡潔な解説があれば 十分です. 注: このファイルはマニュアルでもなければ, 使用方 法やコンパイル方法についての細かい説明書ではありません. 特 に, READMEファイルを何も考えずにここにコピーするような ことはしないでください. (もちろん, READMEがそのソフトウ ェアの簡潔な説明になっている場合は別ですが.)

このファイルの最後にあなたの名前を書くことが推奨されています. たとえば, こんな具合です. This is a port of oneko, in which a cat chases a poor mouse all over the screen. : (うんぬん.) - Satoshi asami@cs.berkeley.edu PLIST

このファイルには, このportによってインストールされるファ イルが列挙されます. このファイルはpackageを作る際のリス トとして使われるため, `packing list' とも呼ばれます. ここ に書かれているファイル名は, インストール時のプレフィックス (普通は/usr/local/usr/X11R6) からの 相対パスです.

簡単な例を載せておきましょう: bin/oneko man/man1/oneko.1.gz lib/X11/app-defaults/Oneko lib/X11/oneko/cat1.xpm lib/X11/oneko/cat2.xpm lib/X11/oneko/mouse.xpm

'Packing list'の詳細については, pkg_create(1)の マニュアルを参照してください. チェックサムファイルの作成

ただ, `make makesum' と入力するだけです. bsd.port.mkにルールがあるので, 自動的にfiles/md5が 生成されます. Portのテスト

そのportが正しく動くことを, package化を含めて確認してく ださい. まず, `make install', `make package' を試してください. また, `pkg_delete -d <pkgname>' をして,すべてのファイルが正しく消去さ れているかどうかを確認してください. それから, `pkg_add <pkgname>.tgz' をおこない, すべてのファイルが再び現 れ, 正しく動作することを確認してください.

さあ, あなたのportに満足したら, あとはそれをFreeBSDのメイ ンのportsツリーに置いて, 皆に使ってもらうだけです. そのた めには, 必要なファイル (この節で述べたすべてのファイル -- た だし, オリジナルのソースファイル, `work' サブディレ クトリ, およびpackageは含みません) をまとめて .tar.gz ファイルにし, ftp://ftp.FreeBSD.ORG/pub/FreeBSD/incoming/ へ置き, send-pr(1) を使って私たちのところにメールを送っ てください (categoryは `ports', classは `change-request' を 使ってください). 私たちは, 何か不明な点があったらあなたに確 認したのち, それをツリーへ置きます. あなたの名前は, FreeBSD ハンドブックやその他のファイルの `Additional FreeBSD contributors' のリストにも載るでしょう. う〜ん, 素晴らし い. :) 本格的なport

残念ながら, 移植がそう簡単ではなく, 動かすために多少の変更が 必要な場合も多いでしょう. この節では, portsコレクション の方法論にのっとって, そのような場合にどのように変更を施し, 動 くようにしたらよいかを順を追って説明します. port構築の詳細

まず, あなたがportのディレクトリで `make' とタイ プしてから起こる一連の出来事について,順を追って説明しま す. ここを読むときには, 他のウィンドウで同時に bsd.port.mkも開いておくとよいかもしれません.

しかし, bsd.port.mkが何をしているのか, 完全に理解 できなくても心配する必要はありません. そう多くの人が理解して いるわけではないですから... f(^_^;) まず, fetchというターゲットが実行されます. このfetchターゲッ トはローカルディスクの${DISTDIR}に配布ファ イルがあるようにするのが役目です. もし, fetchが必要なファ イルを${DISTDIR}に見つけることができなけ れば, Makefileに指定されているURL ${MASTER_SITES}, そして私たちのFTPサイトで ある (ここ には, 私たちが取ってきたファイルをバックアップとして置いてあ ります) に探しにいきます. そして, ユーザのサイトがインター ネットに直接接続されている場合には, ${FETCH} を使って, その名前のファイルを取っ てきて, ${DISTDIR}に保存します. 次に実行されるのはextractターゲットです. これは, ${DISTDIR}にある, 配布ファイル (普通は gzipされたtarファイル) を読み, ソースを一時的な作業ディレ クトリ${WRKDIR} (デフォルトは work) に展開します. 次に, patchというターゲットが実行されます. まず, ${PATCHFILES}に定義されている, すべてのパッ チをあてます. 次にもし${PATCHDIR} (デフォ ルトはpatches サブディレクトリ) にパッチが存在す れば, これらをアルファベット順にあてます. 次に実行されるターゲットはconfigureです. これには, い ろいろな場合があります. もし存在すれば, scripts/configure が実行されます. もし, ${HAS_CONFIGURE} あるいは ${GNU_CONFIGURE} がセットされていれば, ${WRKSRC}/configure が実行されます. もし, ${USE_IMAKE} がセットされていれば, ${XMKMF} (デフォルト: `xmkmf -a') が実行されます. 最後に, buildというターゲットが実行されます. これは, そのport の専用の作業ディレクトリ (${WRKSRC}) にい き, コンパイルするのが役目です. もし ${USE_GMAKE} がセットされていれば, GNU makeが使用されます. さもなければFreeBSDの makeが使用されます.

上記はデフォルトのルールです. さらに, `pre-<何とか >や `post-<何とか>' というターゲット が定義してあったり, そのような名前のスクリプトが scripts サブディレクトリに置いてある場合には, それ らはデフォルトの動作の前後に実行されます.

たとえば, post-extractというターゲットがMakefile で定義されていて, pre-buildというファイルが, scriptsサブディレクトリにあるとすると, post-extractターゲットは, 通常の展開動作のあとに呼 び出され, pre-buildスクリプトはデフォルトのコンパイ ルのルールが実行される前に実行されます. もし動作が簡単であれ ば, Makefileのターゲットを使用することが推奨されています. な ぜならば, そのportが何らかのデフォルトではない動作を必要とす るのかどうかが一箇所にまとめて書いてあった方が他の人に理解しやす いからです.

デフォルトの動作はbsd.port.mk の `do-<何とか>' というターゲットでおこなわれます. たとえば, portを展開するコマンドは, `do-extract' というターゲットにあります. もし, デフォルトのターゲットに 不満があれば, `do-<something>' というターゲッ トを再定義することによって, どのようにでも直すことができます.

「メイン」のターゲット (例えば, extract, configure等) は, すべての前段階が実行されていること を確認して, 実際のターゲットやスクリプトを呼び出す以外のこと はしません. bsd.port.mkはこれらが変更されることは仮定してい ませんので, もし, 例えば, 展開の仕方を直したいときには, do-extract を直し, 絶対にextractには手を 触れないでください.

これで, ユーザが `make' と入力したときに何が起こ るのかが理解できたと思います. では, 完璧なportを手順を追っ て作ってみましょう. オリジナルのソースの入手

オリジナルのソースを, (普通は) 圧縮されたtarファイルの形 (<foo>.tar.gzあるいは <foo>.tar.Z) で入手して, それを ${DISTDIR} にコピーします. 可能なかぎり, 広 く使われている主流のソースを使用するようにしてください.

もし, ネットワークへの接続のよいFTP/HTTPサイトを見つけるこ とができなかったり, 頭にくるような非標準的な形式しか持ってい ないサイトしか見つけられないときには, 最後の手段として, 私たち 自身で, ftp://freefall.FreeBSD.ORG/pub/FreeBSD/LOCAL_PORTS/ に置くことができます. これについての問い合わせのメールは は &a.ports へお願いします.

もし, あなたのportに必要ないくつかの追加パッチがインター ネット上で手に入るのならば, それらも取ってきて, ${DISTDIR} に置きます. もし, それらがメイン のソースのtarファイルとは別のサイトにあっても, 心配する必要 はありません. そのような状況にはちゃんと対応できるようになっ ています. (以下のをご覧く ださい). Portの修正

適当なディレクトリにtarファイルを展開して, FreeBSDの最新の バージョン上で, 正しくコンパイルできるために必要なあらゆる変 更を施します. 最終的に処理は自動化するわけですから, 何をおこなっ たかを注意深く記録しておきましょう. あなたのport が完成した暁には, ファイルの削除, 追加, 修正を含むすべての処 理が, 自動化されたスクリプトやパッチファイルでおこなえるようになっ ていないといけません.

もし, あなたのportのコンパイルやインストールのために必要 な手作業があまりに多いようならば, Larry Wallの模範的な Configureスクリプトでも参考にしたほうがいいかもしれませ ん. 新しいportsコレクションは, 最小のディスクスペースで, 個々のportがエンドユーザにできるだけ「プラグ & プレ イ」の状態でmakeできることをめざしています.

注意: あなたが作成しFreeBSDのportsに寄付されたパッチファイル, スクリプトおよびその他のファイルは,明示的に記述されている場合 を除いては, BSDの標準的な著作権条件によりカバーされていると見な されます. パッチをあてる

portの過程で追加されたり変更されたファイルは再帰的diffで変 更点を取り出すことができます. パッチは適当にまとめて, `patch-<xx>' という名前のファイルに入れてくだ さい. <xx>はパッチが適用される順番を示します -- これらは, アルファベット順, つまり `aa' が 最初, つぎに `ab' などとなります. これらのファイル を${PATCHDIR}に置いておくと, 自動的に適用さ れるようになっています. すべてのパッチは ${WRKSRC} (通常は, portのtarファイルが展 開されるところで, makeが実行されるところと同じです) からの相 対パスになります. 修正やアップグレードを容易にするため, 2つ 以上のパッチが同じファイルを修正するのは避けてください. (例, patch-aaとpatch-abが共に${WRKSRC}/foobar.c を修正する, など.) コンフィグレーション

カスタマイズのために追加したいコマンドがあれば, configureという名前のスクリプトに入れて `scripts' サブディレクトリに置きます. 上で述べたよ うに, pre-configure あるいはpost-configure というMakefileのターゲットおよび/あるいはスクリプトで処理す ることもできます. ユーザからの入力の扱い

もし, そのportがビルド, コンフィグレーション, インストー ルの際にユーザからの入力を必要とするならば, Makefileで IS_INTERACTIVEをセットしてください. これによって, 深夜, 自動的にたくさんのportをコンパイルすることが可能にな ります. 環境変数BATCHがセットされていると IS_INTERACTIVEの定義されているportはスキップされ ます (そして, ユーザがINTERACTIVEという変数をセッ トすると入力を必要とするportのみコンパイルされま す). 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

${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}に取ってきますが, 展開時に はなにもせずに後で使うためにそのまま置いておかれます. CATEGORIES (分類)

完成したpackageの実体は/usr/ports/packages/All に置かれます. また, 1つかそれ以上の /usr/ports/packagesのサブディレクトリからのシンボリッ クリンクが作られます. それらのサブディレクトリの名前が ${CATEGORIES}という変数によって指定されます. これは, ユーザがFTPサイトやCD-ROMのpackageの山を渡り歩 くことを容易にするためです. 現在存在するカテゴリを見て, そ のportに適したもを選んでください. (などが参考になるでしょう). もしそのportが本当 に現在存在するすべてのものとは異なっている場合には, 新しいカテ ゴリ名を作ることもできます. MASTER_SITES

オリジナルの配布ファイルを指し示すFTPまたはHTTPのURLのディ レクトリ部分までを${MASTER_SITES}に記録しま す. スラッシュ (/) を最後につけることをお忘れなく.

配布ファイルがシステム上に存在しないときに, makeマクロは ${FETCH}でこの変数に指定されたサイトから取っ てきます.

複数の, できれば異なる大陸のサイトをこのリストに入れておく ことが推奨されています. これによって, 広域ネットワークにトラ ブルがあった場合でも成功する可能性が高くなります. 私たちはさら に, 自動的に最も近いマスタサイトを検出して, そこから取って くるメカニズムの導入を計画しています. PATCHFILES

もし, オリジナルの配布ファイル以外にも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

あなたのメールアドレスをここに入れてください. お願いします. :)

保守担当者(maintainer)の責任についての詳細は, の節をご覧ください. 依存関係

このプログラムが他のportに依存する場合には, 必要なものが 自動的に作られるようにすることができます. そのために, 以下の 5つの変数が用意されています. LIB_DEPENDS

Portが必要とする非標準の共有ライブラリをこの変数で指定 します. これは `lib:dir' という組のリストで, うち lib が共有ライブラリの名前, そしてdir がそのライブラリが見つからない場合にインストールするport のあるディレクトリです. 例えば, LIB_DEPENDS= jpeg\\.6\\.:${PORTSDIR}/graphics/jpeg と指定してあれば, まずメジャーバージョンが6のjpegライブ ラリがあるかどうか確認し, ない場合にはportsツリーの中の graphics/jpeg というサブディレクトリに移動し, そこ からインストールしようとします. 前半のlib 部分はそのまま `ldconfig -r | grep' へ引数として渡されることに注意してください. 特 に, ピリオド (.) の前には上記の例のようにバックスラッシュ を連続してつける必要があります. この依存関係はextract ステージのはじめでチェック されます. また, packageを作るときに必要となるportのpackage名 が記録され, pkg_addを使用すると自動的にそちら のpackageもインストールされるようになります. RUN_DEPENDS

Portを使用する際に必要となるファイルまたはプログラムがある ときにはこの変数で指定します. これは`path:dir' とい う組のリストで, path がファイルまたはプログラムの 名前, そしてdir がそれが見つからない場合に作成する ためのディレクトリ名です. Path の最初の文字がスラッ シュ (/) の場合にはファイルとみなし, その存在を `test -e' でチェックします; そうでない場合にはプ ログラムであると仮定し, `which -s' を使ってそのプ ログラムがユーザのサーチパス上にあるかどうか確認します.

例えばMakefileに以下のように書いてあるとします. RUN_DEPENDS= ${PREFIX}/etc/innd:${PORTSDIR}/news/inn \ wish:${PORTSDIR}/x11/tk まず, `/usr/local/etc/innd' というファイルが存在 するか確認し, ない場合にはportsツリーの中の news/inn というサブディレクトリから作られます. ま た, `wish' というプログラムがユーザのサーチパス中 にあるかどうか探し, ない場合には同じくportsツリーの x11/tk というサブディレクトリから作られます. (この例で, `innd' は実際にはプログラムです; この ように, プログラムであっても標準のサーチパス以外のところに あるようなものの場合には, 絶対パスで指定してください.) この依存関係はinstall ステージのはじめでチェック されます. また, packageを作る際に必要となるportのpackage名 が記録され, pkg_addを使用すると自動的にそちら のpackageもインストールされるようになります. BUILD_DEPENDS

Portのコンパイルに必要なファイルまたはプログラムがある ときは, この変数で指定してください. RUN_DEPENDSと同 様に, これは `path:dir' という組のリストです. 例 えば, BUILD_DEPENDS= unzip:${PORTSDIR}/archivers/unzip は `unzip' という名前のプログラムを探し, 見つから ない場合にはarchivers/unzip サブディレクトリで作 れという意味になります. ここでは「コンパイル」と一口にいいましたが, この変数は実際 にはファイルの展開から実際のコンパイル・リンクまで全部をま とめて面倒を見てくれます. この依存関係はextract ステージからチェックされます. FETCH_DEPENDS

この変数は, portを取ってくるのに必要なファイルまたはプロ グラムを指定するのに使います. 上の二つと同様に, これは `path:dir' という組のリストです. 例えば, FETCH_DEPENDS= ncftp2:${PORTSDIR}/net/ncftp2 としておけば, `ncftp2' という名前のプログラムを探 し, 見つからない場合にはnet/ncftp2 サブディレク トリにいってインストールします. この依存関係はfetchステージからチェックされます. DEPENDS

上の四つのいずれにもあてはまらないような依存関係がある場 合, または他のportのソースが展開されている必要がある場合 (インストールされているだけでは不十分な場合) にはこの変数 を使います. これはディレクトリ名のリストです (上の四つと違っ て特に「確認」するものがありませんので). コンパイル時の特別な指定

GNUのmakeを使う場合には, `USE_GMAKE=yes' と指定してください. PortにGNUのconfigureが含まれ ている場合には, `GNU_CONFIGURE=yes' を使います. GNU configureにデフォルトの `--prefix=${PREFIX}' 以外の引数を渡したい場 合には追加部分を${CONFIGURE_ARGS}で指定して ください.

X Window Systemのアプリケーションなど, imakeを 使ってImakefileからMakefileを作成するportの場合には `USE_IMAKE=yes' を指定してください. コンフィグレー ションステージで自動的にxmkmf -a が実行されます. も し `-a' フラグが問題をもたらすなら, さらに `XMKMF=xmkmf'としてください.

PortのMakefileが `all' 以外のものをメインのター ゲットとしている場合には, ${ALL_TARGET} でそ れを指定してください. `install' と ${INSTALL_TARGET} も同様です. NO_INSTALL_MANPAGES

あなたのportがimakeは使うものの `install.man' ターゲットを持っていない場合, `NO_INSTALL_MANPAGES=yes' を指定してください. つい でに, 作者を探し出して八つ裂きにするといいでしょ う. (-_-#) Motifを必要とするport

最近はコンパイルにMotifを必要とするアプリケーションが増えて きました. (Motif自体は有料のものがいくつかの会社から手に入りま すし, 無料の互換ライブラリを作ろうとしているグループが少なくと も一つあります.) Motifはかなり広く使われていますし, 製品のライ センスではライブラリを静的にリンクした実行形式は再配布が認めら れている場合が多いので, Motifを必要とするソフトウェアを簡単に 動的/静的にリンクできるようなしくみが用意されています. REQUIRES_MOTIF

MotifがないとコンパイルできないportのMakefileではこの変 数を指定してください. これによって, Motifを持っていない人が このportをコンパイルしようとするのを未然に防ぎます. ${MOTIFLIB}

この変数はbsd.port.mkによってMotifライブラリの指 定に置き換えられます. ソース内のMakefileやImakefileで Motifライブラリを指定しているところをこの変数に置き換えるよ うにパッチをあててください.

代表的な例としては以下の二つがあげられます: MakefileかImakefileの中でMotifライブラリが `-lXm' として使われている場合には, かわりに `${MOTIFLIB}' と書いてください. Imakefileの中で `XmClientLibs' が使われている 場合には, それを `${MOTIFLIB} ${XTOOLLIB} ${XLIB}' と書きかえてください.

${MOTIFLIB} は通常 `-L/usr/X11R6/lib -lXm' か `/usr/X11R6/lib/libXm.a' に置き換えら れます. したがって前に `-L' や `-l' をつけ る必要はありません. ライセンス上の問題

ソフトウェアによっては制限の厳しいライセンスがついてきたり, 法律的に問題があるものがあります (PKPの公開鍵暗号化, ITAR (暗 号化ソフトウェアの輸出) などが例としてあげられます). それらを どう扱えばいいかはライセンスの文面によってさまざまな場合があり ます.

ソフトウェア移植者として, あなたにはライセンスをよく読み, FreeBSDプロジェクトがFTPまたはCD-ROMで配布してはいけないソフ トウェアを配布してしまうことのないよう, 注意する義務があります. なにか疑問がある場合には, &a.ports;に聞いてみてください.

よく見られるケースに対処するために, 二つの変数が用意されてい ます: ソフトウェアに「有償再配布を禁ずる」という趣旨のライセン スがついてきた場合にはNO_CDROMという変数をセットして ください. 私たちはこれがついているportはCD-ROMリリースに入 れないようにしますが, オリジナルのソースファイルとpackage はFTPでは取れるようにしておきます. Portが, 使用者によっては法律上の問題が生じる時 (暗号化ソフ トウェアなど), または「商用利用を禁ずる」とライセンスに書い てある場合にはRESTRICTEDという変数にその理由を入れ てください. この場合には, ソースファイルやpackageは私たちの FTPサイトにも置かれません.

注: GNU一般公有使用許諾書 (GPL) はバージョン1, 2とも port作成上は何ら問題にはなりません.

注: もしあなたが,ソースツリー管理者 (committer) であれば, ソースツリーにこのようなportを入れる際に, ports/LEGALファイルを書き換えるのを忘れないようにし てください. アップグレード

Portのバージョンが原作者からのものに比べて古いことに気がつ いたら, まずはあなたの持っているportが私たちの最新のもの (ミラー サイトのports-currentというディレクトリにあります) であることを確認してください.

次に, portのMakefileにMAINTAINER (保守担当者) の アドレスが書いてある場合には, その人にメールを出してみましょう. 保守担当者の人がすでにアップグレードの準備をしているかもしれま せんし, (新しいバージョンの安定度に問題があるなど) あえてアッ プグレードをしない理由があるのかもしれません.

保守担当者にアップグレードをしてくれと頼まれた場合, あるいは そもそもportのMakefileに保守担当者が書いてない場合などは, あ なたがアップグレードをしてくださると助かります. その場合にはアッ プグレードをしたのち, 変更前と変更後のディレクトリの再帰的diff をとって送ってください. (例えば, 変更前のディレクトリが `superedit.bak' という名前でとってあり, 変更後のもの が `superedit' に入っているなら, `diff -ru superedit.bak superedit' の結果を送ってください. ) もし変 更点が多すぎて, パッチが新しいport全体より大きくなる場合には, 前に述べた手順にしたがって新しいport全体をしてください. いず れの場合にも, send-pr(1) を使ってメールを送るのを忘れ ないようにしてください. やっていいことといけないこと

この節では, ソフトウェアをportする上でよくある落し穴などにつ いて説明します. WRKDIR

大事なファイルをworkサブディレクトリに置き忘れな いようにしてください. うっかり `make clean' とやっ たらこのディレクトリはその下のファイルとともにあとかたも なく消え去ってしまいます! スクリプトやパッチ以外に必要 なファイルがある場合には, filesというサブディレクト リに入れ, post-extractターゲットでworkサ ブディレクトリにコピーするようにしてください. Package情報

Package情報, すなわちpkgディレクトリ内の三つ のファイルは必ず用意してください. これらはpackageを作る以 外にもいろいろ使われていますので, ${NO_PACKAGE}が指定してあってpackageを作 るのが禁止してあるportの場合でも必ず必要です. マニュアルの圧縮, バイナリのstrip

マニュアルは圧縮し, バイナリはstripしてください. オリジナル のソースがやってくれる場合はそれでいいのですが, そうでない場 合にはpost-installターゲットを指定するのがいいでしょ う. マニュアルの圧縮を望まないユーザもいますので, /etc/make.confで指定できるNOMANCOMPRESSと いう変数をチェックするようにしてください. 例えば, こんな風に なります: post-install: strip ${PREFIX}/bin/xdl .if !defined(NOMANCOMPRESS) gzip -9nf ${PREFIX}/man/man1/xdl.1 .endif

インストールされた実行形式がすでにstripされているかどうか はfileコマンドで確認できます. これが`not stripped' と言わなければ, stripされているということです. INSTALL_* マクロ

あなた自身の *-install ターゲットでファイルの正しいモードと オーナを保証するために, 必ずbsd.port.mkで提供されて いるマクロを使用してください. マクロは以下のようなものがあります. ${INSTALL_PROGRAM} は実行可能なバイナリを インストールするコマンドです. ${INSTALL_SCRIPT} は実行可能なスクリプトを インストールするコマンドです. ${INSTALL_DATA} は共有可能なデータを インストールするコマンドです. ${INSTALL_MAN} はマニュアルを インストールするコマンドです.(圧縮をしません)

これらは基本的にinstallコマンドに適当なフラグを与え たものです. どのようにこれらを使用するかは以下の例を見てください. 付加的ドキュメント

普通のマニュアルやinfoファイルのほかにユーザにとって有用だ と思えるようなドキュメントがある場合には, ${PREFIX}/share/docの下にインストールしてく ださい. これは前記と同様, post-installターゲットの 中からするのがいいでしょう.

まず, あなたのportのために新しいディレクトリを作りま す. どのportのドキュメントか簡単にわかるような名前にする必 要がありますので, 普通は${PKGNAME}からバージョ ン番号を除いた部分を使うといいでしょう. もちろん, ユーザが異 なるバージョンのものを同時に使うことが予想されるportの場合 には, ${PKGNAME}をそのまま使ってかまいません.

ユーザが/etc/make.confでこの部分を禁止するために NOPORTDOCSという変数をセットしている場合には, これらのドキュメントがインストールされないようにしてください. こんな具合です. post-install: .if !defined(NOPORTDOCS) mkdir -p ${PREFIX}/share/doc/xv ${INSTALL_DATA} ${WRKSRC}/docs/xvdocs.ps ${PREFIX}/share/doc/xv .endif

これらのファイルをpkg/PLISTに入れるのを忘れないよ うにしてください. (packageが/etc/make.conf内の 変数を読む方法は今のところ存在しませんので, NOPORTDOCSについては気にしないでください.) DIST_SUBDIR

/usr/ports/distfilesディレクトリ内をあまり散らかさ ないようにしてください. たくさんのファイルを取ってくるport や, 数は少なくてもほかのportのファイルと混同されるおそれが あるファイル (`Makefile' など) がある場合には, ${DIST_SUBDIR}にportの名前 (${PKGNAME}からバージョン番号を取った部分を 使うといいでしょう) を入れてください. すると, ${DISTDIR}がデフォルトの /usr/ports/distfilesから /usr/ports/distfiles/${DIST_SUBDIR}に変更さ れ, 取ってきたファイルはすべてそのサブディレクトリの中に置か れるようになります.

また, ファイルを取ってくるときにバックアップサイトとして使わ れるftp.freebsd.orgのディレクトリ名にもこの変数の 値が使われます. (${DISTDIR}を明示的に指定し た場合には, ローカルのファイルを置くところは変わりますが, こ のサイトのディレクトリ名は変わりませんので, 必ず ${DIST_SUBDIR}を使うようにしてください.)

この変数はMakefile中で明示的に指定された ${MASTER_SITES}には影響しないことに注意して ください. フィードバック

Portを作るためにソフトウェアに変更を加えたら, なるべく原 作者にその旨を伝えてパッチ等を送ってください. これらが次のリ リースに取り入れられれば, アップグレードが楽になります. RCS文字列

RCSが特別な意味を与えている文字列をパッチ内に入れないように してください. ファイルを私たちのソースツリーに入れる時にこれら の文字列はCVSによって書き換えられてしまい, あとでまたパッチ を使おうとした時にうまくいかないことがあります. RCS文字列は ドル記号 (`$') で囲まれており, `$Id' や `$RCS' などで始まり ます. パッチ作成上の注意

diffの再帰 (`-r') フラグを使って再帰的なパッ チを作るのは大変結構なのですが, でき上がったパッチは必ず目で チェックして余計なゴミが入っていないことを確認してくださ い. よくあるのはバックアップファイル同士の変更点, あるいは imakeやGNU configureを使うソフトウェアのMakefileの変更点が 入っている場合などです. また, ファイルをまるごと消す場合には パッチを使わずにpost-extractターゲットで消す方が簡 単です. PREFIX

なるべくportは${PREFIX}に対する相対パス にインストールすることができるように心がけてください. この変数の値は${USE_IMAKE}${USE_X11}が指定してある時には ${X11BASE} (デフォルト/usr/X11R6), そうでない場合には${LOCALBASE} (デフォルト/usr/local) にセットされます.

サイトによってフリーソフトウェアがインストールされる場所が 違いますので, ソース内で `/usr/local' や `/usr/X11R6' を明示的に書かないようにしてくださ い. Xのプログラムでimakeを使うものについては, これは問題に はなりません. それ以外の場合には, ソース中のMakefileやスク リプトで `/usr/local' (imakeを使わないXのプログラ ムは `/usr/X11R6') と書いてあるところを `${PREFIX}' に書き換えてください. この値は portのコンパイル, およびインストール時に自動的に環境変数として 下位makeに渡されます.

変数${PREFIX}の値はportのMakefileやユー ザの環境で変更することもできます. しかし, 個々のportが Makefileでこの変数の値を明示的に設定することはなるべくしない でください. (X のプログラムでimakeを使用しないport の場合は, USE_X11=yesとしてください; これは PREFIX=/usr/X11R6とするのとはかなり違います.)

また, 他のportからインストールされるプログラムやファイル を指定するときには, 上で述べた変数を使用してください. 例えば, lessのフルパスをPAGERというマクロに入れた い場合は, コンパイラに -DPAGER=\"/usr/local/bin/less\"と渡すかわりに -DPAGER=\"${PREFIX}/bin/less\" (Xを使う portの時は -DPAGER=\"${LOCALBASE}/bin/less\") を渡し てください. こうしておけば, `/usr/local' がまるごとどこか他 の場所に移してあるサイトでも, あなたのportがそのまま使える 可能性が高くなります. ディレクトリ構成

インストール時には${PREFIX}の正しいサブ ディレクトリにファイルを置くように心がけてください. ソフトウェ アによっては新しいディレクトリを一つ作ってファイルを全部それ に入れてしまうものがありますが, それはよくありません. また, バイナリ, ヘッダファイルとマニュアル以外のすべてを `lib'というディレクトリに入れてしまうportもありま すが, これもBSD的なファイルシステム構成からいうと正しくあり ません. これは以下のように分散すべきです. `etc' に セットアップ/コンフィグレーションファイル, `libexec' に内部で使用されるプログラム (コマンドラ インから呼ばれることのないコマンド), `sbin' に管理 者用のコマンド, そして `share' にアーキテクチャに依 存しないファイルが入ります. 詳細についてはhier(7) を見てください. /usrの構成方針はほとんどそのまま /usr/localにもあてはまります. ldconfig

共有ライブラリをインストールするときには, 共有ライブラリのキャッ シュを更新するためにportのMakefileのpost-install target から`/sbin/ldconfig -m' を走らせてください. このコマンドの引数は共有ライブラリのインストールしてあるディ レクトリ (通常 ${PREFIX}/lib) です.

また, pkg/PLIST@exec行を入れ, package をインストールした場合にも共有ライブラリがすぐ使えるように してください. この行は共有ライブラリを指定する行のすぐ後に書 くのがいいでしょう: lib/libtcl.so.7.3 @exec /sbin/ldconfig -m %D/lib

絶対に引数なしでただ `ldconfig'とだけ書い てある行をMakefileやpkg/PLISTファイルに入れないでください. このコマンドを実行すると, 共有ライブラリのキャッシュが /usr/libの内容のみとなり, ユーザのマシンにさまざま な問題をもたらします (「ぎゃぁ! このportをインストールした らxinitが使えなくなっちゃった!」). この掟を破った者は, 永久 に地獄の底で苦しみ続けるように, 閻魔様に頼んでおきます. 困ったら....

私たちに質問を送る前に, 既存のportの例とbsd.port.mkを ちゃんと読んでください! ;)

それでもわからないことがあったら, 一人で悩まないでどんどん 質問してください! :) Makefileのお手本

これはportのMakefileを作る際のお手本です. かぎかっこ ([])内のコメントは忘れずに取ってください.

変数の順番, 段落の間の空行など, Makefileを作るときはなるべくこ の形式にしたがってください. 既存のportのMakefileがすべてこの形 式にしたがっているわけではありませんが, 今後はなるべく統一していき たいと考えています. この形式は重要な情報が簡単に見つけられるよ うに設計されています. [ヘッダ -- どのようなportのMakefileかすぐにわかるようになっています] # New ports collection makefile for: xdvi # Version required: pl18 ["1.5alpha" みたいなのでも結構です] # Date created: 26 May 1995 [これはこのソフトウェアを最初にFreeBSDにportした人の名前, つまり, このMakefileを書いた人です] # Whom: Satoshi Asami # # $Id$ [ ^^^^ この行の内容は気にしないでください. CVSツリーに入れる時に 自動的に書き込まれます] # [Port自体, およびオリジナルのソースを取ってくるところを記述する部分. 最初は必ずDISTNAME, そして必要ならPKGNAME, CATEGORIES, 続いて MASTER_SITES, そして必要ならEXTRACT_SUFXかDISTFILESが続きます] DISTNAME= xdvi PKGNAME= xdvi-pl18 CATEGORIES= print [最後のスラッシュを忘れないように ("/")!] MASTER_SITES= ftp://crl.dec.com/pub/X11/contrib/applications/ [ソースファイルが標準の ".tar.gz" 形式でない時にこれを使いましょう] EXTRACT_SUFX= .tar.Z [配布パッチのセクション -- ない場合もあります] PATCH_SITES= ftp://ftp.sra.co.jp/pub/X11/japanese/ PATCHFILES= xdvi-18.patch1.gz xdvi-18.patch2.gz [保守責任者 -- これは *必ず* 必要です. 担当者 (あなた) 自身, あるいは 担当者に素早く連絡をとれる人のアドレスを書いてください. どうしてもこ こに自分のアドレスを書くのがいやな人は "ports@FreeBSD.ORG" と書いて もいいです] MAINTAINER= asami@FreeBSD.ORG [依存するport -- ない場合もあります] RUN_DEPENDS= gs:${PORTSDIR}/print/ghostscript LIB_DEPENDS= Xpm\\.4\\.:${PORTSDIR}/graphics/xpm [ここには標準のbsd.port.mkの変数で, 上のどれにもあてはまらないものを 書きます] [${DISTNAME}以外のディレクトリにソースが展開されるなら...] WRKSRC= ${WRKDIR}/xdvi-new [コンフィグレーション, コンパイル, インストールなどの時に質問をする なら...] IS_INTERACTIVE=yes [GNU autoconfによって生成された "configure" スクリプトを走らせたいなら...] GNU_CONFIGURE= yes [/usr/bin/makeでなく, GNU makeを使わないといけないなら...] USE_GMAKE= yes [これがXのアプリケーションで "xmkmf -a" を走らせたいなら...] USE_IMAKE= yes [などなど] [下の方のルールで使う非標準の変数] MY_FAVORITE_RESPONSE= "yeah, right" [そして, 特別なターゲット, 使用順に] pre-fetch: i go fetch something, yeah post-patch: i need to do something after patch, great pre-install: and then some more stuff before installing, wow [最後には必ず] .include Packageの名前

Packageの名前は以下のルールにしたがってつけてください. こ れはpackageのディレクトリを見やすくするためで, 無秩序な名前 がたくさん並んでいるとユーザが使いづらくなるのではという心配か らです. (FTPサイトなどにはたくさんpackageがありますからね.)

Packageの名前は以下のようにしてください. [<言語>-]<名前>[[-]<オプション>]-<バージョン.番号>; ${DISTNAME} が上記の形式になっていない場合に は, ${PKGNAME} をそのようにしてください. FreeBSDはユーザの慣れ親しんだ言語のサポートに力を入れて います. 特定の言語のためのportのpackage名には `<言語>' に言語名の略称を入れてください. 例えば, 日本 語なら `jp', ロシア語なら `ru' といった具合です. `<名前>' の部分は原則的にはすべて英小文字 を使います. 例外はたくさんのプログラムが入っている巨大なport の場合で, XFree86 (ほんとにあるんですよ) やImageMagickな どがこれにあたります. そうでない場合には, 名前の大文字を小文 字に (少なくとも最初の一字だけは) 変えてください. また, その ソフトウェアの名前として通常使われるものに番号, ハイフン, あ るいは下線が入っている場合には, それらを使うことも構いません (`kinput2' など). コンパイル時に環境変数やmakeの引数などでいくつ か別のオプションをつけてコンパイルできる場合, `<compiled.specifics>' にそのオプションを入れてくださ い (ハイフンはあってもなくてもかまいません). 用紙のサイズ, あるいはフォントの解像度などがこれにあたります. バージョン番号は数字とアルファベットからなり, ピリオド (.) で区切ります. アルファベットは二文字以上続けてはいけませ ん. ただ一つの例外は「パッチレベル」を意味する `pl' で, それ 以外にバージョン番号がまったくついていない場合にのみ使うことがで きます.

では, ${DISTNAME}を正しい ${PKGNAME}に直す例を見てみましょう: DISTNAME PKGNAME 理由 mule-2.2.2 mule-2.2.2 まったく問題なし XFree86-3.1.2 XFree86-3.1.2 同上 EmiClock-1.0.2 emiclock-1.0.2 プログラム一つだけの時は小文字のみ gmod1.4 gmod-1.4 `<名前>' のあとにハイフンが必要 xmris.4.02 xmris-4.02 同上 rdist-1.3alpha rdist-1.3a `alpha'のような文字列は使えない es-0.9-beta1 es-0.9b1 同上 v3.3beta021.src tiff-3.3 なんなんでしょう ;) tvtwm tvtwm-pl11 バージョン番号は必ず必要 piewm piewm-1.0 同上 xvgr-2.10pl1 xvgr-2.10.1 `pl' が使えるのは他にバージョン番号がない場合のみ gawk-2.15.6 jp-gawk-2.15.6 日本語バージョン psutils-1.13 psutils-letter-1.13 コンパイル時に用紙のサイズを指定 pkfonts pkfonts300-1.0 300dpiフォント用のpackage

オリジナルのソースにまったくバージョン情報が見当たらず, また原作 者が新しいバージョンをリリースする可能性が低いときには, バージョ ン番号として `1.0' を使えばいいでしょう (上記のpiewmの例がこ れにあたります). そうでない場合には, 原作者に聞くか, 日付 (`年. 月.日') を使うなどしてください. やっとおしまい!

いやはや, 長い文章ですみません. ここまで読んでくださった方に は感謝, 感謝でございます. (_ _)

さあ, portの作り方がわかったところで, 世界中のソフトウェア をport化しましょう. FreeBSDプロジェクトに貢献するには, それ がもっとも簡単な方法です! :)