[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

9. その他の派生されるオブジェクト

AutomakeはCプログラムではない派生されるオブジェクトを扱うことが可能で す.このようなオブジェクトを実際にビルドするサポートを明示的に供給する 必要があることもありますが,Automakeは自動的にインストールと配布物を扱 います.

9.1 実行可能なスクリプト  Executable scripts
9.2 ヘッダファイル  Header files
9.3 アーキテクチャ非依存のデータファイル  Architecture-independent data files
9.4 ビルドされているソース  Derived sources


9.1 実行可能なスクリプト

スクリプトのプログラムを定義しインストールすることが可能です.そのよう なプログラムは,`SCRIPTS'プライマリを使用してリストアップします. Automakeは,スクリプトに対する依存性の定義を全く行ないません. `Makefile.am'に適切なルールを含ませるべきでしょう.

Automakeはスクリプトがオブジェクトからの派生物であると想定しません.そ のようなオブジェクトは手動で削除する必要があります(see section 13. クリーンされるもの).

automakeプログラム自身は,`automake.in'から生成されるPerl スクリプトです.これを処理する方法は以下のようになります.

 
bin_SCRIPTS = automake
CLEANFILES = $(bin_SCRIPTS)

do_subst = sed -e 's,[@]datadir[@],$(datadir),g' \
            -e 's,[@]PERL[@],$(PERL),g' \
            -e 's,[@]PACKAGE[@],$(PACKAGE),g' \
            -e 's,[@]VERSION[@],$(VERSION),g' \
            ...

automake: automake.in Makefile
        $(do_subst) < $(srcdir)/automake.in > automake
        chmod +x automake

御覧のように -- スクリプトはビルド可能なので,デフォルトでは配布され ません.配布されるべきスクリプトは,他のプライマリとしてdist_プ レフィクスを使用して指定することが可能です.例えば,以下の `Makefile.am'では,`my_script'を配布し$(sbindir)にイ ンストールするように宣言されています.

 
dist_sbin_SCRIPTS = my_script

スクリプトオブジェクトはbindirsbindirlibexecdir,またはpkgdatadirにインストールすることが可能 です.

インストールする必要が無いスクリプトはnoinst_SCRIPTSにリストアッ プすることが可能で,その中でmake checkだけで必要なものは check_SCRIPTSに書くべきです.


9.2 ヘッダファイル

ヘッダファイルは,`HEADERS'等の変数で指定します.ヘッダファイルは 通常インストールされないので,noinst_HEADERS変数が最も多く使用 されます.(9)

すべてのヘッダファイルは,どこかにリストアップする必要があります.行方 不明のものは配布物に含まれません.プログラムのソースの残りにインストー ルしないヘッダをリストアップすることが,最も分かり易くなることが多いで す.See section 8.1 プログラムのビルド. `_SOURCES'変数でリストアップされているヘッ ダを,`_HEADERS'変数でリストアップする必要はありません.

ヘッダはincludediroldincludedir,または pkgincludedirにインストールすることが可能です.


9.3 アーキテクチャ非依存のデータファイル

Automakeは,`DATA'等の変数を使用して様々なデータファイルのインス トールをサポートします.

そのようなデータは,ディレクトリdatadirsysconfdirsharedstatedirlocalstatedir,またはpkgdatadirに インストールすること可能です.

デフォルトで,データファイルは配布物に含まれません.もちろん, `dist_'接頭辞を使用することで,変数ごとにこの(デフォルト動作)を変 更することが可能です.

Automakeでその補助データファイルを宣言する方法は,以下のとおりです.

 
dist_pkgdata_DATA = clean-kr.am clean.am ...


9.4 ビルドされているソース

Automakeの自動的な依存性追跡は,コンパイルの副作用として働くので (see section 8.15 自動的な依存性追跡),ブートストラップで問題があります.ターゲットは, 依存性が作成されるまでコンパイルされるべきではありませんが,これらの依 存性は最初にコンパイルされるまで知ることができません.

通常,依存性は配布されているソースにあるので,これは問題になりません. それらは既に存在し,ビルドする必要はありません.`foo.c'が `foo.h'をインクルードしていると仮定します.最初に`foo.o'にコ ンパイルするとき,makeは`foo.o'が`foo.c'に依存する ことを知っています.このコンパイルの副作用として,それ以降の makeの呼び出しで尊重されるように,depcompが `foo.h'の依存性を記録します.この条件では,問題がないことが明らか です.つまり,`foo.o'が存在せずビルドされていない(依存性には影響 されない),または,正確な依存性が存在し`foo.o'をリビルドすべきか どうかを決定するために使用することが可能であるという,いずれかの状態に なっています.

最初にmakeを実行するとき`foo.h'が存在しない場合は,別の 話になります.例えば,`foo.h'をビルドするルールがあると仮定します. このとき,コンパイラが`foo.h'を見つけることができないので, `file.o'のビルドは失敗します.makeは,依存性の情報が足 りないため,最初に`foo.h'をビルドするルールを開始することができま せん.

BUILT_SOURCES変数でこの問題を回避します.BUILT_SOURCESで リストアップされているファイルは,他のターゲットを処理する前に, make allmake check(または,make installでも)作 成されます.しかし,そのようなソースファイルは,明示的に他の `_SOURCES'で記述し,要求していない限りコンパイルされません.

このため,導入する例を決定するため,make allmake check で(`foo.o'を含む)他のターゲットをビルドする前に`foo.h'を確実 に入手できるよう,BUILT_SOURCES = foo.hを使用します.

ビルドプロセスの初期に作成する必要があるファイルは,この変数でリストアッ プすることが可能なので,BUILT_SOURCESは実際にはちょっと誤った名 称です.さらに,ビルドされたすべてのソースを,BUILT_SOURCESにリ ストアップする必要はありません.例えば,生成される`.c'ファイルは, 関連するオブジェクトへの依存性を知っているので,(他のソースからインク ルードされない限り)BUILT_SOURCESに書く必要はありません.

BUILT_SOURCESmake allmake check,そして make installだけを尊重するということを強調しておくのが重要かも しれません.これは,指定したターゲット(例えば,make foo)が,ビ ルドソースで依存されていない場合,クリーンなツリーではビルドできないこ とを意味します.しかし,その前にmake allを実行している場合,依 存性が既に利用可能なように求まっているので,成功します.

次のセクションでは,ビルドされているソースを処理する簡単な例を説明し, 議論していきます.

9.4.1 ビルドされているべきソースの例  Several ways to handle built sources.


9.4.1 ビルドされているべきソースの例

インストールに依存していて,配布には依存していない`bindir.h'をイ ンクルードしている`foo.c'を仮定します.それはビルドで要求されます. ここで,`bindir.h'は,(`configure'から継承される) make変数bindirの値をもつプリプロセッサマクロ bindirを定義しています,

我々は以下の実装を提案します.ビルドされているソースを処理するすべての 方法のリストを網羅していませんが,この問題に遭遇した場合,ちょっとした アイデアにはなるでしょう.


最初の試み

最初の実装は,前のセクションのブートストラップの問題を説明します (see section 9.4 ビルドされているソース).

以下は,試験的な`Makefile.am'です.

 
# This won't work.
bin_PROGRAMS = foo
foo_SOURCES = foo.c
nodist_foo_SOURCES = bindir.h
CLEANFILES = bindir.h
bindir.h: Makefile
        echo '#define bindir "$(bindir)"' >$@

Automakeは,`foo.c'が`bindir.h'をインクルードすることを知ら ないので,この設定では動作しません.自動的な依存性の追跡はコンパイルの 副作用として動作するので,`foo.o'の依存性は,`foo.o'がコンパ イルされた後になって判明すること(see section 8.15 自動的な依存性追跡)を覚えておいて下 さい.症状は以下のようになります.

 
% make
source='foo.c' object='foo.o' libtool=no \
depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \
depmode=gcc /bin/sh ./depcomp \
gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c
foo.c:2: bindir.h: No such file or directory
make: *** [foo.o] Error 1


BUILT_SOURCESの使用

解決方法は,他のものをビルドする前に`bindir.h'をビルドすることを 要求することです.これこそが,BUILT_SOURCESが意味することです (see section 9.4 ビルドされているソース).

 
bin_PROGRAMS = foo
foo_SOURCES = foo.c
BUILT_SOURCES = bindir.h
CLEANFILES = bindir.h
bindir.h: Makefile
        echo '#define bindir "$(bindir)"' >$@

`bindir.h'が最初にビルドされる様子を見て下さい.

 
% make
echo '#define bindir "/usr/local/bin"' >bindir.h
make  all-am
make[1]: Entering directory `/home/adl/tmp'
source='foo.c' object='foo.o' libtool=no \
depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \
depmode=gcc /bin/sh ./depcomp \
gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c
gcc  -g -O2   -o foo  foo.o
make[1]: Leaving directory `/home/adl/tmp'

しかし,以前にいったように,BUILT_SOURCESallcheck,そしてinstallターゲットだけにしか適用されません. これでは,make fooを明示的に実行すると失敗します.

 
% make clean
test -z "bindir.h" || rm -f bindir.h
test -z "foo" || rm -f foo
rm -f *.o
% : > .deps/foo.Po # Suppress previously recorded dependencies
% make foo
source='foo.c' object='foo.o' libtool=no \
depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \
depmode=gcc /bin/sh ./depcomp \
gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c
foo.c:2: bindir.h: No such file or directory
make: *** [foo.o] Error 1


依存性の手動保存

通常,make allの前にmake fooにようにターゲットをビルドす ることはないので,前回の例のようにBUILT_SOURCESで十分幸せになれ ます.しかし,これで問題がある場合,BUILT_SOURCESを避け, `Makefile.am'に明示的にそのような依存性を記録することが可能です.

 
bin_PROGRAMS = foo
foo_SOURCES = foo.c
foo.$(OBJEXT): bindir.h
CLEANFILES = bindir.h
bindir.h: Makefile
        echo '#define bindir "$(bindir)"' >$@

foo.oすべての依存性をリストアップする必要はなく,ビル ドに必要なものだけをリストアップします.依存性が既に存在する場合,最初 のコンパイルは邪魔をせず,通常の依存性の追跡コードが記録されます.(こ の最初のコンパイルの後の依存性の追跡コードも,foo.obindir.hの間に記録されることに注意して下さい.そのため,明示的 な依存性は最初のビルドだけで実際に役に立ちます.)

このような明示的な依存性を追加することで,十分に注意しておかないとちょっ と危険なことになります.これはAutomakeがルールを上書きしようとしないこ とに由来します(おそらく,より良いものを知っているでしょう). foo.$(OBJEXT): bindir.hで,foo.$(OBJEXT)をビルドするため に出力しようとするAutomakeのルールを置き換えます.この状況では, Automakeはfoo.$(OBJEXT):ターゲットを出力する必要がないので偶然 動作します.それは,代わりにサフィックスルールに関連します(すなわち .c.$(OBJEXT):).こうする場合は,常に生成される `Makefile.in'を調査して下さい.


`configure'から`bindir.h'をビルド

プリプロセッサマクロを`configure'から, `config.h'(see section `Defining Directories' in The Autoconf Manual),またはAC_CONFIG_FILESを使用し て`bindir.h.in'で(see section `Configuration Actions' in The Autoconf Manual)定義することも可能です.

