雑知識
訪問数 1574   最終更新 2009-06-18 (木) 17:30:14

> 分割コンパイルとmake
> 分割コンパイルとmakeその2
> 分割コンパイルとmakeその3

分割コンパイルとmake その4

分割コンパイルは、大きなプログラムを作るときに、よく使われます。メリットの1つは、ファイルを分割したことで、一部を修正したときにすべてのソースプログラムをサイドコンパイルする必要がなくなること、でしょう。

bunkatsu_compile.png

右図で見たように、main.cとutil.cは別々にコンパイルできます。だから、main.cを変更したときに、util.cを再コンパイルしてutil.oを作り直す必要が無く、前に作ったutil.oをそのまま使って、3ステップ目の「main.oとutil.oのリンクエディット」のステップに進むことが出来ます。ソースファイルが非常に大きくてたくさんのファイルからなる場合、これはとても便利です。

ただ、どのファイルを作り直す必要があるのか、きちんと把握している必要があります。特に、ヘッダーファイルを書き直した場合には、影響する範囲が1つの.cファイルとは限らないので、やっかいです。そのあたりも含めて、コンパイルの管理をする仕組が考えられています。1つは旧来から用いられているmakeと呼ばれる仕組で、もう1つは最近よく使われる「統合開発環境」(IDE, Integrated Development Environment)です。後者はコンパイルの管理だけでなく、デバッグの環境なども含みます。たとえばMicrosoftのVisual Studio XXX (XXXはC++, C#, Javaなど)とか、オープンソースのEclipseなどが有名です。

IDEは便利で、使えるなら使うほうがいいと思いますが、いつでも使えるわけではありません。C言語では大半がmakeをベースとした管理をしているように思います。というわけで、makeを見てみましょう。

makeは、次の2つのことをすると使えるようになります。1つは、makeをコントロールする "Makefile" と呼ばれるファイルを作ること、もう1つは、コマンドmakeということ、です。Makefileの作り方・使い方は、ネットワーク上のあちこちに解説がありますので、それを参考にしてください。ここでは簡単に原理だけを紹介します。

makeでは、Makefileにファイルの依存性(dependency)を記述します。たとえば、上の図の例で言うと、
  オブジェクトファイル main.o は、main.c に依存する。つまりmain.cを書き直したらmain.oを作り直す必要がある。
  更に、分割コンパイルとmakeその3で、ヘッダーファイル init.h を使うように書き換えたので、main.oは、init.h にも依存する。つまりinit.hを書き直したらmain.oを作り直す必要がある。
  同様に、util.o は、util.c に依存するし、更にinit.hにも依存する。
ここまでで図の左半分のステップが済んだ。右半分は、
  実行可能形式ファイルmainは、main.oとutil.oに依存する。この2つのいずれかが変更されれば、mainも作り直す必要がある。
というわけです。ここで、mainはmain.oに依存するので、当然main.cやinit.hにも間接的に依存するわけですが、それは書かなくてもmakeには分かります。

依存関係はこれでいいのですが、どうやって作るか、たとえばmain.cからmain.oをどうやって作るか、コンパイルオプション等が何か、などを指示する必要があります。更に、このMakefileの全体の最終ゴールが何であるかを書いておけば、単にmakeと命令するだけでその最終ゴールを作ってくれます。(指示しないと、依存関係だけでは、実際に何を作ればいいかわからん、ということになります)

書き方のルール(文法)の初歩的な部分だけを紹介します。基本単位は、

作りたいもの :  依存するファイルのリスト
   <TAB>    実際に処理する時のコマンド、オプションなど

の2行で、これを複数個、間に空白行を入れて、書きます。2行目の始まりが<TAB>コード(TABキー)であることに注意してください。この<TAB>の代わりに空白を入れると、正しく動きません。必ず<TAB>コードでなければならない。コメント行は#で始まる行です。

一番原始的な書き方をしたMakefileのサンプルは

# Makefile Sample
target: main      最終ゴールの指定
 
main.o: main.c
        gcc -c -o main.o -Wall main.c

util.o: util.c
        gcc -c -o util.o -Wall util.c

main:   main.o util.o
        gcc -o main main.o util.o -lm -Wall

clean:
        rm *.o main

要するに、最終ゴールはmainが作りたい、mainの作り方は4エントリー目にあるように、main.oとutil.oを結合するが、そのときに-lm (mathライブラリ)を含める。
main.oとutil.oの作り方は2エントリー目と3エントリー目にある通り。ここで-Wallは、コンパイル時の警告メッセージ(Warning)をすべて出せ、としていますが、これを入れるかどうかはその時々で判断。

最後のエントリーのcleanは、コンパイルしたときに出来るファイル main.oとutil.oそれから最終結果の実行形式ファイルmainを、「消去する」(UNIXのrm 〜 remove コマンド)もので、make clean と起動してやるとこのターゲットcleanを実行します。

もっと、楽な書き方、凝った書き方は、ネットにいっぱい落ちているので、それを参考にしてください。

追加の知識 〜 ライブラリとは


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-06-18 (木) 17:30:14 (4761d)