Node:Top, Next:, Previous:(dir), Up:(dir)

Version

Last updated October 19, 2001.

日本語版翻訳 矢吹洋一,引地美恵子,引地信之

日本語版最終更新日 2001年11月5日


Node:Preface, Next:, Previous:Top, Up:Top

GNU コーディング規約について

この GNU コーディング規約を書いたのは,リチャード・ストールマンとGNU プロジェクトのボランティアの人々です. この規約の目的は, GNU システムをきれいな, 矛盾のない, インストールが容易なものにすることにあります. この文書は, 移植性の良く頑丈で信頼性のあるプログラムを書くための手引としても読むことができます. 主に C 言語に焦点を置いていますが, この規約で述べている規則や原則は, 他の言語でプログラムを書く場合にも役に立つことが多いでしょう. 何故その規則を守るべきなのかという理由もなるべく付けるようにしました.

この GNU コーディング規約は, 2001年10月19日に最終更新しました.

読者がこのファイルを GNU プロジェクトから最近直接入手したのでなければ, もっと新しい版があるかどうか確かめてください. GNU Coding Standards は,GNU FTP ホストの /pub/gnu/standards/ からftp で入手可能です. GNU Coding Standards は色々なフォーマットで利用可能です. standards.info, standards.dvi に加えて、Texinfo の「ソース」も入手できます。ソースは、二つのファイル、standards.text, make-stds.texi に分かれています。また, GNU の WWW サーバ http://www.gnu.org/prep/standards_toc.html でも利用可能です.

この規約についての訂正や提案があれば, bug-standards@gnu.org 宛てに送ってください. なにか提案がある場合には, その提案に沿った文面そのものを送って貰えると, 時間の限られている我々にとっては助かります. 訂正すべき点を見つけたら,元の文面と訂正後の文面との差分を, standards.teximake-stds.texi の をコンテキスト形式 diff で送ってください.手元にこれらのファイルが見当たらなければ, 形式はともかく, 訂正案をメールしてください.

この規約は、GNU パッケージを書く際に重要なものの最小限をカバーしています。おそらく、追加の規約が必要になってくることでしょう。時々、読者はそのような規約をこの文書に追加することを提案してきます。読者の規約が一般にも有用であるなら、そのことを知らせて下さい。

読者は、ここでは扱われていなかったり、はっきり指定されていない多くの疑問について読者のパッケージ用の規約も設けるべきでしょう。最も重要な点は、首尾一貫していることです。読者の選んだ規約に焦点を絞り、可能な限り説明するようにしてください。そうすることで、読者のプログラムを他の人が保守することが容易になるのです。

日本語版の最終更新は 2001年11月5日 です. 日本語翻訳版についての問い合わせは yabuki@sra.co.jp 宛てにお願いします.


Node:Legal Issues, Next:, Previous:Preface, Up:Top

フリーソフトウェアをフリーに保つには

