make 前:makeって何するもん? 次:複数ファイルの場合

makeの第一歩: もっとも簡単な例

makeは、多くの場合、複数のソースファイルからなるプログラムのコンパイルに使われるのですが、もちろん単独のファイルのプログラムにとっても有用なユーティリティです。

例としてhello.cを扱ってみましょう。 ま、このコードなら

      % gcc hello.c

ですむと言えばすむんですけどね。でも、実際は

      % gcc -Wall -O2 -ascii -pedantic -g hello.c -lm -o hello

なぁ〜んて、沢山のオプションを付けたいときもあります。 特に-lmなんてつい忘れてしまいます(hello.cには不要だけど)。

さらにもうひとつ大きなメリット、makeを介してコンパイルすることにしておけば、emacsからのデバッグがとっても楽になります。 M-x compileでemacs内からコンパイルでき、もしエラーがあればC-x`をタイプすると自動的にエラーのあるファイルの該当行にカーソルが移動します。

make自身の使い方が難しかったりすると意味がないんですが、とっても簡単です。 プログラマはMakefileという名前のファイルにどのようにコンパイルするかの指示を書いておき、makeはそれを読んで依存関係に従ってコンパイルを実行します。 というわけで、このページは「Makefileの書き方の第一歩」なのです。


Makefileの書き方の第一歩

Makefileはコンパイルしたいファイルhello.cのあるディレクトリに置いてください。 この例の場合は、その内容は次の一行ですみます。 (gfortranの場合はFC=gfortranの一行も追加してください。 このページ内のコンパイラの指定、オプションの指定を参照。)

        hello: 

たったこれだけです。 このhelloは、「生成したい」実行ファイル名です。 生成したい対象のことを「ターゲット」と呼びます。 Makefileには、ターゲットは行頭からつめて書いてください。でないと動きません。

じゃ、makeを使ってみましょうか? hello.cとMakefileのあるディレクトリでmakeを実行します。 もしくは、hello.cを編集しているMule/EmacsのバッファでC-cC-cをタイプします。

      $ ls
      Makefile    hello.c
      $ make
      cc     hello.c   -o hello
      $ ls
      Makefile    hello.c    hello 

コンパイルされていますね。

この動作を追ってみましょう。makeコマンドは、

  1. ターゲットのhelloを生成するためのソースファイルをカレントディレクトリの中に探します。 この場合はターゲットにサフィックス.c(や.fなど)を補ったファイルを探します。
  2. hello.cを見つけると、ccを利用してコンパイルします。
  3. さらに、-oオプションを使って生成される実行ファイル名がhelloになるようにしてます。

ここで、makeがccを使ってhello.cをコンパイルしたのは、makeが.cで終わるファイルはCのソースファイルだと知っていたからです。

さて、ここでもう一度makeを実行してみましょう。

      $ make
      make: `hello' is up to date. 

up to date、つまり`hello'は最新であると言って何もコマンドを実行しません。 ターゲットである実行ファイルhelloはソースファイルhello.cから作られますが、helloを作った直後ですからhello.cに変更はなく、helloを作り直す必要はないとmakeが判断したのです。

makeはファイルのタイムスタンプ(ファイルの更新時刻)を再コンパイルの判断の基準にしています。 helloとhello.cのタイムスタンプを比較して、実行ファイルよりもソースファイルが新しければ再コンパイルの必要があると判断し、古ければ再コンパイルしなくてよいと判断するのです。

例えば、hello.cを保存しなおしてからmakeを実行すれば、論理的にはプログラムの変更がなくても再コンパイルされます。 また、touchコマンドを使えばタイムスタンプだけが変更できます。 これは意外と有用です。

      $ touch hello.c
      $ make
      cc     hello.c   -o hello 

コンパイラの指定、オプションの指定

「僕はgccを使いたいんだけど」というときにはMakefileに

        CC = gcc 

の一行を追加します。 C言語ではなくてFortranで、しかもgfortranを使いたいときは、

        FC = gfortran 

の一行を追加します。 「-Wallと-O2オプションを付けてコンパイルしたい」なら

        CFLAGS = -Wall -O2 

の一行の追加です。さらに「-lmなどのリンクオプションを付けたい」なら

        LOADLIBES = -lm 

を追加します。 これらはすべて、最初のターゲット(例ではhello:)より前に書きます。 以上の全てを追加したMakefileは次のようになります。

        CC = gcc
        CFLAGS = -Wall -O2
        LOADLIBES = -lm

        hello: 

このMakefileを使ってmakeしてみましょう。

      $ touch hello.c
      $ make
      gcc -Wall -O2    hello.c -lm  -o hello 

gccが使われてますし、指定したオプションがついていますね? リンカへのオプションもLDFLAGSで指定できます。

単独のファイルのコンパイルの時でも、makeの4文字でEmacsの中からならC-cC-cでコンパイルできるのはとっても楽だと思いませんか? なにせプログラミングにはデバッグ、つまり再コンパイルがつきものなんですから。 日にちを置いてからのコンパイルのときにもどんなオプションが必要だったから悩むこともなくなります。


make 前:makeって何するもん? 次:複数ファイルの場合
小栗栖 修
メールアドレス: ogurisu[AT]kanazawa-u.ac.jp ([AT]を@におきかえてください)