<!--
     The FreeBSD Documentation Project
     The FreeBSD Japanese Documentation Project

     Original revision: 1.23
     $FreeBSD$
-->

<chapter id="kernelopts">
  <chapterinfo>
    <authorgroup>
      <author>
	<firstname>J&ouml;rg</firstname>
	<surname>Wunsch</surname>
	<contrib>原作</contrib>
      </author>
    </authorgroup>
  </chapterinfo>

  <title>カーネルコンフィグレーションの
    新しいオプションを追加する</title>

  <para><emphasis>訳: &a.jp.yoshiaki;, 1996 年 12 月 29 日.</emphasis></para>

  <note>
    <para>この章をお読みになる前に <link
	linkend="kernelconfig">FreeBSD
	カーネルのコンフィグレーション</link> の章の内容を
      理解しておいてください.</para>
  </note>

  <sect1>
    <title>そもそも<emphasis>カーネル
	オプション</emphasis>って何?</title>

    <para>カーネルオプションの使い方は基本的には
      <link linkend="kernelconfig-options"> FreeBSD
	カーネルのコンフィグレーション </link>
      の章に書いてあります.
      そこには<quote>伝統的な形式</quote>と<quote>新しい形式</quote>のオプションの説明があります.
      すべてのカーネルのオプションを新しい形式のものに置き換え,
      コンフィグファイル
      を修正して &man.config.8; を実行した後に
      カーネルのコンパイルディレクトリで
      <command>make depend</command> を実行すれば,
      ビルドプロセスが自動的に変更された
      オプションを検出し, 必要なファイルだけを
      再コンパイルするようにすることが
      最終的な目的です. &man.config.8;
      を実行するたびに古いコンパイルディレクトリ
      を消してしまう現在のやりかたは,
      やがておこなわれなくなるでしょう.</para>

    <para>基本的に, カーネルオプションはカーネルのコンパイルプロセスの
      C プリプロセッサのマクロの定義にすぎません. 実際に選択的に make
      できる ようにするためには, 対応する部分のカーネルソース
      (またはカーネルの  <filename>.h</filename> ファイル)
      がオプションを使えるようにあらかじめ書かれていなければ
      なりません.
      つまりデフォルト値をコンフィグファイルのオプションで置き換え
      られるようになっていなければなりません.
      これは普通は次のようになっています.</para>

    <programlisting>#ifndef THIS_OPTION
#define THIS_OPTION (some_default_value)
#endif /* THIS_OPTION */</programlisting>

    <para>この場合,
      管理者がコンフィグファイルのオプションに別の値を記述すれば,
      デフォルトの設定を打ち消して新しい値に置き換えられます. 当然,
      新しい値はプリプロセッサによってソースコード中で
      置き換えられるため,  デフォルトの値が使われていた場所において C
      の式として有効な値でなければ なりません.</para>

    <para>また, 単に特定のコードを有効にするか
      無効にするかを設定するための
      値を持たないオプションも作ることができます.</para>

    <programlisting>#ifdef THAT_OPTION

[あなたのコードが入ります]

