make: ファイルの同期

自分でプログラムを作成する場合、コマンドラインからccと実行して 実行ファイルa.outを作成されている人が多かと思います.

プログラムが1つのソースファイルから作成されている場合、 また全くオプションを指定しないような 簡単なプログラムの場合は、このようなコンパイル方法が、単純かつ明解 ですが、プログラムが複数本から構成されているような場合や、インクルードファイルや リンク等の色々なオプションを指定しなければならないような時には、 コマンドラインでのタイプが面倒になります.

 cc -c prog1.c
 cc -c sub1.c
 cc -c sub2.f
 cc -o prog -I ../include -L ../lib prog.c
このような場合に、makeというUNIXで提供されているユーティリティを 使用することによって、コンパイルの手間を省くことができます.

このmakeコマンドを使用すると、複数のソースファイルが存在する場合、 どのソースファイルが更新されたかといった情報をもとにコンパイルを行うので 全てのソースファイルを再コンパイルすることがありません.

Makefileについて

makeコマンドを使用する場合には、Makefileもしくはmakefileというコンパイルの 指定を行うファイルを作成します.

prog.c, sub1.c, sub2.c, sub3.cという名前のソースファイルが存在する場合の Makefileの例を示します.

例:  (行番号は説明のため)
  1   CC      = cc
  2   CFLAGS  = -c
  3   TARGET  = prog
  4   OBJS    = prog.o \
  5             sub1.o \
  6             sub2.o \
  7             sub3.o
  8
  9   $(TARGET):      $(OBJS)
 10           $(CC) -o $@ $(OBJS)
 11   
 12   $(OBJS):
 13           $(CC) $(CFLAGS) $*.c
 14  
 15   clean:
 16           -rm -f $(OBJS) core
 17   
 18   clobber:        clean
 19           -rm -f $(TARGET)
(説明) $(TARGET)は、progを示します.
$(OBJS)は、prog.o, sub1.o, sub2.o, sub3.oを示します.

9行目の$(TARGET)や12行目の$(OBJS)などをターゲットといい、 9行目の$(OBJS)を依存ファイルといいます. ターゲット$(TARGET)が$(OBJS)に依存していることを意味します.

10行目の$(CC)で始まる行をコマンド行といい、 $(OBJS)がターゲット$(TARGET)よりも新しい場合、 もしくは$(OBJS)が存在しない場合にコンパイルを行います. -o $@ はTARGETと同じ名前(ここではprog)の実行ファイルを作成する ことを意味します.

また、prog.oは、prog.cより作成されるので、prog.cが prog.oよりも新しい場合はコンパイルを行います. sub1,sub2,sub3についても同様です.

makeファイルの書式には以下に示す決まりがあります.

  • ターゲット/依存関係行は1桁目から書き始めます.
  • コマンド行は必ずtabにより字下げを行います. 例:$(CC) -o $@ $(OBJS)
  • 継続行が存在する場合、行末にバックスラッシュ \を付けます.
  • コメントはシャープ記号#で始めます.

makeの実行

Makefileを用いてmakeコマンドを実行します.
  % make
  cc -c prog.c
  cc -c sub1.c
  cc -c sub2.c
  cc -c sub3.c
  cc -c sub4.c
  cc -o prog prog.o  sub1.o  sub2.o  sub3.o
もう一度makeコマンドを実行してみます.
  % make
  `prog' is up to date.
prog.o, sub1.o, sub2,o, sub3,o、およびprog.c, sub1.c, sub2.c sub3.cが 更新されていないので、コンパイルを行いません. ソースファイル変更後、makeコマンドを実行すると変更されたソースファイル だけがコンパイルされ、progが作成されます.

オブジェクトの削除

実行ファイルが正常に作成された場合、オブジェクトファイル(*.o)は 必要なくなります.ディスクスペースを有効にう使用するためにも、 オブジェクトファイルを削除するように心がけて下さい.

ただし、毎回rmコマンドによって削除していたのでは面倒であるうえ、 間違って必要なファイルを消してしまう場合があります. このような事がないよう、Makefile内で削除のターゲットを作成します.

Makefile内15行目cleanターゲットではオブジェクトファイルと、 coreファイルを削除しています. 18行目clobberターゲットでは、cleanターゲットを実行後、実行ファイルprogも 削除しています.

makeコマンドではターゲットを指定して実行すると、 そのターゲットだけを実行します. 以下のように実行すると、cleanターゲットだけが 実行されます.

  % make clean