この {No value for `CHAPTER'} では, GNU ソフトウェアで法律的な問題や,その他関係する問題を回避するにはどうしたら良いかを議論します.


Node:Reading Non-Free Code, Next:, Previous:Legal Issues, Up:Legal Issues

排他的権利を持つプログラムの参照

GNU ソフトウェアに関係する作業をしている間は, Unix のソースコード(あるいは他の排他的権利を有するプログラム)を見ないように努めてください.

とはいっても,なにかの Unix プログラムの内部を見たことがあり, それをぼんやりとでも憶えていたからといって,そのプログラムの別バージョンを書くのはいけないかというと,そんなことはないので安心してください. ただし, そういうプログラムを書く機会があるなら, 元のプログラムとは異なった方針で内部仕様を設計してください. そうすれば元の Unix 版のプログラムとは細かな点では無関係で似ていないものになります.

内部構造を Unix 版のプログラムと違うものにするためにはどうすれば良いか, 少し考えてみましょう.例えば, Unix のコマンドはメモリ使用量が少なくなるような作りのものが多いのですが, 代わりに速度を重視するようにすれば,かなり違ったプログラムになるはずです. ファイルを全部メモリ中に取り込めば, 標準入出力ライブラリを使わずともファイルの中身を走査することもできます. Unix のプログラムで使われているアルゴリズムよりも新しくて賢いアルゴリズムがあればそっちを使いましょう. 一時ファイルを使わないようにしましょう. 2パスはやめ, (GNU アセンブラのように)1パスにしましょう.

あるいは逆に, 速度よりも単純さを重視することも考えられます. 最近の計算機は速くなってきているので, アプリケーションによっては単純なアルゴリズムの方が適している場合もあります.

あるいは一般性を追及しましょう. Unix のプログラムでは静的な配列や固定長の文字列をよく使っていますが, こういう制限は困りものです. 代わりにメモリを動的に獲得するようにしましょう. 自分のプログラムが入力ファイル中の NUL 文字やその他の制御文字等をきちんと扱えるかどうか確かめてみてください. 拡張性を持たせるには, 拡張機能を記述するためのプログラミング言語を作って, プログラムの一部をその言語で書いてください.

あるいは, プログラムの一部を,独立に使えるライブラリに転用しましょう. また, いつメモリを解放すべきかを正確に追跡するのはやめて, 代わりに単純なガベージコレクタを使うか, obstack のような GNU の新しい機能を使いましょう.


Node:Contributions, Next:, Previous:Reading Non-Free Code, Up:Legal Issues

寄贈の受取

読者が作業中のプログラムの著作権が Free Software Foundation にあるものなら, そのプログラムに追加できるようなコードを誰かが送ってきたとしても, 我々がそれを使うには法的な文書が必要です. この文書は, 我々が最初に読者に要求したものと同様の文書です. プログラムの所有権をはっきりさせるため, プログラムに簡単ではない貢献をした人全員が文書にサインしなければなりません. 主となる著者のサインだけでは不十分です.

そういう理由があるので, 他人から寄贈されたコードを自分のコードに加えるまえに知らせてくれれば文書の準備をします. そして, 我々がサイン入りの文書を受けとったという連絡があるまで, 実際に寄贈された部分を使うのは待ってください.

このことは, プログラムをリリースする前, それにリリース以後についても適用されます. バグを修正した差分を受けとって,そのために重要な変更が生じたときも法的な文書が必要です.

これは, コメントやドキュメントのファイルについても当てはまります. 著作権法の観点からみれば, コメントもコードも単なるテキストです. 著作権はあらゆる種類のテキストに適用されますので, 我々もあらゆる種類のテキストについて書類が必要なのです.

法的な文書が必要だなんて煩わしいことなのはわかっています. 我々にとっても煩わしいことなのです. しかし, 法的文書を待たないと孤立無援になります. 例えば,寄与者の雇主が権利放棄書にサインしなかったらどうなるでしょうか? そのコードを再び取り除かなければならなくなるでしょう.

ほんの数行程度の変更なら文書の必要はありません. 著作権の意図するところにとっては, 重要でないからです. また, 受け取ったものが実際に使えるコードではなく, 何かのアイデアである場合も文書はいりません. 例えば, 誰かが読者に何かの実装を送ってきたものの, 読者が同じアイデアをそれとは別に実装した場合もはまります.

一番まずいのは, 他にも寄与者がいることを忘れ, 我々に知らせないことです. その結果として,いつか,我々は法廷において非常に困った事態にあうかもしれません.

プログラムの保守担当者にはもっと細かいアドバイスがあります. もし, GNU のプログラムを実際に保守する段階に達したら(それがリリースされるかどうかは別です), 我々に覚書のコピーを要求してください.


Node:Trademarks, Previous:Contributions, Up:Legal Issues

商標

GNU ソフトウェアのパッケージや文書で商標についての謝辞は一切含めないでください.

商標の謝辞とはこれこれはなになにの商標であるという形の文です. GNU プロジェクトは商標の基本的な考え方に異義はないが,しかしこういう謝辞はいたずらにへつらっているようであり,我々は使用しない.こういうものについて法律的な要請はないのである.

他人の商標について法的に要求されているのは,読んだ人が, 我々自身のプログラムや活動に名前を付けたり,ラベルを貼ったりしていると思わせるような使い方をしないということである. 例えば,"Objective C" というのは商標なので(あるいは,少なくとも昔は商標であったので),我々は「Objective C コンパイラ」ではなく「Objectvie C 言語用コンパイラ」を提供しているというように気をつけていた.前者は後者の短縮形であるが,関係を明示的に述べていないので, "Objecvitve C" を言語を表すものでなく,コンパイラにラベルを貼るものとして使っていると誤解される可能性があったのである.


Node:Design Advice, Next:, Previous:Legal Issues, Up:Top

プログラムの設計について

この{No value for `CHAPTER'}では, プログラムを設計する際に考慮すべき点について幾つか議論します.


Node:Source Language, Next:, Previous:Design Advice, Up:Design Advice

言語は何を使うべきか

コンパイル言語で高速に実行される言語を使いたいのなら,一番良いのはC 言語を使うことです. 他の言語を使うのは標準外の機能を使うようなものです. ユーザにとってはトラブルの元です. もし, GCC が C 以外の言語をサポートしていたとしても, プログラムを構築するには, その言語用に GCC をインストールしなければならないとしたら, 面倒だと感じるでしょう. 例えば, 読者が C++ でプログラムを書いたとすると, 他の人はそれをコンパイルするためには GNU C++ コンパイラをインストールしなくてはなりません.

C++ やその他のコンパイル言語に比べて C には一つ有利な点があります. C を知っている人の方が多いので, C で書かれたプログラムを読んだり修正したりするのが簡単にできる人の方が多いということになります.

このため,他の候補となる言語よりも C を使った方が一般にはずっと良いのです.

ただし,例外が二つあります.

拡張性を持つように設計されているプログラムはたくさんある. そういうプログラムは C 言語よりも高級な言語のインタプリタを内蔵している.そのプログラム自体もその言語で書かれていることも多い. Emacs エディタがこの技法の先駆けとなった.

GNU ソフトウェアの標準の拡張用インタプリタは GUILE である.GUILE はScheme 言語の実装である(Scheme は Lisp の非常にきれいで簡潔な方言である). http://www.gnu.org/software/guile/. われわれは他の「スクリプト言語」例えば Perl や Python で書かれたプログラムを拒絶することはないが, GUILE を使うことは GNU システム全体の一貫性のためには非常に重要である.


Node:Compatibility, Next:, Previous:Source Language, Up:Design Advice

他の実装との互換性

特別な例外を除いて, GNU のユーティリティプログラムとライブラリはバークレー版 Unix のものと上位互換性がなければなりません. また, 標準 C で仕様が規定されているものについては 標準 C との上位互換性が, また, POSIX で仕様が規定されているものについては POSIXとの上位互換性がなければなりません.

これらの標準の間で相反するものがあるなら, 標準ごとに互換モードを提供するのが良いでしょう.

標準 C や POSIX が拡張を禁じている事項はいろいろありますが, とりあえず, あまり気にせず拡張しておいて, --ansi--posix, --compatible などのオプションを指定すると拡張機能が動作しないようにしましょう. しかし, そういう拡張によって, 既存のプログラムやスクリプトが動かなくなる可能性があるなら, それは本当の上位互換とは言えません. 上位互換性を持つようにインターフェースを再設計すべきでしょう.

GNU のプログラムの多くは,環境変数 POSIXLY_CORRECT が定義されていれば(その値がヌルでも), POSIX 規格に反する拡張機能を抑止します. 自作のプログラムにそのような拡張機能があるなら, 是非, この環境変数を認識するようにしてください.

(プログラムやコマンドファイルの中から使われることが無く)ユーザだけが直接その機能を使っているような機能で, しかも Unix で対応するものは機能が貧弱である, という場合には, 全く異なったより良いものに気楽に置き換えてしまいましょう. (たとえば, vi は Emacs に置き換えられます.)しかし, 互換性のある機能を提供することも同様に歓迎します. (フリーの vi クローンがあり, 我々はそれを提供しています.)

新たな有用な機能は,それに先行するものがあるかどうかに関わらず歓迎します.


Node:Using Extensions, Next:, Previous:Compatibility, Up:Design Advice

標準以外の機能を使うには

既に存在する多くの GNU の機能は, 類似のUnix の機能と比べて便利な拡張を多くサポートしています. 読者が自分のプログラムを実装するときに, これらの拡張を使うかどうかは難しい問題です.

ある面でいうと,拡張機能を使うとプログラムがきれいに書けます. その一方で, 他の GNU ツールがないとプログラムを構築できなくなり, プログラムが動く計算機が少なくなってしまうという事態を引き起こします.

拡張機能によっては, 両方の選択肢を提供するのが容易な場合もあるでしょう. たとえばキーワード INLINE をつけて関数を定義しておき, INLINEは,コンパイラによって inline または空に展開されるマクロとして定義しておくことができます.

一般的に, 拡張機能を使わずとも素直に書くことができるなら, それが一番良いでしょう. しかし, 拡張機能を使うことによって得られる改善が非常に大きいものであればどんどん使いましょう.

プログラムが大きくて完成されたものであり,いろんな種類の計算機で動いているものなら( Emacs のように)それはこの規則の例外です. このようなプログラムはGNU の拡張を使うと多くのユーザを不幸に陥れることになるので,我々は使わないようにしています.

コンパイル過程の一部として使われるプログラム, つまり GNU のコンパイル機能をブートストラップするために, 他のコンパイラでコンパイルする必要のあるプログラムも例外です. もしそれらが GNU コンパイラを必要とするようなら, GNU コンパイラをインストールする前には, 誰もそのプログラムをコンパイルできません. これはある場合に非常に問題になります.


Node:Standard C, Next:, Previous:Using Extensions, Up:Design Advice

標準 C と 標準以前の C

標準 C 1989 は今や充分普及しているので,新しいプログラムでその機能を使っても問題はありません. ただし,ひとつだけ例外があります. 標準 C のトリグラフの機能は絶対使わないようにしましょう.

標準 C 1999 はまだ広まっていないので,プログラムの中でこの標準の機能を使わないようにしてください.既にある機能を使うのはかまいません.

とは言っても,大体のプログラムでは標準以前のコンパイラをサポートするのは簡単な事が多いので, やり方を知っているならサポートしても良いでしょう. もし読者が保守しているプログラムが非 ANSI コンパイラをサポートしているなら, それが動作するように維持してください.

標準以前の C をサポートするには, 関数の定義を書く場合に, 標準のプロトタイプ形式

int
foo (int x, int y)
...

の代わりに, 次のように標準以前の形式で書きましょう.

int
foo (x, y)
     int x, y;
...

そして, これとは別に宣言を書いて引数のプロトタイプを指定します.

int foo (int, int);

いずれにせよ,このようなプロトタイプ宣言は必要で,ヘッダファイルに宣言を入れておけば,その関数を呼び出している全てのファイルでプロトタイプの御利益が得られます. そして, 一度宣言を書いておけば, 関数の定義を標準以前の形式で書いても失うものは何もありません.

この方法は, int よりも小さい整数型には使えません. ある引数の型を int よりも小さい型にしたいと思ったら, 変わりに int として宣言しましょう.

この方法を使うのが難しいような, 特別な場合が幾つかあります. 例えば, ある関数の引数がシステムで定義されている型 dev_t を保持する必要がある場合問題になります.なぜなら, 機種によっては dev_t 型がint よりも小さい場合があるからです. しかし, 代わりに int を使うことはできません. dev_tint よりも大きいような機種があるからです. 非標準の定義では, 全ての機種で安全に使える型は存在しないのです. 非標準 C をサポートしつつ, かつこういう引数を渡す方法としては, Autoconf を使って dev_t の幅を検査し, 適切な引数の型を選択するようにするしかないでしょう. これは問題ではありません.

プロトタイプを認識しない標準以前のコンパイラをサポートするには, 以下のようなプリプロセッサマクロを使うと良いでしょう.

/* Declare the prototype for a general external function.  */
#if defined (__STDC__) || defined (WINDOWSNT)
#define P_(proto) proto
#else
#define P_(proto) ()
#endif


Node:Conditional Compilation, Previous:Standard C, Up:Design Advice

条件付コンパイル

読者が自分のプログラムを作成する際、既知のコンフィギュレーションオプションに対応するのであれば、#ifdef による条件付コンパイルよりもif (... ) を使用してください。後者の方が、可能なコード経路の全てについて、より綿密な検査を実行できるからです。

例えば、

  if (HAS_FOO)
    ...
  else
    ...

と書く方が、

  #ifdef HAS_FOO
    ...
  #else
    ...
  #endif

より好ましいでしょう。

GCC などの現代的コンパイラであれば、どちらの場合も全く同じコードを生成します。どうようの手法を使って、たくさんのプロジェクトで成功を収めています。

すべての移植性にまつわる問題を解決する「銀の弾丸」ではありませんが、この方針に従うことで、GCC プロジェクトだけでも、人日や人年の単位ではありませんが、多くの人時を浪費せずに済んでいます。

GCC のソースコードにある REVERSIBLE_CC_MODE のような関数形式のマクロの場合には、単純には if( ...) 文で使うことはできませんが、簡単な回避方法があります。以下の例のように、もう一つ別のマクロ HAS_REVERSIBLE_CC_MODE を使います。

  #ifdef REVERSIBLE_CC_MODE
  #define HAS_REVERSIBLE_CC_MODE 1
  #else
  #define HAS_REVERSIBLE_CC_MODE 0
  #endif


Node:Program Behavior, Next:, Previous:Design Advice, Up:Top

あらゆるプログラムの振るまい

この{No value for `CHAPTER'}では,頑丈なソフトウェアを書くための約束について説明します.また,エラーメッセージの書き方, コマンド行インターフェース,ライブラリの動作についても標準的な方法を解説します.


Node:Semantics, Next:, Previous:Program Behavior, Up:Program Behavior

頑丈なプログラムを書くには

ファイル名, 行, ファイル, シンボル等のどんなデータ構造にも, 長さや個数について勝手な制限は設けてはいけません. データ構造用のメモリは動的に確保しましょう. Unix ユーティリティは「長い行はだまって切る」ものがほとんどですが, GNU のユーティリティではこれは容認できません.

ファイルを読むユーティリティは, NUL 文字,あるいは0177 以上のコードを含む非印字文字を読み落してはなりません. 唯一の意味のある例外は, これらの文字を扱えないある種のプリンタへのインタフェースのためのユーティリティに限られるでしょう. 可能な限り, マルチバイト文字を表現するバイト列に対しても, UTF-8 等のエンコーディングを使って, プログラムが正しく動作するようにしましょう.

わざとエラーを無視したい時以外は, システムコールがエラーを返しているかどうかを必ずチェックしましょう. システムコールの失敗によるすべてのエラーメッセージには, ( perror あるいはそれと同等のものから得られる)システムのエラーメッセージ文とファイル名,ユーティリティ名を入れましょう. "cannot open foo.c" や "stat failed" だけでは十分ではありません.

mallocrealloc を呼ぶときは戻り値がゼロでないか必ずチェックしましょう. 要求するメモリブロックの大きさの指定を小さくして reallocを呼ぶときもチェックが必要です. メモリブロックの大きさを2の累乗に切り上げるシステムでは, reallocに指定するメモリブロックの大きさを小さくして呼び出すと, 異なるメモリブロックが得られることがあります.

通常の Unix の realloc がゼロを返したときは, メモリ領域を壊している可能性があります. GNU reallocにはこの問題はなく, 失敗した場合も,もとのブロックを変更しません. この問題は存在しないと考えて良いでしょう. Unix でプログラムを動かすときに,この問題を避けたいのならGNU malloc を使えば良いのです.

free は解放された後のブロックの内容を変更してしまうと考えなければなりません. そのブロックから何か取りだしたいなら freeを呼び出す前にしましょう.

非対話的なプログラムで malloc に失敗した場合には, 致命的エラーとしましょう.ユーザからのコマンドを読み込むような, 対話的なプログラムの場合には, 実行中のコマンドを中断して, プログラムのコマンド読み込みのループ部に制御を戻したほうが良いでしょう. こうすれば, 他のプロセスを殺すなどして仮想メモリを空けて, そのコマンドの再実行を試みることができます.

引数のシンタックスに合わない場合以外は, 引数を解析するには getopt_long を使いましょう.

プログラム実行中に書き込みが行われる静的記憶領域は,(宣言ではなく)Cコード中で明示的に初期化します. Cの初期化宣言は読みだし専用データにだけ使いましょう.

不透明な Unix のデータ構造(ディレクトリ, utmp,カーネルメモリのレイアウトなど )に対する低レベルインタフェースの使用は避けましょう. それらは互換性があまりないからです. あるディレクトリ内の全てのファイルを見つけたかったらreaddir やその他の高レベルのインタフェースを使いましょう. これらは GNU により互換性がサポートされています.

シグナル操作機能として好ましいのは BSD 版の signalPOSIXsigaction 関数です. USG の signal インターフェースは設計が劣ります.

今や, POSIX のシグナル関数を使うのがプログラムをポータブルにする一番簡単な方法でしょう. signal を使うなら, GNU/Linux で GNU libc バージョン 1 の場合は, signal.h の代わりに bsd/signal.h を使うようにして, BSD の動作になるようにする必要があります. signal の動作が USG のものしかないシステムをサポートするか, あるいはあきらめるかは読者にお任せします.

エラーチェックで”起こりえない”条件を検知したら,単に中断しましょう. 通常,何かのメッセージを出力することには,意味がありません. これらのエラーチェックはバグの存在を示すものです.バグを修正したい人はソースコードを読みデバッガを走らせないといけません.ですから,ソース内のコメントで問題について説明してください.関係のあるデータは変数の中にあるでしょうから,デバッガを用いて簡単に検査できるので,それらをどこかよそへ移す事には意味がありません.

エラーの回数をプログラムの終了ステータスとしてはいけません. そうしても思った通りにいきません.終了ステータスは 8 ビットの値, つまり 0 〜 255 に限られるからです.プログラムを一回実行させただけで, 256 回エラーが発生する可能性があります. 256 を終了ステータスとして返そうとしても,親プロセスには 0 が返されてしまいます.そうすると, そのプログラムはエラー無しで無事終了したものと見なされます.

一時ファイルを作成する場合は,まず環境変数 TMPDIR が定義されているかどうかを調べる必要があります.定義されている場合には, /tmp の代わりに, TMPDIR で指定されたディレクトリを使いましょう.

さらに,誰でも書き込み可能なディレクトリに一時ファイルを作成することについてはセキュリティ上の問題が発生する可能性に注意すべきでしょう. C 言語では,以下のような方法で一時ファイルを作成することでこの問題を回避することができます.

fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600);

あるいは,libiberty ライブラリの mkstemps 関数を使うこともできます.

bash では,set -C とするとこの問題を回避できます.


Node:Libraries, Next:, Previous:Semantics, Up:Program Behavior

ライブラリ関数

ライブラリ関数はリエントラントになるよう努めてください. 関数が動的なメモリ獲得を必要としているならば,すくなくともmalloc 自身の非リエントラント性以外の非リエントラント性を避けるようにしましょう.

ライブラリの名前づけには,名前の衝突を避けるための規約があります.

ライブラリ用に2文字以上のプリフィックス名を選んでください. 外部関数と外部変数名は全てこのプリフィックスで始めるようにします. さらに,これらの名前はどのライブラリのメンバ(...o ファイル)にもそれぞれ一個だけしか現れないようにすべきです. これは通常,それぞれの名前をそれぞれ別々のソースファイルに置くという意味です.

2つの外部シンボルがいつも一緒に使われ,片方をもう一方なしには使えないようなプログラムは例外です. それらは両方とも同じファイルに入れます.

ユーザからエントリポイントとして見えてはいけない外部シンボルは, _で始まる名前にしなければなりません. _ の後にそのライブラリ用に選んだ名前のプリフィックスを続けるようにして、他のライブラリとの衝突を避ける必要があります。こうしておけば,ユーザに見せて良いエントリポイントがあるファイルと同じファイルにいれておくことも可能です.

静的関数と静的変数は好きなように使って良いし, 特に名前付けの規約にも従う必要もありません.


Node:Errors, Next:, Previous:Libraries, Up:Program Behavior

エラーメッセージの形式

コンパイラの出すエラーメッセージは次の形式にします.

ソースファイル名:行番号: メッセージ

カラム番号を表示したい場合は次の形式を使います.

ソースファイル名:行番号:カラム: メッセージ

行番号はファイルの先頭が 1 になるように始め, カラム番号は行頭で 1 になるように始めます. (この規約は互換性のために選ばれました. ) カラム番号を計算する際には, スペースと ASCII の印字可能文字は全て同じ幅を持ち, タブ・ストップは 8 カラム毎であるとしましょう.

コンパイラ以外の対話的でないプログラムの出すエラーメッセージは次の形式にします.

プログラム:ソースファイル名:行番号: メッセージ

これは該当するソースファイルがある場合です. 関係するソースファイルがない場合は次のように書きます.

プログラム: メッセージ

カラム番号を表示したい場合は以下の形式を使います.

プログラム:ソースファイル名:行番号:カラム: メッセージ

対話的なプログラム(端末からコマンドを読むようなもの)においてはエラーメッセージ中にプログラム名を入れないほうがいいでしょう.どのプログラムが動いているかは,プロンプトあるいはスクリーンレイアウトにより示されています. (同じプログラムが端末以外のファイルから入力を読む場合,それは対話的ではありませんから,非対話的な形式でエラーメッセージを印字するのが最良です.)

メッセージの文字列がプログラム名とファイル名の後に続くときは, 大文字で始めてはいけません. また, ピリオドで終わってはいけません.

対話的なプログラムのエラーメッセージや使用法のメッセージは, 大文字で始めます.しかし,ピリオドで終ってはいけません.


Node:User Interfaces, Next:, Previous:Errors, Up:Program Behavior

一般的なインターフェースの規約

起動されるときのコマンド名によって, そのユーティリティ・コマンドの振る舞いを変えるのはやめてください. ユーティリティを違う名前にリンクすると便利なことがあり, その場合でも振る舞いが変わらないようにすべきです.

その代わりに起動時のオプション,あるいはコンパイル時のスイッチ,あるいはその両方で振る舞いを選択できるようにします.

同様に, プログラムの振る舞いを出力先デバイスのタイプによって変えるのはやめてください. デバイスに依存しないことはシステムの設計の重要な原則です. 単に, 誰かがたまにオプションを入力しなくても済むようにするために妥協するのはやめてください. (端末を使っているときにエラー・メッセージの構文を変えるのは構いません. 人々がそのことに依存するようなことのない, 副次的な問題だからです. )

出力先が端末の場合に適した動作と, それとは別に, 出力先がファイルやパイプの場合に適した動作があるなら, デフォルトは端末向けの動作とし, もう一方の動作は何かオプションを指定したときに実行されるようにするのが良いでしょう.

互換性のために, ある種のプログラムでは出力先のデバイスに依存することが要求される場合もあります. (出力デバイスに依存するプログラムの代表例である) lssh が, 全てのユーザの期待する通りに動かなかったら, 一大事でしょう. そのような場合には, 我々は, 出力先デバイスに依存しない好ましい別のバージョンのプログラムで補います. 例えば, 我々は dir という, ls とほとんど同じプログラムを提供していますが, デフォルトの出力フォーマットは, 常にマルチカラムのフォーマットにしています.


Node:Graphical Interfaces, Next:, Previous:User Interfaces, Up:Program Behavior

グラフィカルインターフェースの標準

グラフィカルユーザインターフェースを提供するプログラムを書く場合は, 機能的に何か別のものを必要とする(例えば,「コンソールモードでJPEG のイメージを表示する」など)のでない限り,X Windows と GTK ツールキットで動作するようにして欲しい.

さらに,その機能を制御するコマンド行インターフェースも提供して欲しい. (多くの場合,グラフィカルユーザインターフェースは,コマンド行プログラムを起動する独立したプログラムとすることが可能である.) これは,同じ作業をスクリプトからでも行なえるようにするためである.

また,CORBA インターフェース(GNOME から使うため),ライブラリインターフェース(C 言語から使うため),キーボード入力駆動とするコンソールインターフェース(コンソールモードからユーザが使うため)を提供することも検討して欲しい.一度,機能そのものとグラフィカルユーザインターフェスが動くようになれば,これらはそれほど大変な作業ではない.


Node:Command-Line Interfaces, Next:, Previous:Graphical Interfaces, Up:Program Behavior

コマンド行インターフェースの規約

プログラムのコマンド行オプションは, posix ガイドラインに従うのが良いでしょう.そのためにはオプションの解析時にgetoptを使うのが最も簡単です. GNU 版の getopt では, 特殊な引数--を指定しない限り, 引数の中のどこにオプションがあっても良いことにしています. これは posix の仕様ではありません. GNU の拡張です.

Unix風の1文字オプションと同値のオプションを長い名前で定義してください. このようにGNU はもっと親切になりたいと望んでいます. GNU の関数getopt_long を使えば簡単です.

長い名前のオプションの利点の一つに,プログラム間で一貫性を保てることがあります. 例えば,"verbose" オプションを持つ GNU プログラムではいつでも, そのオプションは --verbose と綴られるとユーザが期待しても良いようにすべきです. このような一貫性を達成するためには, 自分のプログラムのオプション名を選択するときに,共通の長いオプション名の表があるので,見てください (see Option Table).

普通の引数で与えられるファイル名は入力ファイルに限る, というのは良い考えです. 出力ファイルはオプション( なるべく -o--output)であたえれば良いのです. 互換性のため,出力ファイル名も通常の引数で与えられるようにしたいと思った時は, 別の方法で指定するためのオプションも同様に提供しましょう. そうすれば GNU のユーティリティ間の一貫性が保たれ,ユーザが特別に覚えなければならないことが少なくなるからです.

すべてのプログラムは, --version--help の二つの標準オプションをサポートしなければなりません.

--version
このオプションは, 名前, バージョン, 出所, 著作権等のプログラムについての情報を標準出力に表示し, プログラムを正常終了させます. このオプションが指定された場合は, 他のオプションや引数は無視し, それらの引数が指定された場合の通常の動作を行わないようにする必要があります.

プログラム情報の一行目は他のプログラムがパースしやすいようにしてください. バージョン番号自体は, 一行目の最後の空白の後に書きます. さらに, 次のような形式で, プログラムの正式な名前を書きます.

GNU Emacs 19.30

プログラム名は文字列定数にしてください. argv[0] から求めてはいけません. というのは, プログラムのファイル名ではなく, 正式な名前を表示するのが目的だからです. コマンドが PATH にあるものなら, 正確なファイル名を知る方法は別にあります.

プログラムがより大きなパッケージの補助的なものなら, 以下のように, パッケージ名を括弧の中に示します.

emacsserver (GNU Emacs) 19.30

パッケージのバージョン番号とプログラムのバージョン番号が違っている場合には, 閉じ括弧の前にパッケージのバージョン番号を入れましょう.

プログラムが入っているパッケージとは別に配布されているライブラリのバージョン番号についても表示する必要があるばあいは, ライブラリ毎にバージョン情報を一行ずつ追加表示しましょう. 追加する行は一行目と同じ形式を使ってください.

完全性を追及するためだけの理由で, プログラムが使う全ライブラリについて言及するのは避けてください. 役に立たない情報であふれるだけです. デバッグのために非常に重要だと判っているものだけについて, バージョンを表示するようにしてください.

バージョン表示の後には, 著作権表示を出力します. 著作権表示が複数ある場合は, 一行に一つずつ表示します.

その次には, プログラムがフリーソフトウェアであること, ある条件の元でコピーや変更を行って良いことを簡単に説明します. プログラムが GNU GPL でカバーされるものなら, この部分にその旨を宣言します. また, 法律で許される範囲で, 無保証であることも述べます.

最後に, プログラムの主要な著者名を挙げて, クレジットの表示としても良いでしょう.

以上の規則に則った例を以下にしめします.

GNU Emacs 19.34.5
Copyright (C) 1996 Free Software Foundation, Inc.
GNU Emacs comes with NO WARRANTY,
to the extent permitted by law.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters,
see the files named COPYING.

もちろん, 自分のプログラムに合わせて変更すべき部分があります. 年, 著作権保持者, プログラム名, 配布条件への参照を埋め, 他の部分も必要に応じて変更してください.

著作権表示に示す年は, 最後に変更があった年を示すだけでかまいません. それ以前の変更を行った年を表示する必要はありません. 面倒なら, 著作権表示中にプログラム名を示す必要はありません. 既に一行目に示しています.

以上の行の翻訳は、著作権表示の有効性を保持しなければなりませんsee Internationalization)。翻訳に使用する文字セットが対応しているなら、(C) は、以下のように、著作権記号で置き換える必要があります。

©

"Copyright"という語は、そのまま英語で書いて下さい。これを他の言語に翻訳しては行けません。国際条約は、英単語 "Copyright"を認識しますが、他の言語に翻訳したものは法的な意味を持ちません。

--help
このオプションは, プログラムの起動方法の簡単な説明を標準出力に表示し, プログラムを正常終了させます. このオプションが指定された場合は, 他のオプションや引数は無視し, それらの引数が指定された場合の通常の動作を行わないようにする必要があります.

オプション --help の出力の最後に,バグレポートの送り先のメールアドレスを書いた行を一行含めてください. 以下の形式で書いてください.

Report bugs to mailing-address.


Node:Option Table, Next:, Previous:Command-Line Interfaces, Up:Program Behavior

長いオプションの表

次の表は,GNU プログラムで使われている長い名前のオプションの一覧です. まだ不完全なものですが, 我々は新しいプログラムと互換性のあるオプションをすべて列挙することを目指しています. この表にまだ入っていない名前を使ったら, 意味を書いたリストをbug-standards@gnu.org に送ってくれれば, われわれはこの表を更新します.

after-date
tar-N .
all
du, ls, nm, stty, uname, unexpand-a .
all-text
diff-a .
almost-all
ls-A.
append
etags, tee, time-a, tar-r.
archive
cp-a .
archive-name
shar-n .
arglength
m4-l .
ascii
diff-a .
assign
gawk-v .
assume-new
Make の -W.
assume-old
Make の -o .
auto-check
recode-a .
auto-pager
wdiff-a .
auto-reference
ptx-A .
avoid-wraps
wdiff-n .
background
サーバプログラムをバックグランドで走らせる.
backward-search
ctags-B .
basename
shar-f .
batch
GDB で使用.
baud
GDB で使用.
before
tac-b .
binary
cpiodiff-b .
bits-per-code
shar-b .
block-size
shar-b .
block-size
cpiotar で使用.
blocks
headtail-b .
break-file
ptx-b .
brief
色々なプログラムで出力を短くするために使われている.
bytes
head, split, tail-c .
c++
etags-C .
catenate
tar-A .
cd
色々なプログラムで,使用するディレクトリを指定するために使われている.
changes
chgrpchown-c .
classify
ls-F .
colons
recode-c .
command
su-c, GDB の -x .
compare
tar-d .
compat
gawk で使用.
compress
tarshar-Z .
concatenate
tar-A .
confirmation
tar-w .
context
diff で使用.
copyleft
gawk-W copyleft .
copyright
ptx, recode, wdiff-C, gawk-W copyright.
core
GDB で使用.
count
who-q .
count-links
du-l .
create
tarcpio で使用.
cut-mark
shar-c .
cxref
ctags-x .
date
touch-d .
debug
Make と m4-d, Bison の -t .
define
m4-D .
defines
Bison と ctags-d .
delete
tar-D .
dereference
chgrp, chown, cpio, du, ls, tar-L .
dereference-args
du-D .
device
入出力装置(特殊ファイル名)を指定する.
diacritics
recode-d .
dictionary-order
look-d .
diff
tar-d .
digits
csplit-n .
directory
色々なプログラムで, 使用するディレクトリを指定する. ls では, 中身ではなくディレクトリ自身を表示することを意味する. rmln では, ディレクトリへのリンクを特別扱いしないようにする.
discard-all
strip-x .
discard-locals
strip-X .
dry-run
Make の -n .
ed
diff-e .
elide-empty-files
csplit-z .
end-delete
wdiff-x.
end-insert
wdiff-z.
entire-new-file
diff-N .
environment-overrides
Make の -e .
eof
xargs-e .
epoch
GDB で使用.
error-limit
makeinfo で使用.
error-output
m4-o .
escape
ls-b .
exclude-from
tar-X .
exec
GDB で使用.
exit
xargs-x .
exit-0
unshar-e .
expand-tabs
diff-t .
expression
sed-e .
extern-only
nm-g .
extract
cpio-i, tar-x .
faces
finger-f .
fast
su-f .
fatal-warnings
m4-E .
file
info, gawk, Make, mt, tar-f, sed-n, touch-r .
field-separator
gawk-F .
file-prefix
Bison の -b .
file-type
ls-F .
files-from
tar-T .
fill-column
makeinfo で使用.
flag-truncation
ptx-F .
fixed-output-files
Bison の -y .
follow
tail-f .
footnote-style
makeinfo で使用.
force
cp, ln, mv, rm-f .
force-prefix
shar-F .
foreground
サーバプログラムをフォアグラウンドで走らせる. 言い換えると, サーバをバックグランドで走らせるときに行なう特別な事は何もやらない.
format
ls, time, ptx で使用.
freeze-state
m4-F.
fullname
GDB で使用.
gap-size
ptx-g .
get
tar-x .
graphic
ul-i .
graphics
recode-i .
group
install-g .
gzip
tarshar-z .
hashsize
m4-H .
header
objdumprecode-h .
heading
who-H .
help
簡単な使用法を求めるのに使用.
here-delimiter
shar-d .
hide-control-chars
ls-q .
html
makeinfo で,HTML を出力する.
idle
who-u .
ifdef
diff-D .
ignore
ls-I, recode-x .
ignore-all-space
diff-w .
ignore-backups
ls-B .
ignore-blank-lines
diff-B .
ignore-case
lookptx-f, diffwdiff-i .
ignore-errors
Make の -i .
ignore-file
ptx-i .
ignore-indentation
etags-I .
ignore-init-file
Oleo の -f.
ignore-interrupts
tee-i .
ignore-matching-lines
diff-I .
ignore-space-change
diff-b .
ignore-zeros
tar-i .
include
etags-i, m4-I .
include-dir
Make の -I.
incremental
tar-G .
info
Finger の -i, -l, -m .
init-file
いくつかのプログラムで,ユーザの初期化ファイルとして読むファイル名を指定する.
initial
expand-i .
initial-tab
diff-T .
inode
ls-i .
interactive
cp, ln, mv, rm-i, m4-e, xargs-p, tar-w .
intermix-type
shar-p .
iso-8601
date で使われている.
jobs
Make の -j.
just-print
Make の -n.
keep-going
Make の -k.
keep-files
csplit-k.
kilobytes
duls-k .
language
etags-l.
less-mode
wdiff-l.
level-for-gzip
shar-g .
line-bytes
split-C .
lines
split, head, tail で使用.
link
cpio-l .
lint
lint-old
gawk で使用.
list
cpio-t, recode-l .
list
tar-t .
literal
ls-N .
load-average
Make の -l.
login
su で使用.
machine
これを使っているプログラムはない. 使っているプログラムを見かけたら, gnu@gnu.org まで連絡を.
macro-name
ptx-M .
mail
hellouname-m .
make-directories
cpio-d .
makefile
Make の -f.
mapped
GDB で使用.
max-args
xargs-n .
max-chars
xargs-n .
max-lines
xargs-l .
max-load
Make の -l.
max-procs
xargs-P .
mesg
who-T .
message
who-T .
minimal
diff-d .
mixed-uuencode
shar-M .
mode
install, mkdir, mkfifo-m .
modification-time
tar-m .
multi-volume
tar-M .
name-prefix
Bison の -a.
nesting-limit
m4-L .
net-headers
shar-a .
new-file
Make の -W.
no-builtin-rules
Make の -r.
no-character-count
shar-w .
no-check-existing
shar-x .
no-common
wdiff-3.
no-create
touch-c .
no-defines
etags-D .
no-deleted
wdiff-1.
no-dereference
cp-d .
no-inserted
wdiff-2.
no-keep-going
Make の -S.
no-lines
Bison の -l.
no-piping
shar-P .
no-prof
gprof-e .
no-regex
etags-R.
no-sort
nm-p .
no-split
makeinfo で使用.
no-static
gprof-a .
no-time
gprof-E .
no-timestamp
shar-m .
no-validate
makeinfo で使用.
no-wait
emacsclient で使用.
no-warn
色々なプログラムで警告を抑止するために使用.
node
info-n .
nodename
uname-n .
nonmatching
cpio-f .
nstuff
objdump-n .
null
xargs-0 .
number
cat-n .
number-nonblank
cat-b .
numeric-sort
nm-n .
numeric-uid-gid
cpiols-n.
nx
GDB で使用.
old-archive
tar-o .
old-file
Make の -o.
one-file-system
tar, cp, du-l .
only-file
ptx-o.
only-prof
gprof-f .
only-time
gprof-F .
options
getopt, fdlist, fdmount, fdmountd, fdumount-o .
output
色々なプログラムで出力ファイル名を指定する.
output-prefix
shar-o .
override
rm-o .
overwrite
unshar-c .
owner
install-o .
paginate
diff-l .
paragraph-indent
makeinfo で使用.
parents
mkdirrmdir-p .
pass-all
ul-p .
pass-through
cpio-p .
port
finger-P .
portability
cpiotar-c .
posix
gawk で使用.
prefix-builtins
m4-P .
prefix
csplit-f .
preserve
tarcp で使用.
preserve-environment
su-p .
preserve-modification-time
cpio-m .
preserve-order
tar-s .
preserve-permissions
tar-p .
print
diff-l .
print-chars
cmp-L .
print-data-base
Make の -p.
print-directory
Make の -w.
print-file-name
nm-o .
print-symdefs
nm-s .
printer
wdiff-p.
prompt
ed-p.
proxy
HTTP のプロキシを指定する.
query-user
shar-X .
question
Make の -q.
quiet
多くのプログラムで通常の出力を抑止するのに使用. 注意: --quiet を受け付けるプログラムは必ず別名として--silent も受け付けなければならない.
quiet-unshar
shar-Q.
quote-name
ls-Q .
rcs
diff-n .
re-interval
gawk で使用.
read-full-blocks
tar-B .
readnow
GDB で使用.
recon
Make の -n.
record-number
tar-R .
recursive
chgrp, chown, cp, ls, diff, rmで使用.
reference-limit
makeinfo で使用.
references
ptx-r .
regex
tacetags-r .
release
uname-r .
reload-state
m4-R.
relocation
objdump-r .
rename
cpio-r .
replace
xargs-i .
report-identical-files
diff-s .
reset-access-time
cpio-a .
reverse
lsnm-r .
reversed-ed
diff-f .
right-side-defs
ptx-R .
same-order
tar-s .
same-permissions
tar-p .
save
stty-g .
se
GDB で使用.
sentence-regexp
ptx-S .
separate-dirs
du-S .
separator
tac-s .
sequence
recode で,シーケンスを渡すファイルやパイプを選択するのに使われる.
shell
su-s .
show-all
cat-A .
show-c-function
diff-p .
show-ends
cat-E .
show-function-line
diff-F .
show-tabs
cat-T .
silent
多くのプログラムで通常の出力を抑止するのに使用. 注意: --silent を受け付けるプログラムは必ず別名として--quiet も受け付けなければならない.
size
ls-s .
socket
ネットワークサーバが, 新しいソケットをオープンしバインドする代わりに使うファイル記述子を指定する. これにより, 通常は予約されたポート番号を必要とするサーバプログラムを特権のないプロセスとして実行することができる.
sort
ls で使用.
source
gawk-W source.
sparse
tar-S .
speed-large-files
diff-H .
split-at
unshar-E .
split-size-limit
shar-L .
squeeze-blank
cat-s .
start-delete
wdiff-w.
start-insert
wdiff-y.
starting-file
tardiff で, ディレクトリ中のどのファイルから処理を開始するかを指定するのに使用.
statistics
wdiff-s.
stdin-file-list
shar-S .
stop
Make の -S.
strict
recode-s .
strip
install-s .
strip-all
strip-s .
strip-debug
strip-S .
submitter
shar-s .
suffix
cp, ln, mv-S.
suffix-format
csplit-b .
sum
gprof-s .
summarize
du-s .
symbolic
ln-s .
symbols
GDB と objdump で使用 .
synclines
m4-s .
sysname
uname-s .
tabs
expandunexpand-t .
tabsize
ls-T .
terminal
tputul-T . wdiff-t.
text
diff-a .
text-files
shar-T .
time
lstouch で使用.
timeout
ある操作をあきらめるまでにどれだけの時間を待つかを指定する.
to-stdout
tar-O .
total
du-c .
touch
Make と ranlibrecode-t .
trace
m4-t .
traditional
hello-t, gawk-W traditional, ed, m4ptx-G .
tty
GDB で使用.
typedefs
ctags-t .
typedefs-and-c++
ctags-T .
typeset-mode
ptx-t .
uncompress
tar-z .
unconditional
cpio-u .
undefine
m4-U .
undefined-only
nm-u .
update
cp, ctags, mv, tar-u.
usage
gawk で使用. --help に同じ.
uuencode
shar-B .
vanilla-operation
shar-V .
verbose
進行状況についてより詳細な情報を出力する. 多くのプログラムがサポートしている.
verify
tar-W .
version
バージョン番号を表示.
version-control
cp, ln, mv-V .
vgrind
ctags-v .
volume
tar-V .
what-if
Make の -W.
whole-size-limit
shar-l .
width
lsptx-w .
word-regexp
ptx-W.
writable
who-T .
zeros
gprof-z .


Node:Memory Usage, Next:, Previous:Option Table, Up:Program Behavior

メモリの使い方

プログラムのメモリ使用量が数メガバイト程度なら,使用量を減らそうと四苦八苦する必要はありません.例えば,数メガバイトを越えるファイルの取扱いが何か他の理由で難しければ,ファイル全体をメモリに読み込んで取り扱うのが妥当でしょう.

しかし, cattail のように, 非常に大きなファイルに対しても問題なく使える必要のあるプログラムについては, 取り扱えるファイルの大きさを人為的に制限するような細工を使うのは避けるべきです. 行単位に動作するプログラムで,ユーザが指定した任意の入力ファイルに対して適用可能であれば,メモリ中には一行分だけ保持すべきです. これはそれほど難しいことではないし,ユーザはメモリに一度に入り切らないぐらい大きなファイルが取り扱えることを望むものだからです.

読者の作るプログラムが, 複雑なデータ構造を要するものなら,それを動的にメモリ中に作り, malloc がゼロを返した場合には致命的エラーとしましょう.


Node:File Usage, Previous:Memory Usage, Up:Program Behavior

ファイルの使い方

プログラムは,/usr/etc が読み出し専用ファイルシステムであっても動作するよう用意しておかなければならないでしょう. つまり,プログラムがログファイルや,ロック用ファイル,バックアップ用ファイル,ソースファイル,あるいはそれ以外のファイルを内部的な目的で変更することがあるなら,これらのファイルは /usr/etc に置いてはいけません.

例外が二つあります./etc はシステムの構成情報を置くのに使われます. プログラムの仕事がシステム構成情報を更新することにあるなら,そのプログラムが/etc にあるファイルを変更するのは妥当でしょう. また,ユーザがあるディレクトリにあるファイルを変更することを明示的に要求したなら,プログラムが同じディレクトリに他のファイルを置くのも妥当でしょう.


Node:Writing C, Next:, Previous:Program Behavior, Up:Top

C言語の上手な書き方

この{No value for `CHAPTER'}では, GNU ソフトウェアを書くときの C 言語の上手な使い方を説明します.


Node:Formatting, Next:, Previous:Writing C, Up:Writing C

ソースコードの整形

C言語では, カラム0に関数本体の始まりの開き括弧を置くことが大事です. カラム0に関数の始まりでない括弧や, 開き丸括弧, 開き大括弧を書くのはやめましょう. カラム0に開き括弧があると関数の始まりとみなすツールがいくつかあります. そのようにコードが整形されてないとこういったツールはうまく機能しません.

関数定義において, 関数名をカラム0から始めることも大事です. 他の人が関数定義を検索するのに役立つし, ツールが関数定義を認識するのにも助けになります. つまり, 適切なフォーマットは次のようになります.

static char *
concat (s1, s2)        /* Name starts in column zero here */
     char *s1, *s2;
{                     /* Open brace in column zero here */
  ...
}

あるいは標準 C では次のように定義します.

static char *
concat (char *s1, char *s2)
{
  ...
}

標準 C で書く場合, 引数がうまく一行に収まらない場合には次のように二行に分けます.

int
lots_of_args (int an_integer, long a_long, short a_short,
              double a_double, float a_float)
...

この章の残りでは, C のフォーマッティングスタイルの他の面についての我々のお勧めを紹介します. これは、indent プログラムのバージョン 1.2 以降のデフォルトのスタイルでもあります。これは、以下のオプションに対応します。

-nbad -bap -nbc -bbo -bl -bli2 -bls -ncdb -nce -cp1 -cs -di2
-ndj -nfc1 -nfca -hnl -i2 -ip5 -lp -pcs -psl -nsc -nsob

我々は以下のものを必須とは考えていません. 二つの別々のプログラムが異なるフォーマッティングスタイルを使ってもユーザには何の問題もないからです.

ただし, どんなスタイルを使うにしても, それを一貫して使ってください. 一つのプログラムでスタイルを混ぜて使うと読みにくくなるからです. 既存のプログラムに読者が行った変更を寄与するなら, そのプログラムのスタイルに従ってください.

関数本体のコードについては, 以下のようなスタイルを推奨します.

if (x < foo (y, z))
  haha = bar[4] + 5;
else
  {
    while (z)
      {
        haha += foo (z, z);
        z--;
      }
    return ++x + bar ();
  }

開き丸括弧の前とコンマの後ろにスペースを置くとプログラムが読みやすくなります. 特にコンマの後には必ずスペースを入れましょう.

式を複数行に分けて書く時は演算子の後ろではなく, 前で分けます. 次のようにします.

if (foo_this_is_long && bar > win (x, y, z)
    && remaining_condition)

優先順位が異なる2つの演算子を同じ深さに字下げするのはやめましょう. たとえば, 次のように書いてはいけません.

mode = (inmode[j] == VOIDmode
        || GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])
        ? outmode[j] : inmode[j]);