#endif</programlisting>

    <para>コンフィグファイルに <literal>THAT_OPTION</literal>
      と記述するだけで (値の有無 にかかわらず)
      対応する部分のコードが組み込まれます.</para>

    <para>C 言語にくわしい人であれば
      <quote>コンフィグオプション</quote>とされているもの
      は少なくとも一つの <literal>#ifdef</literal>
      で参照されているということはすぐに理解 できるでしょう. ところで,
      ごく一部の人たちは次のようなものを試して
      みようとするかもしれません.</para>

    <programlisting>options		notyet,notdef</programlisting>

    <para>このようにコンフィグファイルをしておくと,
      カーネルのコンパイルは うまく行きません.</para>

    <para>(訳注: たとえば MATH_EMULATE のように
      有効/無効のためのパラメータを 持たないオプションの場合,
      無効とするためのパラメータをつけて, オプション
      で「無効とする」と明示することはできないという意味です)</para>

    <para>明らかに,
      任意のオプション名がカーネルソースツリー全体でどのように
      使われているかを追いかけることは非常に難しいことです. このことが
      <emphasis>新しい形式</emphasis>
      のオプションの機構を採り入れる理由の背景です.
      ここではそれぞれのオプションは
      カーネルコンパイルディレクトリにある別々の
      <filename>.h</filename> ファイルとなり,
      <filename>opt_<replaceable>foo</replaceable>.h</filename>
      という名前に されます. この方法では, 通常の Makefile
      の依存関係が適用され,  <command>make</command>
      プログラムはオプションが変更された時に再コンパイルが必要な
      ものを見つけることができます.</para>

    <para>古い形式のオプションの機構は,
      局部的なオプションや実験的なオプション
      のような一時的に利用されると考えられるオプションにおいては
      有効です.  つまり <emphasis remap=tt>#ifdef</emphasis>
      をカーネルのソースに追加するのは簡単であり,
      それがそのままカーネルコンフィグオプションになります. この場合,
      管理者はオプションの利用において
      依存関係を把握しておく責任があります (また,
      手動でカーネルの一部分を
      強制的に再コンパイルする必要があるかもしれません).
      サポートされている
      オプションのすべてについて一つでも変更があると, &man.config.8;
      は サポートされていないオプションがコンフィグファイルの中に
      あるという警告 を出しますが, カーネルの Makefile
      内にはそれを含めます.</para>
  </sect1>

  <sect1>
    <title>ではどのようにして追加するのでしょう?</title>

    <para>最初に <filename>sys/conf/options</filename> (または
      <filename>sys/<replaceable>&lt;arch&gt;</replaceable>/conf/options.<replaceable>&lt;arch&gt;</replaceable></filename>, たとえば <filename>sys/i386/conf/options.i386</filename>)
      を編集し, 新しいオプション を含めるのに最適な
      <filename>opt_<replaceable>foo</replaceable>.h</filename>
      ファイルを選びます.</para>

    <para>新しいオプションの必要がなくなったとしたら,
      これを取り除きます. たとえば, SCSI
      サブシステムに関するすべてのふるまいについてのオプション
      の変更は <filename>opt_scsi.h</filename> に入れられます.
      デフォルトでは, 適切 なオプションファイルに単に記述されます.
      たとえば <literal>FOO</literal> であれば 値は対応するファイルの
      <filename>opt_foo.h</filename> に格納されます. これは右端に別
      のファイル名を書いて置き換えることができます.</para>

    <para>新しいオプションを加えるのに使えそうな
      <filename>opt_<replaceable>foo</replaceable>.h</filename>
      がない場合は新しい名前を作ってください.  意味のある名前を作り
      <filename>options[<replaceable>.&lt;arch&gt;</replaceable>]</filename>
      ファイル に新しいセクションのコメントをつけてください.
      &man.config.8; は自動的
      に変更を検出して, 次の実行からは (訳注: 新しい
      <filename>.h</filename>) ファイル を作ります.
      ほとんどのオプションはヘッダファイルに入れられます.</para>

    <para>大量のオプションを一つの
      <filename>opt_<replaceable>foo</replaceable>.h</filename>
      にまとめると
      コンフィグファイルの一つのオプションを変更したときに
      多くのファイルが 再コンパイルされる原因になります.</para>

    <para>新しいオプションに依存するカーネルファイルは
      最終的には見つけ出されます.
      ただし, オプションを作っただけで対応するソースがどこにもない場合は別です.
      <screen>&prompt.user; <userinput>find /usr/src/sys -type f | xargs fgrep NEW_OPTION</userinput></screen>
      オプションに対応するソースを見つけるのに上記のコマンドは便利です.
      見つけたすべてのファイルで編集, 追加をおこないます.

      <programlisting>#include "opt_foo.h"</programlisting>

      <emphasis>ファイルの先頭の</emphasis>, すべての
      <literal>#include &lt;xxx.h&gt;</literal> より前に入れます.
      この場合, オプションによって次のようにしてデフォルト値
      を持たせている標準のヘッダファイル内の値を置き換えるため,
      順番は非常に 重要です.

      <programlisting>#ifndef NEW_OPTION
#define NEW_OPTION (something)
#endif</programlisting>

      システムヘッダファイル (たとえば
      <filename>/usr/include/sys/</filename> にある ファイル)
      をオプションで置き換えることは, ほとんどの場合で失敗します.
      そうすると, ヘッダファイルを深刻な状態に破壊してしまうので,
      include  しないとオプションの値によって
      不整合が起きてしまう場合を除き, それらの ファイルに
      <filename>opt_<replaceable>foo</replaceable>.h</filename>
      を include しないでください.
      そう, 現在このような例がいくつか存在していますが,
      必ずしも正しい方法 ではありません.</para>
  </sect1>
</chapter>

<!--
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "part" "chapter")
     End:
-->