---
title: 第4章 本格的な port
prev: books/porters-handbook/quick-porting
next: books/porters-handbook/makefile
showBookMenu: true
weight: 4
params:
  path: "/books/porters-handbook/slow/"
---

[[slow]]
= 本格的な port
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 4
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/porters-handbook/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

残念ながら移植がそう簡単ではなく、それを動かすために 多少の変更が必要になる場合もあるでしょう。 このセクションでは、模範的な ports の作法に従い、 どのように変更を行なって動くようにするのかを 順を追って説明します。

[[slow-work]]
== port 構築の詳細

まず、あなたが port のディレクトリで `make` と 入力してから起こる一連の出来事について、 順を追って説明します。 ここを読むときには、別のウィンドウに [.filename]#bsd.port.mk# を表示しておくと 理解の助けになるかもしれません。

しかし、[.filename]#bsd.port.mk# が何をしているのか 完全に理解できなくても 心配する必要はありません。 それほど多くの人が理解している というわけでは ありませんから...。 _f(^_^;)_

[.procedure]
====
. まず、`fetch` という ターゲットが実行されます。 この `fetch` ターゲットは、 配布ファイルがローカルの `DISTDIR` に 存在することを保証する役目を持っています。 もし必要なファイルが `DISTDIR` に 存在しなければ、`fetch` ターゲットは [.filename]#Makefile# で指定された `MASTER_SITES` 中の URL や、 FreeBSD のメイン FTP サイト link:ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/[ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/] (ここにはバックアップとして、われわれ ports 管理者が確認した 配布ファイルを置いてあります) を探しにいきます。 `make` を実行するマシンがインターネットに 接続されていて、目的のファイルを `FETCH` で 取ってこれた場合には、それを `DISTDIR` に 保存します。
. 次に `extract` ターゲットが実行されます。 このターゲットは `DISTDIR` から 配布ファイル (普通は gzip された tar ファイル) を読み込み、 その内容を作業ディレクトリ `WRKDIR` (デフォルトでは [.filename]#work#) に展開します。
. 次に `patch` ターゲットが実行されます。 まず、`PATCHFILES` にパッチファイルが 指定されていれば、そのパッチを適用します。 次に、`PATCHDIR` ディレクトリ (デフォルトでは [.filename]#files# サブディレクトリ) に [.filename]#patch-*# という 名前のパッチファイルが存在すれば、 これらをアルファベット順に適用します。
. 次に `configure` ターゲットが 実行されます。 これには、いろいろな場合があります。
.. [.filename]#scripts/configure# が 存在する場合には、そのスクリプトが実行されます。
.. `HAS_CONFIGURE` または `GNU_CONFIGURE` がセットされていれば、 [.filename]#WRKSRC/configure# が 実行されます。
.. `USE_IMAKE` がセットされていれば、 `XMKMF` (デフォルトでは `xmkmf -a`) が 実行されます。

. 最後に `build` ターゲットが実行されます。 これは作業ディレクトリ (`WRKSRC`) に降りていき、 ビルド (コンパイル) を実行するのが役目です。 `USE_GMAKE` がセットされていれば GNU `make` が使用され、 セットされていなければ FreeBSD の `make` が 使用されます。
====

上記はデフォルトの動作です。これに加えて ``pre-__ 何とか__``や ``post-__何とか__``という ターゲットを定義したり、そのような名前のスクリプトを [.filename]#scripts# サブディレクトリに置くことも可能で、 それぞれデフォルトの動作の前や後に実行されます。

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

デフォルトの動作は [.filename]#bsd.port.mk# の ``do-__何とか__``という ターゲットで実行されます。 たとえば port を展開するコマンドは `do-extract` ターゲットに書かれています。 もしデフォルトのターゲットに不満があれば、 [.filename]#Makefile# 中で ``do-__ 何とか__``という ターゲットを再定義することにより、 好きなように変更することができます。

[NOTE]
====
"メイン"のターゲット (たとえば `extract`, `configure`、その他) は、 すべての前段階が実行されていることを確認してから、 実際のターゲットやスクリプトを呼び出す以外のことは 行ないませんし、これらが変更されることも想定されていません。 もし展開の方法を変更したいときには `do-extract` の変更によって実現し、 `extract` の動作は絶対に変更しないでください。
====

これで、ユーザが `make` と 入力したときに何が起こるのかが理解できたと思います。 では、完璧な port を作成するための推奨手順を 順に見ていきましょう。

[[slow-sources]]
== オリジナルのソースの入手

(通常の場合、) 圧縮された tar ファイルの形 ([.filename]#foo.tar.gz# あるいは [.filename]#foo.tar.Z#) で オリジナルのソースを入手して、 それを `DISTDIR` にコピーします。 できる限り、__主流の__ソースを 使用するようにしてください。

もとの tar ファイルがどこにあるかを示すために、変数 `MASTER_SITES` を設定する必要があります。 主なサイトのほとんどについては省略形が [.filename]#bsd.sites.mk# で定義されています。 これらのサイト (と付随する定義) を、ソースコード内で同じ情報が繰り返されるのを避けるために、 可能な限り使うようにしてください。 これらのサイトは時とともに変わってゆきますので、そうしないと、 関係者一同にとってメンテナンスの悪夢になってしまいます。

ネットワークへの接続の良好な FTP/HTTP サイトを 見つけることができなかったり、頭にくるような非標準的な形式しか 置いていないサイトしか見つけられないときには、 自分の管理下にあり信頼できる FTP サーバや HTTP サーバ (たとえば、あなた自身のホームページ) に置くこともできます。

そのような便利かつ信頼のおける置き場所が見つからない場合、 我々が `ftp.FreeBSD.org` に "置き場所"を提供することもできますが、 これはなるべく避けたい解決法です。 配布ファイルは、誰かの `freefall` アカウントの [.filename]#~/public_distfiles/# に置かれることでしょう。 その port をコミットする人に、置いてもらえるように頼んでください。 その人は配布ファイルを置いて、`MASTER_SITES` を `MASTER_SITE_LOCAL` にセットし、 `MASTER_SITE_SUBDIR` には 自分の `freefall` ユーザ名を 入れておいてくれるでしょう。

その port の配布ファイルが、 作者によるバージョン更新のようなことがなく変更されるなら、 その配布ファイルを あなたのホームページに置いて、`MASTER_SITES` の 最初に指定することも考えてみてください。できれば、その port の作者にそういうことをしないようにお願いしてみてください。 そのためには、何かしらのソースコード管理を行うと役に立つでしょう。 あなたが独自のバージョンを置けば、ユーザが `checksum mismatch` エラーに悩まされることもなくなりますし、FreeBSD の FTP サイトの 保守担当者の負担も減らすこともできます。 また、その port にマスターサイトが一つしか存在しない場合には、 あなたのサイトにバックアップを置き、 それを `MASTER_SITES` の 2 番目に 指定すると良いでしょう。

その port がインターネット上で入手できる追加パッチを 必要とするのなら、それも取ってきて `DISTDIR` に置いてください。 それらがメインのソースの tar ファイルとは別のサイトに あったとしても、心配する必要はありません。 そのような状況にも ちゃんと対応できるようになっています (後述の <<porting-patchfiles,PATCHFILES の記述>>を ご覧ください)。

[[slow-modifying]]
== port の修正

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

その port のコンパイルやインストールのために必要な手作業が あまりに多いようならば、Larry Wall の芸術的な Configure スクリプトを 参考にしたほうが良いかもしれません。 新しい ports collection は、エンドユーザにとって個々の port が 可能な限り"プラグ & プレイ"かつ 最小のディスク消費で make できることを目指しています。

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

[[slow-patch]]
== パッチの適用

port の準備段階で追加されたり変更されたりしたファイルは、 再帰的 man:diff[1] により後で man:patch[1] に与えられる形にすることができます。 パッチは適当にまとめて [.filename]#patch-*# という名前のファイルに入れてください。 [.filename]#*# はパッチが適用される順番を示します - これらは _アルファベット順_、 つまり `aa` が最初、 `ab` が その次といった順番で処理されます。 お望みなら、[.filename]#patch-Imakefile# とか [.filename]#patch-src-config.h# のように、 パッチ対象のファイルのパス名を示す名前を使うこともできます。 これらのファイルは `PATCHDIR` に置いてください。 そうすれば自動的に適用されるようになっています。 すべてのパッチは `WRKSRC` からの相対パスにするべきです (通常、`WRKSRC` は port の tar ファイルが展開されるディレクトリで、 make が実行されるところと同じです)。 修正やアップグレードを容易にするため、 複数のパッチで同じファイルを修正するのは避けてください (たとえば、[.filename]#patch-aa# と [.filename]#patch-ab# が共に [.filename]#WRKSRC/foobar.c# を修正するなど)。

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

man:diff[1] の再帰 (`-r`) フラグを使って再帰的なパッチを作るのは大変結構なのですが、 でき上がったパッチは必ず目でチェックして余計なゴミが入っていないことを確認してください。 よくあるのはバックアップファイル同士の変更点、あるいは `Imake` や GNU `configure` を使うソフトウェアの [.filename]#Makefile# の変更点が入っている場合などです。 また [.filename]#configure.in# を編集して `autoconf` を使って `configure` を作り直すときには、 `configure` の diff は含めずに (それらは良く数千行におよぶことがあります)、 `USE_AUTOCONF=yes` を定義して [.filename]#configure.in# の diff をとってください。

ファイルをまるごと消す場合には、 パッチを使わずに `post-extract` ターゲットで消す方が簡単です。 できあがった差分に満足したら、 それらをソースのファイルごとに別々のパッチファイルに分割してください。

[[slow-configure]]
== コンフィグレーション

カスタマイズのために追加したいコマンドがあれば、 [.filename]#configure# という名前のスクリプトに入れて [.filename]#scripts# サブディレクトリに置いてください。 上で述べたように、[.filename]#pre-configure# あるいは [.filename]#post-configure# という [.filename]#Makefile# ターゲットや、 スクリプトで処理することもできます。

[[slow-user-input]]
== ユーザからの入力の扱い

もし、その port がビルド、コンフィグレーション、または インストールの際にユーザからの入力を必要とするならば、 [.filename]#Makefile# 中で `IS_INTERACTIVE` を設定しなければなりません。 これにより、ユーザが環境変数 `BATCH` を セットしている場合には、この port の処理がスキップされるので "夜間の無人ビルド" が実行可能になります。 (逆に環境変数 `INTERACTIVE` がセットされていると、 ユーザからの入力を必要とする port __だけ__が コンパイルされます)。 これは、連続して ports をビルドするマシン群で、 無駄になる時間を大きく減らします。

もし、適切なデフォルト設定が存在するのであれば、 `PACKAGE_BUILDING` 変数をチェックして、 それが設定されている場合には ユーザ入力のスクリプトを起動しないようにしてください。 こうすることによって、我々 ports 管理者が CDROM や FTP に 置く package を作成することができます。 