代わりに丸括弧を補って, 字下げでネストを示すようにします.

mode = ((inmode[j] == VOIDmode
         || (GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])))
        ? outmode[j] : inmode[j]);

丸括弧を余分につけるとEmacs なら適切に字下げしてくれます. 例えば次の字下げは手で行なうのならこれでも良いでしょう.

v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
    + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000;

ですが, Emacs はこれを変更してしまいます. 丸括弧を追加すれば, 同じように見栄えが良くなり, Emacs もいじることをしません.

v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
     + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);

do-while 文 は以下のように書いてください.

do
  {
    a = foo (a);
  }
while (a > 0);

プログラムの(関数の中ではない)論理的な位置でページ替えするときは, フォームフィード文字(control-L)を使ってください. 印刷されたページに収まる必要はないので,一ページの長さがどれだけになってもかまいません. フォームフィード文字は, 行中にそれだけで現れなければなりません.


Node:Comments, Next:, Previous:Formatting, Up:Writing C

コメントの書き方

すべてのプログラムは, 何をするプログラムかを簡潔に説明するコメントで始まってなくてはいけません. 例えば, fmt - filter for simple filling of text のように書きます.

GNU プログラムではコメントは英語で書いてください. というのは, 英語はほぼ全ての国の全てのプログラマが読むことの出来る唯一の言語だからです. 英語をうまく書けない人は, 出来る範囲で英語で書くようにして, 他の人に書き直すのを手伝ってもらってください. 英語でコメントを書けない人は, 書いたコメントを英語に翻訳してくれる人を見つけてください.