この時点で,`configure'から`bindir.h'がビルドされることが明 確になり,この例はうまく動作します.`bindir.h'はターゲットをビル ドする前に存在しているので,依存性の問題は生じません.

Makefileは以下のように短くなります.`bindir.h'を記述する必要さえ ありません.

 
bin_PROGRAMS = foo
foo_SOURCES = foo.c

しかし,`configure'からソースをビルドすることが常に可能だというわ けではなく,特に,これらのソースが最初にビルドされるツールから生成され るときがそうなります....


`bindir.h'ではなく`bindir.c'をビルド

もう一つの魅力的な考えは,bindirを`bindir.o'からエクスポー トする変数や関数として定義し,`bindir.h'の代わりに`bindir.c' をビルドする方法です.

 
noinst_PROGRAMS = foo
foo_SOURCES = foo.c bindir.h
nodist_foo_SOURCES = bindir.c
CLEANFILES = bindir.c
bindir.c: Makefile
        echo 'const char bindir[] = "$(bindir)";' >$ 

`bindir.h'には,宣言された変数だけが含まれていて,ビルドする必要 がないため,問題になることはありません.`bindir.o'は,常に `bindir.c'に依存するので,`bindir.c'は最初にビルドされます.


最善の方法は?

もちろん万能薬はありません.それぞれの解決方法には長所と短所があります.

クリーンなツリーでmake fooを実行する能力が重要な場合, BUILT_SOURCESを使用することは不可能です.

Automakeのルールを間違ってオーバーライドしないように用心している場合, 明示的に依存性を追加しないでしょう.

`./configure'からファイルをビルドしたり,`.h'ファイルを `.c'ファイルに変換することは,常に可能だというわけではありません.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on February, 25 2004 using texi2html