関数ごとにコメントを書き,何をする関数か,引数は何か,引数の値の意味と用途は何かを述べましょう.Cの型が慣例に沿った使われ方をしているなら, Cの引数宣言の意味を繰り返して書く必要はありません. 標準的でない使い方(たとえばchar * 型の引数が,実際には文字列の一番目ではなく,二番目の文字のアドレスであるような場合)があったり, 値によっては期待どおりに動かない可能性のある場合(たとえば,改行を含む文字列は動きが保証されない,等)は,その旨を明記しましょう.

また, 戻り値があるならばその意味を説明します.

コメントのセンテンスの終りにはスペース2文字を置いて, Emacs のセンテンス用コマンドが使えるようにしてください. また, 完結したセンテンスを書くようにして, 最初の1語は先頭の文字を大文字にしてください. センテンスの始めに小文字の識別子が来た場合は大文字にしないでください. 綴りを変えると違う識別子になってしまいます. 小文字で始めたくなかったらセンテンスを違ったやりかたで書いてください. ( 例えば,"The identifier lower-case is ...").

引数の値を説明するのに引数名を使えば, 関数のコメントはより明確になります. 変数名そのものは小文字であるべきですが, 変数自身でなく変数の値について言う場合は大文字で書きましょう. つまり,"an inode" ではなく "the inode number NODE_NUM"と書きましょう.

関数の直前のコメント中で関数名を記述する必要は普通ありません.読む人が自分で見ることができるからです.しかし,コメントが長過ぎて関数本体が一画面に入り切らない場合などは別です.

各静的変数については次のようにコメントすべきです.

/* Nonzero means truncate lines in the display;
   zero means continue them.  */
int truncate_lines;

入れ子になっていない,数行しかない短い条件節のときは別にして, #endifにはすべてコメントを入れるべきです. そのコメントには,最後の条件節の条件を,肯定/否定を含めて書きます. #else の場合は,条件とそれに続くコードの肯定/否定を説明するコメントを書きます. 例えば以下のようになります.

#ifdef foo
  ...
#else /* not foo */
  ...
#endif /* not foo */
#ifdef foo
  ...
#endif /* foo */

これに対して, #ifndef の場合は次のように書きます.

#ifndef foo
  ...
#else /* foo */
  ...
#endif /* foo */
#ifndef foo
  ...
#endif /* not foo */


Node:Syntactic Conventions, Next:, Previous:Comments, Up:Writing C

構文についての規約

全てのオブジェクトの型を明示的に宣言してください.例えば, 関数の引数は全部明示的に宣言してください. int 型を返す関数も,int を省略しないで明示的に宣言して下さい.

プログラマの中には GCC の -Wall オプションを使って, 警告が出たところを片っ端から直していくのが好きな人もいます. そうしたい人はどうぞおやりください. 他に -Wall が好きではないプログラマもいます. 有効であり正統なコードに対しても警告を出し, そのための変更はしたくないからです. こちらも, そうしたい方はどうぞご自由に. コンパイラは読者の召使なのですから.

外部関数とソースファイルの後部に出現する関数の宣言はファイルの最初の方の一箇所(最初の関数定義の前あたり)にまとめるか,ヘッダファイルに入れてください. 関数内に extern 宣言を入れないでください.

1つの関数内で同じ局所変数(tempのような)を何度も違う値で使うことはよくありますが,こうしないで,目的別に違う局所変数を宣言してその意味を反映した名前をつけたほうが良いでしょう. プログラムが理解しやすくなるだけでなく, 良いコンパイラによる最適化の助けになるでしょう. また, 各局所変数はそれを使っている最小のスコープ内に移動させるべきでしょう. こうするとプログラムがきれいになります.

グローバルな識別子と同じ名前の局所変数や引数を使ってはいけません.

複数の変数を複数行にまたがって一度に宣言しないでください. 行ごとに新たな宣言を開始します.たとえば,

int    foo,
       bar;

とせずに,

int foo, bar;

と書くか

int foo;
int bar;

としてください.(これらがグローバル変数ならば,その前にコメントも必要です.)

if 文の中にさらに if-else 文がある場合はif-else を括弧で囲みます.

if (foo)
  if (bar)
    win ();
  else
    lose ();

とするのではなく,次のようにしてください.

if (foo)
  {
    if (bar)
      win ();
    else
      lose ();
  }

else 文の中に if 文があるなら,次のように else if を一行に書きます.

if (foo)
  ...
else if (bar)
  ...

このとき, then 節をすぐ前の then 節と同じ深さに字下げしてください.または,ネストした if を括弧で囲みます.

if (foo)
  ...
else
  {
    if (bar)
      ...
  }

1つの宣言で, 構造体タグとその変数あるいはtypedefの両方を宣言しないでください. タグの宣言は別にし,それを使って変数あるいはtypedef の宣言をします.

if 条件中で代入をしないでください.例えば次のように書いてはいけません.

if ((foo = (char *) malloc (sizeof *foo)) == 0)
  fatal ("virtual memory exhausted");

代わりに次のように書きましょう.

foo = (char *) malloc (sizeof *foo);
if (foo == 0)
  fatal ("virtual memory exhausted");

lint の警告を抑制するために,プログラムを醜くしないようにしてください. void へのキャストは入れないでください. キャストなしのゼロは, 可変数引数の関数呼び出しに使われるとき以外は, ヌルポインタ定数として全く正しいものです.


Node:Names, Next:, Previous:Syntactic Conventions, Up:Writing C

変数,関数,ファイルの名前付け

大域変数や関数の名前は, 一種のコメントの働きをすると考えてください. ですから, 短すぎる名前は付けないでください. 代わりに, その変数や関数の意味について有益な情報を得ることが出来るような名前を選びましょう. GNU のプログラムでは, 名前は英語で意味をもつような名前にしてください. これは, コメントを書くときと同じです.

局所変数は短くてもかまいません. なぜなら, 局所変数は一つの文脈でしか使われず, その文脈のコメントで使用目的を説明するからです.

シンボル名で, 語の省略形を使い過ぎないようにしましょう. 省略形を数個作って, その意味を説明し, 頻繁に使うものなら構いませんが, 判りにくい省略形をたくさん使うのは止めましょう.

名前の中で語を分けるのにはアンダースコアを使ってください. Emacs の語単位のコマンドが使えるようになります. 小文字だけを使って,大文字はマクロと enum 定数と一定の規約にしたがった名前のプリフィックスのためにとっておきます.

例えば, iCantReadThis のような名前は使わずにignore_space_change_flag のような名前を使ってください.

コマンド行オプションが指定されたかどうかを示す変数の名前は,オプション文字を使うのではなく, オプションの意味を表す名前にすべきです. コメントはオプションの正確な意味とオプション文字の両方を明言すべきです. たとえば,次のようにします.

/* Ignore changes in horizontal whitespace (-b).  */
int ignore_space_change_flag;

整数の定数を定義したかったら #define より enum を使いましょう. GDB が enum 定数を理解するからです.

ファイルを MS-DOS のファイルシステムに落した時に、MS-DOS がファイル名を短くすることによる、ファイル名の衝突が起きないかどうか、あらかじめ確認したいこともあるでしょう。そのためには、doschk というプログラムを使うことができます。

GNU のプログラムの中には、ファイル名が 14 文字以下に収まるように制限して、古い System V のシステムに持っていった時に起こり得るファイル名の衝突を回避するものがあります。既存の GNU プログラムでこの機能を持っているものはそのまま保持するようにしてください。しかし、新規の GNU プログラムではこの機能は不要です。doschk は、14文字を越えるファイル名についても報告します。


Node:System Portability, Next:, Previous:Names, Up:Writing C

異なる OS 間の移植性

Unix の世界では,「移植性」とは異なるバージョンの Unix に移植することを意味します. GNU のプログラムにとっては,この種の移植性は望ましいことではありますが,究極のものではありません.

殆どの Unix で移植性を達成するのに一番手っ取り早い方法はAutoconf を使うことです.ホストとなるプラットフォームについてAutoconf が提供できる以上の情報が必要となる事はまずありません. そういう情報が必要になるようなプログラムは,殆どが既に書かれてしまっているからです.

半ば内部的なデータベース(例えばディレクトリ)のフォーマットを使うことは, より高レベルのもの(ディレクトリの場合はreaddir)が使える時は, 避けてください.

Unix 以外のシステム,例えば MSDOS, Windows, Macintosh, VMS, MVS 等については,サポートするのは大変な場合がほとんどです. その場合, そのような互換性のないシステムをサポートするよりは, GNU と GNU/Linux で役に立つ機能を追加するのに時間を使ったほうが良いでしょう.

読者の C のファイルをコンパイルするときに「機能テストマクロ」_GNU_SOURCE を定義するのは良い考えです. GNU あるいは GNU/Linux でコンパイルするときは, これによりGNU ライブラリの拡張関数の宣言が有効になります. そして, 読者のプログラムで同じ関数名を何か別の方法で定義すると普通はコンパイラがエラーメッセージを出します. (実際にはこれらの関数を使う必要はありません. 他のシステムにたいしてプログラムの移植性をさらに高めたいのであれば. )

ですが, これらの GNU の拡張を使おうと使わまいと, その名前を何か他の意味で使うのは避けるべきでしょう. それをやってしまうと, コードを他の GNU プログラムに移すのが難しくなってしまいます.


Node:CPU Portability, Next:, Previous:System Portability, Up:Writing C

サポートする CPU のタイプについて

GNU システムは, CPUの型による差異 --例えば,バイト順の違いやアラインメントの要求など -- により,異なるものができるでしょう. これらの差異を取り扱うのは極めて重要なことです.しかし, int 型が32ビットより小さい可能性にまで対処する必要はありません.我々はGNU では 16ビットマシンをサポートしないからです.

同様に,longsize_t のような事前定義型より小さくなる可能性も考える必要はありません. 例えば以下のように書いてかまいません.

printf ("size = %lu\n", (unsigned long) sizeof array);
printf ("diff = %ld\n", (long) (pointer2 - pointer1));

標準C 1989 は,これが動作することを要求していますし,反例はひとつしか知られていません.Microsoft Windows IA-64 上の64ビットプログラムです.我々は,GNU プログラムをその環境に移植しようと思う人にどうするか任せるつもりです.

off_t のようなファイルの大きさを表す事前定義型は例外です. これらは多くのプラットフォームで long より大きくなるので, 上のようなコードは動作しません.off_t 型の値を表示する,移植性のある方法の一つは,自分で数字をいちいち印字することです.

int型オブジェクトのアドレスが,そのオブジェクトの最下位バイトのアドレスでもあると仮定するのは正しくありません.ビッグエンディアンのマシンでは間違いです.つまり,以下のようなコーディングは避けなければなりません.

int c;
...
while ((c = getchar()) != EOF)
  write(file_descriptor, &c, 1);

関数を呼び出すとき,色々な型へのポインタ間の違いや,ポインタと整数型の違いを気にする必要はありません.ほとんどのマシンでは,どちらにしても何の違いもないからです.違いが存在する数少ないマシンについては, そういうマシンでは標準 C のプロトタイプをサポートしていますから, プロトタイプ宣言(おそらく標準 C の場合にのみ有効になるようにして)を使ってコードを正しく動作させることができます.

ある場合には,引数として整数とポインタを区別することなく同じ関数に渡しても大丈夫ですし,どんなシステムでもプロトタイプ宣言を使う必要がありません.例えば,多くの GNU ソフトウェアでは, 以下のようなエラーメッセージ出力関数を使っており,渡された引数をさらに printf 系の関数に渡しています.

error (s, a1, a2, a3)
     char *s;
     char *a1, *a2, *a3;
{
  fprintf (stderr, "error: ");
  fprintf (stderr, s, a1, a2, a3);
}

実際問題として,この例はあらゆるマシンで正しく動作します. というのは, ポインタは引数の種類の中で最も幅の広いものだからです. これは「正しい」とされる方法よりもずっと簡単です. こういう場合には,プロトタイプ宣言を使わないようにしましょう.

標準 C しかサポートしないと決めたなら, 代わりに stdarg.h を使って error を定義し, 引数を vfprintf で渡すことができます.

ポインタを整数にキャストするのは可能な限り避けてください. そういうキャストは移植性を非常に悪くしますし, ほとんどのプログラムで簡単に避けられるはずです. ポインタを整数にキャストするのが本質的な場合--例えば,Lisp インタプリタは,型情報をアドレスと同じく一語に格納します--にそうするのは良いのですが,その場合には, 異なるサイズの語を扱うための仕組みを自分で明示的に用意する必要があります. また, malloc が返すアドレスの通常の範囲が, 0 から遠く離れたところから始まるシステム用に準備が必要になります.


Node:System Functions, Next:, Previous:CPU Portability, Up:Writing C

システム関数の呼び出し

C 言語は実装により,大いに異なっています. 標準 C によりその差異は少なくなっていますが, 非互換性が完全に無くなったわけではありません.一方, 多くのGNU のパッケージは依然として標準以前のコンパイラをサポートしています. そんなに難しいことではないからです. この章では,不必要に移植性を失うことを避けるための標準 C ライブラリ関数の使い方をお勧めします.

ここで, HAVE_STRCHRHAVE_STRRCHR は, 対応する関数が存在するシステムでマクロとして定義されているものとします. これらのマクロが正しく定義されるようにする方法の一つはAutoconf を使うことです.


Node:Internationalization, Next:, Previous:System Functions, Up:Writing C

国際化

GNU には, GNU gettext と呼ばれるライブラリ関数があり,プログラム中のメッセージを色々な言語に翻訳するのを手助けしてくれます. このライブラリ関数をあらゆるプログラムで使うようにすべきです. プログラム中のメッセージは英語で書き, gettext を使って他の言語へ翻訳できるようにしましょう.

GNU gettext の使い方は以下のように,翻訳が必要な各文字列をマクロ gettext で囲みます.

printf (gettext ("Processing file `%s'..."));

こうしておくと, GNU gettext が文字列 "Processing file `%s'..." を翻訳したものと置き換えてくれます.

プログラムで一旦 gettext を使い始めたら,翻訳が必要な文字列を追加した場合, gettext の呼出しを入れるのを忘れないでください.

あるパッケージで GNU gettext を使うには,「テキストドメイン名」 というものをそのパッケージに対して指定する必要があります. テキストドメイン名は,そのパッケージの翻訳を他のパッケージの翻訳と区別するのに使われます.普通は,テキストドメイン名はパッケージ名と同じにすべきです.例えば, GNU ファイルユーティリティなら fileutils とします.

gettext をうまく動作させるためには,単語や文の構造について何らかの仮定を設けたコードを書くのは避ける必要があります. あるセンテンスの一部をデータに依存して変更したいときには, そのセンテンス全体を含む文字列定数を選択肢の数だけ用意しましょう. センテンスの中の一部分だけを条件で切り分けるのは止めましょう.

以下にやってはいけない例を示します.

printf ("%d file%s processed", nfiles,
        nfiles != 1 ? "s" : "");

この例の問題は,複数形は `s' を付けることで示されると仮定していることです. この文字列にたいして以下のように gettext を適用したとします.

printf (gettext ("%d file%s processed"), nfiles,
        nfiles != 1 ? "s" : "");

メッセージはこれとは違った文を使う事もできるはずなのに,複数形を示すのに 's' を使うことが強制されます. 元のプログラムを以下のように書くのが良いでしょう.

printf ((nfiles != 1 ? "%d files processed"
         : "%d file processed"),
        nfiles);

こうしておけば,二つの文字列にそれぞれ別に gettext を適用することができます.

printf ((nfiles != 1 ? gettext ("%d files processed")
         : gettext ("%d file processed")),
        nfiles);

これだと, "file" という言葉の複数形を示す方法がどんなものでも良く, また, どんな言語でも扱うことができます.

以下のコード例では, 同様の問題がセンテンス構造レベルでも起きます.

printf ("#  Implicit rule search has%s been done.\n",
        f->tried_implicit ? "" : " not");

このコードに gettext への呼びだしを加えた場合, 全ての言語に対して正しい結果を与えることはできません. 何故なら, 言語によっては否定を表すためにはセンテンスの複数の箇所に語を追加する必要があるからです. これに較べて, 元のコードを以下のようにすれば gettext の呼出しの追加は単純明解になります.

printf (f->tried_implicit
        ? "#  Implicit rule search has been done.\n",
        : "#  Implicit rule search has not been done.\n");


Node:Mmap, Previous:Internationalization, Up:Writing C

Mmap

mmap について, 全てのファイルに対して正しく動作するか, あるいは全然動作しないかのどちらかである, という考えを持っていたら改めてください. mmap は, あるファイルについては動作するが, 別のファイルでは動作しないこともあるのです.

mmap の正しい使い方というのは, 使いたいと思うある特定のファイルに対して mmap を試してみて, 駄目だったら, readwrite を使った別の方法で代わりに行う, というものです.

何故このような予防策が必要かと言うと, GNU カーネル(HURD) では, ユーザが拡張可能なファイルシステムを提供しており, そういう拡張されたファイルシステムには色々な種類の「通常ファイル」が存在し得るからです. 多くの場合は, mmap をサポートしていますが, 中にはサポートしていないものもあります. これらのあらゆる種類のファイルを扱えるようにプログラムを作るのが重要なことです.


Node:Documentation, Next:, Previous:Writing C, Up:Top

ドキュメント

GNU のプログラムには,理想的には,参照用と入門用両方を兼ね備えた完全でフリーなドキュメントを付けなければならない. そのパッケージがプログラムしたり拡張したりすることが可能なら, 単なる使い方だけでなく,プログラミングや拡張方法についても触れていなければならない.


Node:GNU Manuals, Next:, Previous:Documentation, Up:Documentation

マニュアルの正しい書き方

GNU システムの構成部分のドキュメントを書くのに望ましいフォーマットは, Texinfo フォーマット言語です.どの GNU パッケージも(理想的には) 参照用と学習用両方を目的とするドキュメントを Texinfo で書いたものを持つべきです. Texinfo を使うことで, TeX を使って高品質のフォーマットされた本を作ったり, Info ファイルを生成することが可能になります. Texinfo のソースから HTML 出力を生成することも可能です. Texinfo のマニュアルは,ハードコピー か info コマンド, あるいはGNU Emacs の Info (C-h i)で参照してください.

現在では,Docbook や Sgmltexi のような他のいくつかのフォーマットも自動的に Texinfo に変換できます.Texinfo のドキュメントをこのような変換で生成するのは,良い結果が得られるのであれば,かまいません.

プログラマは, ドキュメントの構成を, プログラムの実装の構成に合わせるのが自然であると考えがちです. プログラムの構成については良く知っているので. しかし, こういう構成はプログラムの使い方を説明するのには向いていません. どちらかというと, ユーザにとっては不親切で混乱させかねないのです.

段落の中の文章から, 話題を別々のマニュアルに分類することに至るまでの, 文書のあらゆる階層において, 正しい文書の構成方法というのは, 読者が読んでいるときに心に浮かんでいる考えや疑問に従うということです. こういう構成方法は, ソフトウェアの実装の構成と一致することもありますが, 異なることが多いと考えたほうが良いでしょう. 良い文書を書く方法を学ぶうえで一つ重要なことは, 文書の構成をソフトウェアの実装に合わせているなら, 他にもっと良い方法があるはずだということに気が付くことです.

例えば, GNU システムの各プログラムの説明は, 一つのマニュアルに納まるべきでしょう. しかし, このことは, それぞれのプログラムがそれぞれのマニュアルを持つべきであるということは意味しません. それぞれのマニュアルを持つというのは, ユーザの理解を助ける構成というよりは, プログラムの実装にしたがった構成です.

代わりに, それぞれのマニュアルは首尾一貫した話題をカバーすべきです. 例えば, diffdiff3 のマニュアルを別々に用意する代わりに, 我々は "comparison of files" いう名前のマニュアルを一つ用意し, 両方のプログラム, それに cmp の解説を含めています. これのプログラムを一緒に説明することで, 話題全体をはっきりさせることが出来ます.

あるプログラムについて解説しているマニュアルには, そのプログラムの全コマンド行引数と全内部コマンドが確かに書かれていなくてはなりませんし, その使用例を載せなくてはなりません. しかしマニュアルを機能の一覧として構成しないでください. 代わりに,論理的に副題で構成しましょう. そのプログラムが実際に行うことについて考えたときにユーザが疑問に思うであろう事柄を説明しましょう.

一般に, GNU のマニュアルは入門書とリファレンスの両方の役割を果たすべきです.Info を通じて各トピックを参照するのが簡単に出来なくてはいけませんし,付録を除いて,頭から順番に読んでいっても良いようになっていなくてはなりません.また, GNU のマニュアルは初心者が読み始めるのに適した入門遍がなくてはなりませんし,熟練者が必要とするあらゆる詳細についても提供する必要があります. Bison のマニュアルが良い例になっています. Bison のマニュアルを眺めて我々の意図を理解してください.

これは思ったほど難しいことではありません.各章を,そこで扱う話題を論理的に分割し,それを節として順序良く並べ,それから中身の文章を書きます.そうすることで,その章を頭から読み進めても理解できるようになります.本を章に分けるときや,節を段落から構成するときにも同じことが言えます.標語的に言えば,文章のどの場所においても, 前の文章で提示されたもっとも基本的で重要な問題に注意を向けましょう.

必要なら,マニュアルの冒頭に章を追加して完全な入門遍とし,基本事項をカバーするようにしましょう.こうすることで,初心者がマニュアルの残りの部分を理解するための指針となります. Bison のマニュアルがその良い例になっています.

リファレンスとするには,マニュアルには,関数,変数,オプション, それに,そのプログラムの一部である重要な概念を全て列挙した索引がなくてはなりません.全部を一つの索引にいれたものでも短いマニュアルには充分かもしれませんが,複雑なパッケージの場合は複数の索引を使った方が良いでしょう.Texinfo のマニュアルには良い索引項目の作り方についての説明があります.Index EntriesIndexing Commands を見て下さい.

GNU のドキュメントを書くのに, Unix のマンページの書き方は手本にしないでください. Unix のマンページは大抵短すぎて, 構成がまずく, 背景にある考え方の説明が適切ではありません. (もちろん, いくつか例外はありますが. ) また, Unix のマンページで使っているフォーマットは我々が GNU のマニュアルで使っているのと全然違っているという事情もあります.

マニュアル自体のバグの報告先の電子メールアドレスをそのマニュアルに書いてください.

Unix のドキュメントで使われている "pathname" という言葉は使わないでください.代わりに "file name" という二語を使ってください. 我々は "path" は,検索パス,つまりディレクトリ名のリストにしか使いません.

プログラムに対する入力が誤っていることを示すのに, "illegal" という言葉は使わないでください. 入力の誤りには "invalid" を使うようにし, "illegal" は法律により罰せられる活動という意味に取っておきます.


Node:Doc Strings and Manuals, Next:, Previous:GNU Manuals, Up:Documentation

説明文とマニュアル

プログラミングシステムの中には,Emacs のように,関数や,コマンド, 変数毎に説明文(documentation string)を提供しているものがあります. リファレンスマニュアルを書く時に,この説明文を編集して,補足文をいくらか追加するというやりかたをしたくなるかも知れません.が,決してそうしてはなりません. そのやり方は根本的に間違っているのです.うまく書かれた説明文はマニュアル用には全く向いていないのです.

説明文は自立している必要があります.画面に表示された時, それを紹介したり説明したりする文はないのです. 一方,形式にはあまり拘らなくてかまいません.

マニュアルの中では,関数や変数を説明する文は孤立してはなりません. それは,セクションやサブセクションの文脈の中に現れるのです. セクションの冒頭には何らかの概念を説明する文を置き,それに,いくつかの関数や変数に適用される一般的な観点を提供すべきでしょう. セクション内でそれ以前に現れる関数や変数の説明もまた話題についての情報を提供するでしょう.独立したものとして書かれた説明は, そういう情報の一部を繰り返すことになります.これは冗長で良くありません. 一方,形式から外れるのは説明文では許されるても,マニュアルでは受け入れられません.

良いマニュアルを書く上で,説明文の正しい使い道は, 良い文を書くための情報源として使う他にはありません.


Node:Manual Structure Details, Next:, Previous:Doc Strings and Manuals, Up:Documentation

構成方法

タイトルページには, マニュアルに記述されているプログラムやパッケージのバージョンを書かなくてはなりません. マニュアルの先頭ノードにも,この情報が必要です. プログラムとは独立に, あるいはプログラムより頻繁にマニュアルが変更されるなら, マニュアルのバージョン番号も書いてください.

マニュアルに記述されているプログラム毎に, program Invocation あるいは Invoking programという名前のノードが必要です. ここで programは,説明されるプログラムの名前であり, 実行するためにシェルにタイプするものです. このノード(もしあればサブノードも)には,プログラムのコマンド行引数の説明と起動方法(つまり,通常マンページに書かれるような情報)を明記します. @example で始め,そこには全オプションと引数のテンプレートを書きます.

あるいは,名前が上のパターンのどれか一つに一致するようなメニュー項目をどこかのメニューに入れます. こうすることで,ノードの実際の名前には関係なく, そのメニュー項目が指すノードをこの目的のためのノードとして識別します.

Info リーダプログラムの --usage の機能を使うと, ノードやメニュー項目を探して,関係するテキストを見つけるので, どの Texinfo ファイルにも入れるのが本質的に重要です.

1つのマニュアルで複数のプログラムを記述しているなら,そのマニュアルの中にプログラム毎にそれを記述するノードを持つようにすべきです.


Node:License for Manuals, Next:, Previous:Manual Structure Details, Up:Documentation

マニュアルのライセンス

マニュアルが GNU GPL または GNU LGPL のコピーを含んでいるなら, あるいはマニュアルが政治的あるいは個人的な宣言を行っている章を含んでいるなら, GNU Emacs マニュアルの配布条項をコピーしてください. そして, 修正したり削除してはならない特別な章のリストを適切に修正して合わせてください.

マニュアルにそのような章がなければ, Texinfo のマニュアルの同様の配布条項を真似てください.

GNU のマニュアルには,それが2,3ページよりも長いものなら,全てGNU Free Documentation License を使ってください. 短いドキュメントの集まりについても同じようにしてください. その場合,集まり全体に一つ GNU FDL のコピーがあれば充分です. 短いドキュメントが一つあるだけなら,非常に制限の緩い, コピーレフトでないライセンスを使って,長ったらしいライセンスでスペースを使うのを避けることができます.

GFDL を採用する方法についてのより詳しい説明は、http://www.gnu.org/copyleft/fdl-howto.html を見て下さい。

ライセンスが GNU GPL でも GNU LGPL でもないマニュアルに、GPL やLGPL を含める義務はないことに注意して下さい。分厚いマニュアルの場合は、プログラムのライセンスを含めるのは良い考えです。短いマニュアルの場合は、プログラムのライセンスを入れると大きさが非常に大きくなってしまうようであれば、多分取り込まない方が良いでしょう。


Node:Manual Credits, Next:, Previous:License for Manuals, Up:Documentation

マニュアルのクレジット

主となるマニュアルの作者を著者として,タイトルページに明記して下さい. 企業がスポンサーとなっている作業の場合には,マニュアルの適切な場所にその企業に対する謝辞を入れるようにし,著者としては入れないでください.


Node:Printed Manuals, Next:, Previous:Manual Credits, Up:Documentation

印刷されたマニュアル

FSF は、GNU マニュアルのうちいくつかを印刷して発行している。これらのマニュアルが売れるように、マニュアルのオンライン版では、冒頭で、印刷されたマニュアルが入手可能であることを述べ、入手方法についての情報を、例えば <http://www.gnu.org/order/order.html> というページへのリンクをはって、指し示すこと。ただし、この情報は、冗長であるので、印刷されたマニュアルには含める必要はない。

オンライン版のマニュアルで、ソースからマニュアルを印刷する方法を説明するのも良いことである。


Node:NEWS File, Next:, Previous:Printed Manuals, Up:Documentation

NEWS ファイル

マニュアルに加えて,各パッケージには NEWSという名前のファイルを含めて,そこに記述に値するユーザに見える変更点を書きます. そして,新しいリリースのたびにファイルの先頭に項目を追加し,バージョンを明らかにしておきます. 古い項目を捨てずに,新しい項目の後ろに残しておきましょう. こうしておくと,以前のバージョンからアップグレードしたユーザは何が最新かが分かります.

NEWSが長くなり過ぎたら,古い項目は ONEWSに移動させ, NEWS ファイルの最後に,ONEWSを参照するように注意書きをつけましょう.


Node:Change Logs, Next:, Previous:NEWS File, Up:Documentation

変更履歴

プログラムのソースファイルになされた変更については,全部,変更履歴に書くようにしてください.目的は,将来バグについて調査をする人が, どの変更がバグを招いたのかを知ることができるようにするためです. 新しいバグは,変更したばかりのところで良く見つかります. もっと重要なことは,変更履歴があるとプログラムの別々の部分で方針に食い違いが生じるのを防ぎます.それぞれの方針の食い違いがどのようにして生じたのか,それがどの部分で発生したのかが履歴として残るからです.


Node:Change Log Concepts, Next:, Previous:Change Logs, Up:Change Logs

変更履歴の考え方

変更履歴は, 以前のバージョンが現在のバージョンとどれだけ違うかを説明する変更取消しの一覧のようなものと考えることもできます. 現在のバージョンはすぐ見ることができます.それが何をしているのかの変更履歴は必要ないのです. 変更履歴に求められるものは, 以前のバージョンがどのように異なるかの明確な説明です.

変更履歴ファイルは普通 ChangeLog という名前で,それが置かれているディレクトリ全体をカバーします.ディレクトリ毎にそのディレクトリ用の変更履歴を置いても良いし,親ディレクトリの変更履歴に書いても構いません. どちらでも好きな方を選べます.

別の選択肢としては,変更履歴情報を RCS や CVS のようなバージョン管理システムで記録することです.これは,rcs2log を使って自動的に ChangeLog形式のファイルに変換することができます. Emacs では, C-x v a (vc-update-change-log) というコマンドでできます.

変更の目的を逐一書いたり, ある変更点と別の変更点との関係を書いたりする必要はありません. 変更についての説明が必要だと思うこともあるでしょう. その場合,おそらくその通りでしょう.大いに説明を書いてください. ただし,その説明は,プログラム中にコメント文として書いてください. そうすれば,プログラムを読む人は必ずそのコメント文を見ることになるからです. 例えば,関数を一個追加したとき,変更履歴には "New function" と書けば充分です.その関数が何をする関数かの説明はソースコード中で, その関数の定義の前にコメントとして書かれているはずだからです.

しかし, 変更量が多いときには, 変更目的の概要を示す一行が役にたつこともあります.

ChangeLog に新しい項目を追加するのに一番簡単な方法は, Emacs の M-x add-change-log-entry コマンドを使うことです. 各項目にはアスタリスクと変更したファイル名を書き,さらに変更した関数や変数名などを丸括弧でくくって書いて, コロンをつけてください.その後に関数なり変数に加えた変更を記述してください.


Node:Style of Change Logs, Next:, Previous:Change Log Concepts, Up:Change Logs

変更履歴の形式

以下に簡単な変更履歴の例をいくつか示します. まず,ヘッダ行で誰がいつ変更を行なったかを述べます. 次に,個々の変更の説明を書きます. (以下の例は,Emacs と GCC から取ったものです.)

1998-08-17  Richard Stallman  <rms@gnu.org>

* register.el (insert-register): Return nil.
(jump-to-register): Likewise.

* sort.el (sort-subr): Return nil.

* tex-mode.el (tex-bibtex-file, tex-file, tex-region):
Restart the tex shell if process is gone or stopped.
(tex-shell-running): New function.

* expr.c (store_one_arg): Round size up for move_block_to_reg.
(expand_call): Round up when emitting USE insns.
* stmt.c (assign_parms): Round size up for move_block_from_reg.

変更を行った関数名や変数名は略さずに全部書くことが重要です. 省略したり,複数の名前を組み合わせて書いたりしないでください. 保守を引き継いだ人が,関係する変更の履歴を関数名で検索する場合に, 名前が省略されていると,探しているものが見つからずに困ります.

例えば, * register.el({insert,jump-to}-register) のように関数名をグループ化して略記する人がいますが,これはやめてください. これでは jump-to-registerinsert-register で検索した場合に, 該当する変更履歴を見つけられないからです.

関連のない変更履歴の項目間は空行で区切ります.2つの項目が同じ一つの変更の各部分を表していて関係があるなら, 空行を入れないでください.その場合, 連続する項目が同じファイルにあるならファイル名とアスタリスクは省略できます.

関数名のリストが長い場合は,以下の例のように,行の途中で, , ではなく ) で閉じて分割し,継続行は ( で始めるようにします.

* keyboard.c (menu_bar_items, tool_bar_items)
(Fexecute_extended_command): Deal with `keymap' property.


Node:Simple Changes, Next:, Previous:Style of Change Logs, Up:Change Logs

簡単な変更の場合

変更がある程度簡単なものなら,変更履歴にあまり詳しく書く必要はありません.

ある関数の呼び出しシーケンスをより単純な形に変更して, それに合わせて呼び出し側を全部その新しい呼び出しシーケンスに変更した, というような場合, 呼び出し側の変更全部についてを個々の項目を作る必要はありません. 呼び出される関数の項目に以下のように「呼び出し側のすべてを変更」と書いておけば十分です.

* keyboard.c (Fcommand_execute): New arg SPECIAL.
All callers changed.

コメントやドキュメントを変更した時は, 項目には関数の説明は書かずに, ファイル名だけで充分です. "Doc fix"とだけ書けば変更履歴としては充分です.

ドキュメントファイルの変更履歴を作る必要はありません. ドキュメントの場合には, 修正困難なバグというのはあまり無いからです. ドキュメントは, 厳密な工学的な取扱いを必要とする部分には含まれません. 誤りを直すためにその履歴を知る必要はありません. ドキュメントに書かれていることと実際のプログラムの動作を比較すれば良いのです.


Node:Conditional Changes, Next:, Previous:Simple Changes, Up:Change Logs

#ifdef の場合

C 言語のプログラムでは,コンパイル時の条件節 #ifを良く使います.変更が条件節に入っていることも多くあります. 完全に条件節の内側に入る新しい定義を追加することもあるでしょう. 変更履歴に,変更が適用される場合の条件を示すのは大変役に立ちます.

我々の約束では,条件節の変更を示すには,条件の名前(#define 名)を鍵括弧で囲むことになっています.

以下の簡単な例は,条件節に関する変更を記述しています.ただし, 変更点に関数名や変数名が伴っていません.

* xterm.c [SOLARIS2]: Include string.h.

次の例は,完全に条件節に含まれる新しい #define を記述する項目です. マクロ FRAME_WINDOW_P のこの新しい #define は, HAVE_X_WINDOWS が #define された場合にのみ使われます.

* frame.h [HAVE_X_WINDOWS] (FRAME_WINDOW_P): Macro defined.

次の例は, init_display という関数の中の変更を記述する項目です. 関数 init_display 全体としての定義は条件節の中には含まれていませんが, 変更点自体は, #ifdef HAVE_LIBCURSES という条件節に含まれます.

* dispnew.c (init_display) [HAVE_LIBNCURSES]: If X, call tgetent.

次の例は,あるマクロが定義されない場合にのみ有効になる変更点に関する項目です.

(gethostname) [!HAVE_SOCKETS]: Replace with winsock version.


Node:Indicating the Part Changed, Previous:Conditional Changes, Up:Change Logs

部分的な変更を示すには

関数の変更のあった部分を, その部分が何をするものかを示すものを角括弧で囲んで示すようにしましょう. 以下の例は, sh コマンドを扱う関数 sh-while-getopts の一部についての変更を表すエントリです.

* progmodes/sh-script.el (sh-while-getopts) <sh>: Handle case that
user-specified option string is empty.


Node:Man Pages, Next:, Previous:Change Logs, Up:Documentation

マンページは重要ではない

GNU プロジェクトにおいては,マンページは必須ではありません. GNU のプログラムは,マンページは必要ではありませんし,要求されることもありません.中にはマンページを持っているものもありますが. 読者の自作のプログラムにマンページを含めるかどうかは読者自身が決めれば良いことです.

どっちにするか決める際には,マンページを入れるということは, プログラムが変更される度にマンページも更新し続ける必要があるということを考えてください.マンページを保守するのに割く時間は, もっと役に立つ仕事に回せるはずです.

変更のほとんどない,簡単なプログラムの場合には,マンページの更新もたいした作業ではないでしょう.そういう場合には,既にマンページを作成済なら,それを含めない理由はありません.

大量の変更が発生する大きなプログラムの場合には,マンページの更新作業は大変な負荷になります.そのプログラムのユーザがマンページを書いてくれたとします.しかし,それを受け取るのは高くつくということがわかるでしょう. そのユーザがマンページの保守を全面的に引き受けてくれて,自分は何もする必要がないというのでない限り,断わったほうが良いでしょう. もし保守作業を引き受けてくれたとして,その人がある時点で保守作業をやめたとします.しかし,それを自分で引き継ごうとは思わなくて良いのです. 誰か他に保守してくれる人が現れるまで,配布物からマンページを抜いた方が抜いてしまいましょう.

変更が少ないプログラムの場合,マンページを更新しなくても,相違点は少ないからそのままでも役に立つと考える人もいるでしょう.その場合には, マンページの先頭に目立つように注意書きを書いて,マンページの更新は行っていないこと,および,正しくは Texinfo のマニュアルを見るべきであることを知らせましょう.注意書きには,Texinfo マニュアルの探し方も書いておきます.


Node:Reading other Manuals, Previous:Man Pages, Up:Documentation

他のマニュアルをどこまで参考にしてい良いか

自分がドキュメントを書こうとしているプログラムについて,それを解説しているフリーでない本やドキュメントファイルが存在することもあるでしょう.

そういうドキュメントを参考文献として使うことに問題はありません. ちょうど,新しい代数学の教科書の著者が,他の代数学の本を読むのが問題ないのと同じようなものです. フィクションでない本はどんな本でも,ほとんどの部分が事実から構成されています.この場合事実というのはあるプログラムがどのように動作するのかという点に関する事実を指します.そして,そういう事実は同じ主題について書く人誰にでも同じである必要があります. しかし,フリーでない文書からは,文書の構造や,言葉遣い,表や例などをコピーしないように注意する必要があります. フリーな文書からコピーするのはおそらく大丈夫でしょう. しかし,個々の場合については FSF に問い合わせてください.


Node:Managing Releases, Next:, Previous:Documentation, Up:Top

リリースの管理

ソフトウェアをリリースするということは,単にソースファイルを tar ファイルにまとめて FTP サイトに置くだけでは済みません.そのソフトウェアの設定を色々なシステムで動作するように構成可能にする必要があります. Makefile は,以下に述べるように GNU コーディング規約に則っている必要がありますし,ディレクトリ構造も以下で議論するようになっている必要があります.そうすることで,すべての GNU ソフトウェアからなるフレームワークにそのパッケージを取り込むことが容易になります.


Node:Configuration, Next:, Previous:Managing Releases, Up:Managing Releases

どのようにコンフィギュレーションを行うか

GNU の配布物には configure というファイル名のシェルスクリプトを入れておく必要があります. このスクリプトには, 計算機やシステムの種類を記述する引数を指定します.

configure スクリプトはコンフィギュレーションのオプションを記録して,コンパイルの際に反映されるようにしなければなりません.

そのための方法の一つは, config.hのような標準的な名前を, システム固有のコンフィギュレーションファイルにリンクすることです. この方法を使うなら, 配布物には config.h を含めてはいけません. これは, configure を実行しないうちは, プログラムを構築できないようにするためです.

configure に Makefile を編集させることもできます. その場合, 配布物には Makefile という名前のファイルを含めないでください. その代わりに, 編集に必要な入力の入ったファイルMakefile.in を含めるべきです. これも, configure を実行しないうちはプログラムを構築できないようにするためです.

configureMakefileを作るならば, Makefile の中にMakefile というターゲットが書かれていなければなりません. このターゲットは, configure を再起動し, 最後に設定されたコンフィギュレーションをもう一度再設定します. configure が読み込むファイルは ターゲット Makefile の依存ファイルとして列記されてなければなりません.

configure スクリプトが出力するファイルには, 全て先頭にコメントを入れ, configureから自動生成されたことの説明を付けておきます. これはユーザが自分で書き直そうとしないようにするためです.

configure スクリプトは config.statusというファイルを作成し, プログラムが最後に構成された時の指定オプションを記録しなければなりません. このファイルはシェルスクリプトになるようにし, 実行すると同じ構成を再設定するようにしなければなりません.

configure スクリプトは, ソースの存在するディレクトリ(それがカレントディレクトリでないなら)を指定するオプション--srcdir=dirname を受け付けなければなりません. このオプションを指定すれば, 実際のソースディレクトリを変更せずに,別のディレクトリにプログラムを作ることが可能になります.

ユーザが --srcdir を指定しない場合, configure は, ソースが存在するかどうか, ...を調べる必要があります. もしどちらかに存在すればそこにあるソースを使うようにし, 見つからなければソースがないと報告してゼロ以外のステータスで終了しなければなりません.

--srcdir をサポートする簡単な方法は, Makefile 中の VPATH の定義を編集することです.(makeの)ルールの中には, 指定されたソースディレクトリを明示的に参照することが必要なものがあります. これを可能にするため, configure は Makefile にsrcdir という名の変数を追加できます. この変数の値は指定されたソースディレクトリです.

configure は,プログラムを構築するシステムのタイプを決めるための引数を受け付けます.その引数は次のような形式です.

cpu-company-system

たとえば Sun 3 ならば m68k-sun-sunos4.1となります.

configure は, 計算機を記述するための適当な別名を解読できる必要があります. つまり, sun3-sunos4.1 は, 有効な別名になるようにしなければなりません. Ultrix と BSD の違いはほとんど気づかないものだし,それを区別する必要のあるプログラムも滅多にないので,多くのプログラムにとっては vax-dec-ultrixvax-dec-bsd の別名となり得ます.

config.subというスクリプトがあります. これはシステムのタイプと正規化された別名を確認するためのサブルーチンとして使えます.

各マシン上のソフトウェア,ハードウェアをもっと詳細に指定したり, パッケージ中のオプション部分を取り込むか,外すかを指定するオプションを与えることができます.

--enable-feature[=parameter]
feature と呼ばれるユーザーレベルのオプション機能を作成,インストールするように,パッケージをコンフィギュレーションする.これによって, どの機能を取り込むか選べるようになる.デフォルトで作成されるものに対しては, parameterno を指定すると, feature を外さなくてはならない.

--enable オプションを指定することで,一つの機能を何か別のもう一つの機能で置き換えてはいけない. --enable オプションを指定することで,一つの便利な動作を他の便利な動作の代用にしてはいけない. --enable の正しい使い道はただ一つで,プログラムの一部を構築するかそれとも排除するかを選ぶためにある.

--with-package
package というパッケージがインストールされるのでこれと一緒に動くように構成する.

configureは以上の詳細なオプションを全て受け付なければいけません.それが特定のパッケージに違いをもたらすものであろうとなかろうと. 特に, --with- あるいは --enable-で始まるオプションは, 1つのオプションのセットでGNU のソース・ツリー全体を同時に構成できるようにするために, 必ず受け付けなければなりません.

--with---enable- の役割は限られたものであることに注意してください.読者が自分で思い付いたオプションを置く場所ではありません.つまり,慎重に考えてください. 我々は, GNU ソフトウェアでは指定できるコンフィギュレーションのオプションを限定したいのです.GNU のプログラムに変なコンフィギュレーションオプションを入れたくないのです.

コンパイルの過程の一部をなすようなパッケージは, クロスコンパイルをサポートする可能性があります. そのような場合, ホストとターゲットマシンは異なるものに指定できます.

通常は, configure は指定されたシステムのタイプをホストとターゲット両方に対してのものと見なすので, 同じタイプのマシンで動くプログラムを作成します.

クロスコンパイラ, クロスアセンブラ等をコンフィギュレーションするには, configure を実行する時にホストとはことなるターゲットを, --target=targettype オプションを使って指定します. targettype の書き方は上に述べたとおりです. つまり,コマンド行は以下のようになります.

./configure hosttype --target=targettype

クロス環境で動かすことに意味のないプログラムの場合には, --target オプションを受け付ける必要はありません. 何故なら,クロスで動くオペレーティングシステム全体を構成することは意味のないことだからです.

クロスコンパイラをブートストラップするには, ホスト以外の, そのコンパイラが走るであろうマシン上で,それをコンパイルする必要があります. コンパイラパッケージは,コンフィグレーションオプション--build=buildtype で, コンパイルを行なうコンフィグレーションを指定することができます. ただし,configure スクリプトは通常,構築を行なう機種型を(config.guess を使って)推測するはずなので,このオプションはおそらく必要ないでしょう. ホストとターゲットの機種のデフォルトは通常ビルド機種になるので, クロスコンパイラをブートストラップする場合は,両方を明示的に指定しなければなりません.

自分自身を自動的に構成するプログラムもあります. 自分のプログラムがそのように設定されていれば, configure スクリプトはその引数のほとんどを単に無視できるでしょう.


Node:Makefile Conventions, Next:, Previous:Configuration, Up:Managing Releases

Makefileの規約

このでは GNU のプログラムに向けて Makefile を書くときの規約を述べます. Automake を使うと、以下の規約に従う Makefile を書く助けとなります。


Node:Makefile Basics, Next:, Previous:Makefile Conventions, Up:Makefile Conventions

Makefileについての一般的な規約

変数 SHELL が環境変数から継承される可能性のあるシステムでの問題を避けるために, Makefile には必ず以下の一行が必要です. (これは, GNU make では決して問題になりません.)

SHELL = /bin/sh

make によっては,サフィックスのリストや暗黙のルールについて互換でない部分があるために,混乱や誤解を招くことが良くあります. ですから,問題の Makefile で必要なサフィックスだけを明示的にサフィックスのリストに設定するのが良い方法です.例えば以下のように書きます.

.SUFFIXES:
.SUFFIXES: .c .o

一行目でサフィックスリストをクリアしておき,二行目でこの Makefile の中で暗黙のルールに従って欲しいサフィックスを定義します.

コマンド検索パスの中には必ずしも . が入っているとは限りません. make の実行時にパッケージに含まれるプログラムを起動する必要がある場合, そのプログラムが make で作成されるものならば ./を, あるいはそのファイルがソースコードの不変な部分であるときは, $(srcdir)/ を使っているかを確かめてください. これらの接頭辞(prefix)がなければ現在の検索パスが使われます.

./(コンパイルディレクトリ$(srcdir)/(ソースディレクトリ) の区別は重要です. 何故なら、configure--srcdir オプションを使って別のディレクトリでコンパイル可能でなければならないからです。

foo.1 : foo.man sedscript
        sed -e sedscript foo.man > foo.1

と言う形のルールは, コンパイルディレクトリがソースディレクトリと異なる場合, foo.mansedscript はソースディレクトリにあるので失敗します.

GNU make を使う場合に, 依存ファイルが一つしかない場合は,ソースファイルを見つける手段としてVPATHを使うとうまくいきます.なぜならば,ソースファイルがどこにあっても make の組み込み変数 $< でそれを表現できるからです. (多くの make では, $< は暗黙のルールでのみ設定されます.) Makefileのターゲットは,

foo.o : bar.c
        $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o

ではなく, VPATH が正しく働くように,次のように書くべきです.

foo.o : bar.c
        $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@

ターゲットが複数のファイルに依存している場合は, 明示的に $(srcdir) を使うのが, 最も簡単にルールを機能させる方法です. 例えば, 上の foo.1 というターゲットは次のように書くのが一番良いでしょう.

foo.1 : foo.man sedscript
        sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@

GNU の配布物には通常、ソースファイルではないファイル--例えば、Info ファイルやAutoconf, Automake, Bison, Flex 等の出力ファイルが含まれています。これらのファイルは通常はソースディレクトリに置かれるので、必ずコンパイルディレクトリではなくてソースディレクトリに置かれるようにする必要があります。つまり、Makefile の書き方としては、これらのファイルを更新するときにはソースディレクトリに更新されたファイルを置くようにする必要があります。

一方、あるファイルが配布物には含まれないものなら、Makefile では、それをソースディレクトリに置くように書いてはいけません。なぜなら、通常の環境でプログラムをコンパイルするときには、ソースディレクトリを更新すべきではないからです。

少なくとも構築用とインストール用のターゲットについては(そして,それらのサブターゲット全てについても),並列 make を使用した場合にも正しく動作するようにしましょう.


Node:Utilities in Makefiles, Next:, Previous:Makefile Basics, Up:Makefile Conventions

Makefile 中で使用するユーティリティ

Makefile 中に書くコマンド(それに configureなどのシェルスクリプトも)は, csh ではなくsh で動作するようにしましょう. kshbash に固有の特殊な機能は使わないでください.

configureスクリプトを書くとき, それにプログラムの構築とインストールについてのルールを, Makefile に書く場合, 次のものを除いて, プログラム名を直接書くのは避けてください.

cat cmp cp diff echo egrep expr false grep install-info
ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true

圧縮プログラム gzip は、dist の規則で使うことができます。

上にあげたプログラムを使う場合でも, 一般的にサポートされてるオプションだけを使うようにしてください. 例えば, mkdir -p が使えると便利ですが, サポートしていないシステムがほとんどなので, 使わないようにしてください.

Makefile 中でシンボリックリンクを作るのは避けたほうが良いでしょう. シンボリックリンクをサポートしていないシステムが少数ですが,存在します.

プログラムの構築とインストールについてのルールを, Makefile に書く場合にコンパイラやコンパイラに関連したプログラムを使うことができますが, その場合も make の変数を経由して使うようにし, ユーザが別のものと置き換えることができるようにしてください. 次のようなプログラムが該当します.

ar bison cc flex install ld ldconfig lex
make makeinfo ranlib texi2dvi yacc

それぞれ以下の make の変数を使用します.

$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)

ranlib または ldconfig を使うのなら, これらのコマンドの無いシステムでも問題が起きないことを確認してください. これらのコマンドが存在しないためにエラーになってもそれを無視するようにし, コマンドの実行前に, これらのコマンドによる失敗は問題ではないことをユーザに知らせるようなメッセージを出力すべきでしょう. (Autoconf の AC_PROG_RANLIB マクロを使うのが便利です.)

シンボリックリンクを使う場合には, シンボリックリンクがないシステムのために代わりのものを実装すべきです.

さらに、以下のコマンドが Make の変数経由で使用できます.

chgrp chmod chown mknod

あるシステムには存在するとわかっているユーティリティを, Makefile 中のその特別なシステム向けの部分(あるいはスクリプト)に記述するのは構いません.


Node:Command Variables, Next:, Previous:Utilities in Makefiles, Up:Makefile Conventions

コマンドを指定するための変数

Makefileでは,ある種のコマンドやオプションなどを上書きするための変数を提供しなければなりません.

特に,大部分のユーティリティプログラムは変数を経由させて起動すべきです. つまり, Bisonを使う必要があるなら BISONという変数を設けてそのデフォルト値を BISON = bison とし,必要な箇所では $(BISON) と書いて参照するようにします.

ln, rm, mv などのファイル管理ユーティリティはこのように変数経由にしなくてかまいません. これらを他のプログラムに置き換える必要がないからです.

プログラム名を指定するための変数ごとに,そのプログラムにオプションを与えるためのオプション変数を設けましょう.オプション変数の名前は,プログラム名の変数名にFLAGSをつけたものにします.例えば BISONFLAGSとします. (C コンパイラ用の CFLAGS, yacc 用の YFLAGS, lex 用のLFLAGS はこの規則の例外ですが,すでに標準になっているのでそのままにします.)プリプロセッサを起動するコマンドには CPPFLAGSを, リンクを行なうコマンドには, ld コマンドを直接使う時と同様にLDFLAGS を使います.

特定のファイルだけ特別な方法でコンパイルするときに必要になるCコンパイラのオプションは, CFLAGSには入れないでください. ユーザは自分で自由に CFLAGS に指定できることを期待します. CFLAGSに入れる代わりに, コンパイルコマンドに明示的に書くか, 暗黙のルールを定義するかして, CFLAGS とは別にCコンパイラに渡すようにします. 例えば以下のようにします.

CFLAGS = -g
ALL_CFLAGS = -I. $(CFLAGS)
.c.o:
        $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<

-g オプションを CFLAGS に入れてください. 特別のコンパイルでは必要とされないオプションだからです. それは単にお薦めであるというだけのデフォルトであると考えて構いません. デフォルトでGCCでコンパイルされるようにパッケージが設定されているときには, CFLAGS のデフォルト値に -O を入れておくのも良いでしょう.

CFLAGS は,コンパイルコマンドの最後,コンパイラオプションを含む他の変数群の後に入れてください.そうすると,ユーザが CFLAGS を使って他のオプションを上書きすることができます.

CFLAGS は C コンパイラが起動するたびに使うようにすべきです。これは、コンパイル自体とリンクの両方の過程で必要です。

Makefile にはINSTALLという変数の定義が必要です.これはファイルをシステムにインストールするときの基本コマンドを指定します.

また, Makefile には INSTALL_PROGRAMINSTALL_DATA という変数の定義が必要です. (INSTALL_PROGRAM のデフォルト値は $(INSTALL) で、INSTALL_DATA のデフォルト値は ${INSTALL} -m 664 でなければなりません。)実際には, これらの変数で指定されるコマンドを使って,それぞれ実行形式ファイル, 非実行形式ファイルをインストールします. 次のように使用します.

$(INSTALL_PROGRAM) foo $(bindir)/foo
$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a

あるいは、DESTDIR の値をターゲットのファイル名の頭に付けることもできます。こうしておくと、インストーラが、実際の目標のファイルシステムに後でコピーできるような、インストールのスナップショットを作ることが出来るようになります。Makefile で DESTDIR の値を設定しないこと。また、インストールされるファイルにそれを含めないこと。DESTDIR のサポートを追加すると、上の例は次のようになる。

$(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo
$(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a

インストールコマンドの第二引数には,ディレクトリ名でなく,ファイル名を指定するようにします.一つのコマンドで,一個のファイルをインストールするようにします.


Node:Directory Variables, Next:, Previous:Command Variables, Up:Makefile Conventions

インストールディレクトリ

インストール先のディレクトリ名は必ず変数で与えなければなりません. そうしておけば標準的でない場所にインストールするのが容易になります. 変数の名前を以下に示します.これらは標準的なファイルシステム構成に基づくものです.これに似たものが SVR4, 4.4BSD, GNU/Linux, Ultrix v4 等の最近のオペレーティングシステムで使われています.

最初の二つの変数は,インストールのトップディレクトリを設定します. 他の全てのインストールディレクトリは,このどちらかのサブディレクトリでなければなりません.また,この二つのディレクトリには何も直接インストールしてはいけません.

prefix
以下に現れる変数のデフォルト値を構成するのに使われるプレフィックス. prefixのデフォルト値は /usr/local でなければならない. 完全な GNU システムを構築する際には,このプレフィックスは空で, /usr は, / へのシンボリックリンクとなる予定である. (Autoconf を使うなら, @prefix@ と書く.)

プログラムを構築するときに使った prefix の値と異なる値を使って make install を実行した場合、そのプログラムを再コンパイルすべきではない。

exec_prefix
以下の変数のうち,いくつかの変数のデフォルト値に使われるプレフィックス. exec_prefix のデフォルト値は $(prefix) でなければならない. (Autoconf を使うなら, @exec_prefix@ と書く.)

一般的に, $(exec_prefix) は計算機に固有のファイル(実行形式ファイルやライブラリ)を置くディレクトリに使われる. 一方, $(prefix)はその他のディレクトリ用に直接使われる.

プログラムを構築するときに使った exec_prefix の値と異なる値を使って make install を実行した場合、そのプログラムを再コンパイルすべきではない。

実行可能プログラムは,以下のディレクトリのどれか一つにインストールされます.

bindir
ユーザが実行可能な実行形式プログラムをインストールするディレクトリ. これは通常, /usr/local/bin にすべきで, $(exec_prefix)/bin と書く. (Autoconf を使うなら, @bindir@ と書くこと.)
sbindir
実行可能プログラムのうち,シェルから実行可能だが, 一般にはシステム管理者しか使わないものをインストールするディレクトリ. これは通常 /usr/local/sbin とすべきで, $(exec_prefix)/sbin と書く. (Autoconf を使うなら, @sbindir@ と書くこと.)
libexecdir
ユーザが直接実行するのではなく, 他のプログラムが呼び出すような実行可能プログラムをインストールするディレクトリ. これは通常 /usr/local/libexec とすべきで, $(exec_prefix)/libexec と書く. (Autoconf を使うなら, @libexecdir@ と書くこと.)

プログラムが実行中に使用するデータファイルには,二つの分類方法があります.

以上のことから,6つの可能性があることがわかります. しかし,オブジェクトファイルとライブラリは別にして,我々はアーキテクチャ依存ファイルを使うのは勧めません. データファイルはアーキテクチャに依存しないようにしたほうが綺麗ですし, またそれは難しいことではないからです.

そのため, Makefile では以下の変数を使ってディレクトリを指定します.

datadir
プログラムが実行中に参照するデータファイルのうち,読み取り専用で, アーキテクチャ独立のファイルを置くディレクトリ. これは通常 /usr/local/share とすべきで, $(prefix)/lib と書く. (Autoconf を使うなら, @datadir@ と書くこと.) 特別な例外として,以下の $(infodir)$(includedir) を参照.
sysconfdir
ある一つのマシン-すなわち,コンフィギュレーションを行ったホストに関する読み取り専用データファイルをインストールするディレクトリ. メールやネットワークのコンフィギュレーションファイルや, /etc/passwd 等が該当します.このディレクトリに置くファイルは全て ASCII テキストファイルである必要があります.このディレクトリは通常は/usr/local/etc とすべきで, $(prefix)/etc と書きます. (Autoconf を使うなら, @sysconfdir@ と書きます.)

ここに実行可能ファイルをインストールしてはいけません. (この場合,実行可能ファイルはおそらく $(libexecdir)$(sbindir)に置くべきでしょう.) プログラムを普通に使った場合に更新されるファイルもまた,インストールしてはいけません.(プログラムの目的がシステムのコンフィギュレーションを変更することにある場合は除きます.) そういうファイルは,おそらく$(localstatedir) に置くべきです.

sharedstatedir
アーキテクチャに依存しないデータファイルのうち,プログラムが実行中に更新するファイルをインストールするディレクトリ. 通常は /usr/local/com とすべきで, $(prefix)/com と書きます. (Autoconf を使うのなら, @sharedstatedir@ と書きます.
localstatedir
プログラムが実行中に更新するファイルのうち,特定の一つのマシンにだけ関係するファイルをインストールするディレクトリ. ユーザがパッケージの操作をコンフィギュレーションするために, このディレクトリに置かれたファイルを更新する必要があってはいけません.そのようなコンフィギュレーション情報は別のファイルにし, $(datadir)$(sysconfdir) に置きます. $(localstatedir) は通常 /usr/local/var とすべきで, $(prefix)/var と書きます. (Autoconf を使うのなら, @localstatedir@ と書きます.
libdir
オブジェクトファイルやオブジェクトコードのライブラリを置くディレクトリ. 実行形式をここにインストールしてはいけません. ここに置きたいと考えた実行形式はおそらく $(libexecdir) に置くのが正しいでしょう. libdir の値は通常 /usr/local/lib とすべきで $(exec_prefix)/lib と書く. (Autoconf を使うのなら, @libdir@ と書く.)
infodir
パッケージの Info ファイルをインストールするディレクトリ. デフォルトでは, /usr/local/info とすべきで, $(prefix)/info と書く. (Autoconf を使うのなら, @infodir@ と書く.)
lispdir
パッケージに Emacs Lisp ファイルがあれば,それをインストールするディレクトリ.デフォルトでは, /usr/local/share/emacs/site-lisp とすべきで, $(prefix)/share/emacs/site-lisp と書く.

Autoconf を使うのなら,デフォルトを @lispdir@ と書く. @lispdir@ が正しく動作するように, configure.in に以下の二行を追加する必要がある.

lispdir='${datadir}/emacs/site-lisp'
AC_SUBST(lispdir)

includedir
Cプリプロセッサ制御行 #include によりプログラムからインクルードされるヘッダファイルを置くディレクトリ. これは通常 /usr/local/include であるが $(prefix)/include と書く. (Autoconf を使うのなら, @includedir@ と書く.

GCC以外のコンパイラはディレクトリ /usr/local/include にあるヘッダファイルを参照しないので, ここにヘッダーファイルをインストールするのはGCCに対してだけ意味がある. GCCでコンパイルした時だけ動作するようになっているライブラリもあるので, そういう場合は問題ではない.しかし,他のコンパイラでコンパイルした時にも動作するようになっているライブラリもある. そのようなライブラリの場合はヘッダファイルは2箇所にインストールすべきである. その時は,片方をincludedir,もう一方を oldincludedirで指定する.

oldincludedir
GCC以外のコンパイラで使われる #includeヘッダファイルを置くディレクトリ. これは通常 /usr/includeである. (Autoconf を使うのなら, @oldincludedir@ と書く.)

Makefile 中のコマンドは, oldincludedirが空でないかどうかチェックしなければならない.もし空なら,使ってはいけない. ヘッダファイルの二番目のインストールはやめるべきである.

各(ソフトウェア)パッケージは,同じパッケージが提供したものでない限り, このディレクトリにすでに存在しているヘッダーを置き換えるべきではない. つまり,Foo というパッケージが foo.h というヘッダーファイルを提供している場合, このヘッダーファイルをoldincludedir ディレクトリにインストールするのは, 次のどちらかの場合だけにすべきである. (1) foo.h がそのディレクトリにない場合,(2) パッケージ Foo が提供した foo.h が存在する場合.

foo.h が Foo というパッケージから来たのものかどうかが分かるように, ファイルの中に,コメントの一部として特別な文字列を埋め込んでおいて, grep コマンドで調べるようにする.

Unix 形式のマンページは以下のどこかにインストールします.

mandir
マンページがもしあれば,それをインストールするトップディレクトリ. このディレクトリは,通常 /usr/local/manになるが, $(prefix)/man と書くべきである. (Autoconf を使うのなら, @mandir@ と書く.)
man1dir
マンページのセクション 1 を置くディレクトリ. $(mandir)/man1 と書く.
man2dir
マンページのセクション 2 を置くディレクトリ. $(mandir)/man2 と書く.
...
GNUソフトウェアの主なドキュメントはマンページにしてはいけない. かわりにTexinfoで書くこと.マンページは GNUソフトウェアを Unix で動かす人々のためにあり,それは二義的な目的にすぎないから.
manext
インストールされたマンページのファイル名の拡張子.ピリオドと適切な数字から成る.通常は .1 にする.
man1ext
マンページのセクション1をインストールする時の拡張子.
man2ext
マンページのセクション2をインストールする時の拡張子.
...
複数のセクションにマンページをインストールする必要のあるパッケージならば manext のかわりにこれらの名前を使う.

そして最後に,以下の変数を設定する必要があります.

srcdir
コンパイルされるソースが置かれているディレクトリ.この変数の値は普通 configure シェルスクリプトによって挿入される. (Autoconf を使うなら, srcdir = @srcdir@ と書く.)

例:

# Common prefix for installation directories.
# NOTE: This directory must exist when you start the install.
prefix = /usr/local
exec_prefix = $(prefix)
# Where to put the executable for the command `gcc'.
bindir = $(exec_prefix)/bin
# Where to put the directories used by the compiler.
libexecdir = $(exec_prefix)/libexec
# Where to put the Info files.
infodir = $(prefix)/info

ユーザの指定した標準ディレクトリの一つに大量のファイルをインストールするようなプログラムの場合には, それらをプログラム固有のサブディレクトリにわけると便利でしょう. そうするなら, install ルールにはそのサブディレクトリを作成するように書かなければなりません.

ユーザが,上に挙げた変数の値にサブディレクトリ名を含めていると期待してはいけません.インストールディレクトリの変数名の集合に決まりを設けるのは,そうしておくとユーザが異なる GNU パッケージに対しても全く同じ値を指定できるようにするためです. この決まりが役に立つためには,全てのパッケージは, ユーザがそうした時に正しく動くように設計しなくてはなりません.


Node:Standard Targets, Next:, Previous:Directory Variables, Up:Makefile Conventions

標準的なターゲット

GNU プログラムの Makefile には以下のターゲットを入れなければなりません.

all
プログラム全体をコンパイルする.これはデフォルトのターゲットでなければならない. このターゲットでドキュメントファイルを再構築する必要はない.Info ファイルは通常は配布物に含まれるべきであり,DVI ファイルは明示的に要求されたときにのみ作成すべきである.

デフォルトでは,このターゲットのルールはコンパイルとリンクに -g オプションを使って,実行形式にデバッグ情報を入れる必要がある. デバッグ情報が無くても困らないユーザは,後で実行形式をストリップすれば良いのである.

install
プログラムをコンパイルし,実行形式やライブラリなどを実際に使用される名前でコピーする.プログラムが適切にインストールされたかどうかのテストがあれば, このターゲットで実行すべきである.

インストール時に実行形式をストリップしてはならない. デバッグ情報がいらないユーザ向けに install-strip というターゲットがある.

可能ならば, installターゲットに対応するルールはプログラムを構築したディレクトリは何もいじらず, make all を実行した直後の状態になるように書きましょう. こうすると,プログラムの構築とインストールを別の人が行うのが簡単になります.

ファイルをインストールすべきディレクトリが既に存在していなければ, それらのディレクトリを全て作らなければならない. これは,必要な全てのサブディレクトリだけではなく,変数 prefixexec_prefix の値で指定されるディレクトリを含む. このための一つの方法として,後述する installdirs ターゲットによる方法がある.

マンページ(man page)をインストールするコマンドには必ず先頭にも- をつけて, make がエラーを無視するようにすること. これは Unix マンページシステムがインストールされてないシステムに備えるためである.

Info ファイルをインストールするには,それらを $(INSTALL_DATA) (see Command Variables) を使って, $(infodir) にコピーし, その後, install-info プログラムがあればそれを実行する. install-info は,Info の dir ファイルを編集し, 指定した Info ファイルのメニューエントリを追加,更新するプログラムである. これは, Texinfo パッケージの一部である. 以下に Info ファイルをインストールするルールの例を示す.

$(DESTDIR)$(infodir)/foo.info: foo.info
        $(POST_INSTALL)
# There may be a newer info file in . than in srcdir.
        -if test -f foo.info; then d=.; \
         else d=$(srcdir); fi; \
        $(INSTALL_DATA) $$d/foo.info $(DESTDIR)$@; \
# Run install-info only if it exists.
# Use `if' instead of just prepending `-' to the
# line so we notice real errors from install-info.
# We use `$(SHELL) -c' because some shells do not
# fail gracefully when there is an unknown command.
        if $(SHELL) -c 'install-info --version' \
           >/dev/null 2>&1; then \
          install-info --dir-file=$(DESTDIR)$(infodir)/dir \
                       $(DESTDIR)$(infodir)/foo.info; \
        else true; fi

install ターゲットを書くときには、そこで使用するコマンドを全て三つのカテゴリに分類する必要があります。それは、ノーマルとプレインストールポストインストールです。See Install Command Categories.

uninstall
インストールされたファイル、すなわち install ターゲットが作成したコピーを全部消す.

このルールでは,コンパイルを行ったディレクトリを触ってはならない. ファイルをインストールしたディレクトリのみを更新すべきである.

アンインストールコマンドも,インストールコマンドと同様三つのカテゴリに分けられる. See Install Command Categories.

install-strip
install と同じ.ただし,インストールする際に実行形式ファイルをストリップする. 単純な場合, このターゲットは install ターゲットを使って以下のように簡単にできる。
install-strip:
        $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
                install

ただし、パッケージが本当の実行形式だけでなくスクリプトもインストールする場合は、install-strip ターゲットが単に install ターゲットを参照することはできない。実行形式はストリップしなければならないが、スクリプトはしてはならない。

install-strip はインストールの際のコピー元になる、構築ディレクトリにある実行形式をストリップすべきではない。インストールされたコピーだけをストリップすべきである。

読者のプログラムにバグがないという確信がない限り,実行形式をストリップするのはおすすめしない.ただし,バグがある場合, ストリップしてない実行形式をどこかに取っておいて,実際に実行するファイルはストリップしたものをインストールするというのは構わないだろう.

clean
プログラムを構築するうえで作成されたファイルを全部カレントディレクトリから消す.コンフィギュレーションを記録したファイルは消さない. 構築の際に作成される可能性があるが,配布物に含まれているので通常は作成しないファイルも保存する.

配布物に含まれていない .dvi ファイルは消す.

distclean
プログラムの構築やコンフィギュレーションの結果生じたファイルを全部カレントディレクトリから消す. ソースを展開してから他のファイルを作成することなくプログラムを構築した場合に, make distcleanとすると配布物だけを残すようにすべきである.
mostlyclean
cleanに似ているが,普通はコンパイルし直したくないようなファイルは消さない. 例えば, GCC の mostlyclean ターゲットは libgcc.a を消さない.これをコンパイルし直す必要は滅多にないし, 非常に時間もかかるからである.
maintainer-clean
カレントディレクトリにある, Makefile によって再構築可能なファイルをほぼ全部消す.

「ほぼ全部」というのは, make maintainer-clean を実行した場合, ファイル configure だけは, たとえ Makefile に書かれているルールから作り直すことが出来たとしても, 消してはならないからである. もっと一般的にいうなら, make maintainer-clean は, confiugre を実行して,プログラムの構築を解するのに必要なファイルは消してはいけないということである. この例外を除いて, maintainer-clean は構築可能なファイルを全部消す必要がある.

この maintainer-clean は,一般ユーザ向けではなくて, パッケージの保守担当者向けのターゲットである. make maintainer-clean で消されるファイルの中には, 作り直すのに特別なツールが必要なものもある. そういうファイルは配布物の中に含まれるのが普通なので, 読者のところで簡単に作り直せるかどうかは気にしていない. 誤って消してしまった場合,読者は,配布物をもう一度展開するはめになるだろうが,ご容赦を.

この点について注意を促すために,ターゲット maintainer-clean のコマンドの先頭には以下の二行を追加するようにして欲しい.

@echo 'This command is intended for maintainers to use; it'
@echo 'deletes files that may need special tools to rebuild.'

TAGS
プログラムのタグテーブルを更新する.
info
必要な Info ファイルを生成する.このルールを書くためには次のようにするのが一番である.
info: foo.info

foo.info: foo.texi chap1.texi chap2.texi
        $(MAKEINFO) $(srcdir)/foo.texi

Makefileの中で,変数 MAKEINFO を定義しなければならない. このターゲットは makeinfo プログラムを実行すべきである. makeinfo は Texinfo の配布物の一部である.

通常、GNU の配布物には Info ファイルが付いてくるので、ソースディレクトリにInfo ファイルが存在するということになります。このため、info ファイルについての Make のルールでは、ソースディレクトリで更新を行うように書く必要があります。ユーザがパッケージをコンパイルする際には、通常 Make は Info ファイルを更新しません。既に更新済のはずだからです。

dvi
すべての Texinfo のドキュメントから DVI ファイルを生成する. 例えば,以下のようにする.
dvi: foo.dvi

foo.dvi: foo.texi chap1.texi chap2.texi
        $(TEXI2DVI) $(srcdir)/foo.texi

Makefileで 変数 TEXI2DVI を定義しなければならない. このターゲットでは texi2dvi プログラムを実行させるべきである. texi2dvi はTexinfo の配布物の一部である.1 あるいは, 依存関係だけを書き, 後は GNU make にまかせる事もできる.

dist
配布のための tar ファイルを作る.tar ファイル中のファイル名の先頭には, 配布用のパッケージ名がサブディレクトリ名として付いてなければならない. このサブディレクトリ名にはバージョン番号も含める.

例えば, GCC バージョン1.40 配布用の tar ファイルは, gcc-1.40という名前のサブディレクトリに中身を展開するようになっている.

このための最も簡単な方法は,適切な名前のサブディレクトリを作成し, ln あるいは cpを使ってそのサブディレクトリにファイルをインストールし,そのサブディレクトリを tar すればよい.

tar ファイルは gzip を使って圧縮すること. 例えば, GCC バージョン 1.40 の,実際に配布されるファイル名はgcc-1.40.tar.gz となる.

dist ターゲット は,配布物が最新であることを保証するために, 配布物中のソース以外の全てのファイルに明示的に依存していなければならない. GNUコーディング標準の「リリース」の章を参照.

check
自己テスト(があれば)を実行する. ユーザはテストを実行する前にプログラムを構築しておかなければならないが, インストールしておく必要はない. 自己テストは, プログラムの構築後, インストールの前に実行されるという前提で書くべきである.

以下のターゲットはそれがあれば便利なプログラムのために習慣的な名前として提供します.

installcheck
インストールのテスト(があれば)を実行する.ユーザはこのテストを実行する前にプログラムを構築してインストールしなければならない.$(bindir) が検索パスにあると仮定してはいけない.
installdirs
installdirsというターゲットを追加して,ファイルがインストールされるディレクトリやその親ディレクトリを作るようにしておくと便利だろう. このために便利な, mkinstalldirs というスクリプトがある. このスクリプトは,Texinfo パッケージの中に含まれている. 次のように,ルールを書くと良い.
# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
        $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
                                $(libdir) $(infodir) \
                                $(mandir)

あるいは、DESTDIR をサポートしたいのであれば以下のようにする。

# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
        $(srcdir)/mkinstalldirs \
            $(DESTDIR)$(bindir) $(DESTDIR)$(datadir) \
            $(DESTDIR)$(libdir) $(DESTDIR)$(infodir) \
            $(DESTDIR)$(mandir)

このルールでは,コンパイルを行ったディレクトリを触ってはいけない. インストール先ディレクトリを作成すること以外はしてはならない.


Node:Install Command Categories, Previous:Standard Targets, Up:Makefile Conventions

インストールコマンドのカテゴリ

install ターゲットを書くときには、そこで使用するコマンドを全て、三つのカテゴリに分類する必要があります。三つのカテゴリとは、ノーマルとプレインストールポストインストールです。

ノーマルのコマンドは、各ファイルを適切な場所に移動し、モードを設定します。ノーマルコマンドは、パッケージに含まれているファイルをそのまま移動する場合以外は、どのファイルも変更していけません。

プレインストールとポストインストール用コマンドは、他のファイルを変更する可能性があります。特に、システムワイドなコンフィギュレーシンファイルやデータベースを変更し得ます。

プレインストールコマンドは、普通はノーマルのコマンドの前に実行され、ポストインストールコマンドは、ノーマルコマンドの後に実行されます。

ポストインストールコマンドのもっとも一般的な使い方は、install-info を実行することです。これは、ノーマルコマンドでは為し得ません。何故なら、ファイル全体がインストールされたパッケージから単独で由来しているのではないファイル(Info ディレクトリファイル)を変更するからです。これは、そのパッケージの Info ファイルをインストールするノーマルコマンドの後に実行する必要があるため、ポストインストールコマンドになっています。

プレインストールコマンドを必要とするプログラムはほとんどありませんが、必要な場合に備えてこの機能を入れています。

install の規則のコマンドを三つのカテゴリに分けるには、その間にカテゴリ行を挿入します。カテゴリ行は、次行以降のコマンドのカテゴリを指定します。

各カテゴリ行は、タブと特別な Make 変数、それに付加的なコメントからなります。三つの変数があり、各カテゴリに対し一つが対応します。変数名がカテゴリを指定します。カテゴリ行は、普通に make を実行した場合には何もしません。というのは、この三つの Make 変数は普通は未定義だからです(そして、makefile 中で定義すべきではありません).

以下に三つのカテゴリ行を、コメントに説明文を入れて、示します。

        $(PRE_INSTALL)     # Pre-install commands follow.
        $(POST_INSTALL)    # Post-install commands follow.
        $(NORMAL_INSTALL)  # Normal commands follow.

install 規則の先頭にカテゴリ行を入れなかった場合には、最初のカテゴリ行が現れるまで、全てのコマンドがノーマルと分類されます。

uninstall 用のカテゴリ行は以下の通りです。

        $(PRE_UNINSTALL)     # Pre-uninstall commands follow.
        $(POST_UNINSTALL)    # Post-uninstall commands follow.
        $(NORMAL_UNINSTALL)  # Normal commands follow.

プレアンインストールコマンドは、普通は Info ディレクトリファイルからエントリを削除するのに使います。

installuninstall ターゲットに、インストール過程のサブルーチンとして働くような依存物があるなら、それぞれの依存物に対するコマンドの最初にカテゴリ行を置くべきです。そして、主となるターゲットのコマンドもやはりカテゴリ行で始める必要があります。こうすることで、どの依存物が実際に実行されるかにはよらずに、各コマンドが正しいカテゴリに置かれることが保証されます。

プレインストールとポストインストールコマンドは、以下のものを除いてどんなコマンドも実行すべきではありません。

[ basename bash cat chgrp chmod chown cmp cp dd diff echo
egrep expand expr false fgrep find getopt grep gunzip gzip
hostname install install-info kill ldconfig ln ls md5sum
mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee
test touch true uname xargs yes

このようにコマンドを区別するのは,バイナリパッケージの作成を考慮したためです.バイナリパッケージはインストールする必要のある実行形式や他のファイルを全て持っており,独自のインストール方法も持っています. そのため,普通のインストールコマンドは実行する必要がないのです. しかし,バイナリパッケージはプレインストールコマンドとポストインストールコマンドを実行する必要があります.

バイナリパッケージを構築するためのプログラムは、プレインストールコマンドとポストインストールコマンドを抜き出すことで動作します。プレインストールコマンドを抜き出す一つの方法を示します。

make -n install -o all \
      PRE_INSTALL=pre-install \
      POST_INSTALL=post-install \
      NORMAL_INSTALL=normal-install \
  | gawk -f pre-install.awk

ここで、ファイル pre-install.awk は以下のようになっています。

$0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ {on = 0}
on {print $0}
$0 ~ /^\t[ \t]*pre_install[ \t]*$/ {on = 1}

プレインストールコマンドの抽出の結果のファイルは、バイナリパッケージのインストールの一部として、シェルスクリプトとして実行されます。


Node:Releases, Previous:Makefile Conventions, Up:Managing Releases

リリース

例えば Foo version 69.96 の配布物は, foo-69.96.tar.gzという名の gzip された tar ファイルとしてパッケージにしてください. これは foo-69.96 という名のサブディレクトリに展開されるようになっていなくてはなりません.

プログラムのインストールと構築時には,配布物中のどんなファイルも変更すべきではありません.プログラムの部分を構成しているファイルは,全てソースファイル非ソースファイルに分類されるべきだということです. ソースファイルは人間が書くもので,自動的には変更されません. 非ソースファイルは, Makefile の制御のもとに何らかのプログラムによってソースファイルから生成されるものです.

配布には README というファイルを入れなくてはなりません. このファイルでは, パッケージの名前と, それが何をするものであるのかの一般的な説明を行ないます. パッケージの中のサブディレクトリがあれば, 最上位のものついて, それぞれ目的が何かを説明するのも良いでしょう. README ファイルでは, パッケージのバージョン番号を述べたり, パッケージがどこに行けば見つかるかを記述しなくてはなりません.

README ファイルは, ファイル INSTALL について言及しなければなりません. INSTALL には, インストール手順の説明を書く必要があります.

また, REAMDE では, 複製条件を書いたファイルも参照していなければなりません. GNU GPL を使うのであれば, COPYING というファイルにそれを置くべきです. GNU LGPL を使うのであれば, COPYING.LIB というファイルに置くようにします.

通常,配布物の中に全てのソースファイルが入っていなければなりません. 非ソースファイルを入れてもかまいません.それらが最新でマシン独立ならば,通常の構築の際に決して変更されないでしょう. 我々は, 通常 Bison, lex, TeX, makeinfo により作成された非ソースファイルを含めています. 我々の配布物間の不要な依存関係を避ける助けになり, ユーザはインストールしたいどのパッケージであってもインストールできるようになります.

プログラムを構築, インストールする時に変更される非ソースファイルは絶対に 配布物に含めてはいけません. 非ソースファイルを配布したかったら,新しい配布を作る時にそれが最新であるかどうかをいつも確認してください.

配布物が展開されるディレクトリ(サブディレクトリも同様に)は, 誰でも書き込み可能(モード 777) になっていることを確認してください. これは,tar アーカイブ中のファイルのオーナーとパーミッションを保存するような古いバージョンの tar を使った場合,特権ユーザでなくても全てのファイルを引き出せるようにするためです.

配布中のファイルは全て誰でも読めるようになってることを確かめてください.

配布物中には14文字より長い名前のファイルがないことを確認しましょう. 同様に, プログラムを構築したときにできるファイルにも14文字より長い名前のものがないことを確認してください. その理由は, POSIX 標準を間違って解釈しているシステムがあり, 昔のように名前を途中で切り落とす代わりに,長い名前のファイルをオープンすることを拒むからです.

配布物自体の中にシンボリックリンクを含んではなりません. tar ファイル中にシンボリックリンクがあると, シンボリックリンクをサポートしていないシステムでは展開できないからです. また, 一つのファイルに対して異なったディレクトリで複数の名前を使うことはしないでください. あるファイルシステムでは, これを扱えず, 配布物を展開できないからです.

ファイル名が全て MS-DOS上で一意的になることを確かめましょう. MS-DOSでのファイル名は,最初の8文字と,オプションで付くピリオドとそれに続く3文字以内の文字から成ります. MS-DOS はピリオドの前後両方で,余分な文字を切り捨てます.したがってfoobarhacker.cfoobarhacker.ofoobarha.cfoobarha.oに縮められるので区別されます.

*.texinfo または *.texi ファイルを印刷するのに使うtexinfo.texのコピーは必ず配布物中にいれましょう.

もし, regex, getpot, obstack, termcap などの小さな GNU ソフトウェアパッケージが必要なら, 一緒に配布物に入れましょう. 一緒に入れとかないと,配布ファイルは少し小さくなりますが, 他にどんなファイルを手に入れたらいいのか知らないユーザにとっては不便です.


Node:References, Next:, Previous:Managing Releases, Up:Top

フリーでないソフトウェアとドキュメントを参照することについて

GNU のプログラムでは, フリーでないプログラムを使用するのを進めるのは避けなくてはなりません. 人々が独占的なプログラムを書いたり, 使ったりするのを止めることはできません. だが, 新しいユーザに独占的なプログラムを宣伝する手助けをするのを避けることは可能ですし, 避けるべきでもあります.

読者の作成したパッケージを, フリーでない OS や他のフリーでない基本的なパッケージ上に構築する方法を述べることが重要なこともあるでしょう. そういう場合は, フリーでないパッケージやシステムの名前に触れるのは可能な範囲で必要最小限に留めて欲しいのです. その独占的なプログラムについての情報をさらに得るためにはどこをみれば良いかという参照情報は一切含めないで欲しいのです. 目標としては, 既に独占的なプログラムを使っている人々が, 読者のフリーなプログラムの使い方についての必要な助言を受け取るように仕向けることにする必要があります. 一方, 独占的なプログラムをまだ使っていない人々には, その独占的なプログラムに興味を持たせるようなことは一切目に触れさせないようにするのです.

同様に, GNU のパッケージでは, フリーソフトウェアについて, フリーでないドキュメントを参照させるようにしてはなりません. フリーソフトウェアにはフリーなドキュメントを付ける必要性は, 今や, GNU プロジェクトの大きな目標になっています. フリーなドキュメントを切実に必要としているということを示すためには, フリーでないドキュメントを推奨することで我々の立場を弱くしてはならないのです.


Node:Copying This Manual, Next:, Previous:References, Up:Top

本マニュアルの複製について


Node:GNU Free Documentation License, Up:Copying This Manual

GNU Free Documentation License

Version 1.1, March 2000

Copyright © 2000 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA  02111-1307, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
  1. PREAMBLE

    The purpose of this License is to make a manual, textbook, or other written document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

    This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

    We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

  2. APPLICABILITY AND DEFINITIONS

    This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".

    A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

    A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

    The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.

    The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.

    A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".

    Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.

    The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

  3. VERBATIM COPYING

    You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

    You may also lend copies, under the same conditions stated above, and you may publicly display copies.

  4. COPYING IN QUANTITY

    If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

    If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

    If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

    It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

  5. MODIFICATIONS

    You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. In any section entitled "Acknowledgments" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgments and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.

    If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

    You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

    You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

    The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

  6. COMBINING DOCUMENTS

    You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.

    The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

    In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgments", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."

  7. COLLECTIONS OF DOCUMENTS

    You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

    You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

  8. AGGREGATION WITH INDEPENDENT WORKS

    A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.

    If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.

  9. TRANSLATION

    Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.

  10. TERMINATION

    You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

  11. FUTURE REVISIONS OF THIS LICENSE

    The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

    Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

  Copyright (C)  year  your name.
  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.1
  or any later version published by the Free Software Foundation;
  with the Invariant Sections being list their titles, with the
  Front-Cover Texts being list, and with the Back-Cover Texts being list.
  A copy of the license is included in the section entitled ``GNU
  Free Documentation License''.

If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being list"; likewise for Back-Cover Texts.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.


Node:Index, Previous:Copying This Manual, Up:Top

Index

Table of Contents


Footnotes

  1. texi2dvi の実際の作業は TeX が行う. TeX は Texinfo には含まれていない.