make 改訂版(序文, 1, 2章)

序文

makeとは?

Makefileやあらかじめ定義された規則にそって、シェルが実行するコマンド列を生成するコマンドジェネレータ

1章 簡単なメイクファイルを書く

make を実行した結果出来上がるものをターゲット、ターゲットを作るために必要なものをコンポーネントとすると、
make の行う作業は、

  1. Makefileからターゲットに対するコンポーネントを調べる
  2. コンポーネントに対する下位コンポーネントがあるか再帰的に調べる
  3. 更新時刻を調べて下位コンポーネントが新しい or コンポーネントがなければコンポーネントを作成し、全コンポーネントを最新化する
  4. 更新時刻を調べてコンポーネントが新しい or ターゲットがなければターゲットを作成する

Makefileを書く上でよくするミスをチェックするには、

cat -t -e Makefile
  -t : タブを^Iと表示(コマンド行がタブで始まっているかチェック)
  -e : 行末を$と表示(行末に不要なスペースがないかチェック)

2章 マクロ

マクロの定義

マクロの定義で注意することは、

  • マクロに定義する値を引用符('や")で囲むと引用符ごとマクロに定義される
  • マクロを定義する順番を気にする必要はないが、依存関係で参照される前に定義しておかないとだめ

マクロを定義する方法は次の3つ

これに加えて、デフォルトで定義されているマクロもある

マクロの参照

4つあるマクロの参照順は、優先順位の高いものから

  1. コマンドライン上で指定する
  2. Makefile で指定する
  3. シェル変数として定義する
  4. デフォルトで定義されているもの
マクロ文字列の置換

次のようなベタ書きのMakefileだとソースファイルを1つ追加すると結構大変

CC = gcc
CFLAGS = 
SRCS = main.c func1.c func2.c
OBJS = main.o func1.o func2.o

main : ${OBJS}
	${CC} ${CFLAGS} -o $@ ${OBJS}

main.o : main.c
	${CC} -c $?

func1.o : func1.c
	${CC} -c $?

func2.o : func2.c
	${CC} -c $?

OBJSというマクロを文字列の置換を使って書き直して、
サフィックスルール(.c.o:)を使うと、ソースファイルの追加でもSRCSだけいじればよくなる

CC = gcc
CFLAGS = 
#SRCS = main.c func1.c func2.c
SRCS = main.c func1.c func2.c func3.c
OBJS = ${SRCS:.c=.o}

.SUFFIXES : .o .c

main : ${OBJS}
	${CC} ${CFLAGS} -o $@ ${OBJS}

.c.o:
	${CC} -c $<

マクロ文字列の置換を使う方法がこれぐらいしか思いつかない。
いろいろなMakefileを見ていけば、もっと別の使いかたも身につくんだろうなぁ。

ほかにも置換のやり方が書いてあったけど、どう使えばよいのか思いつかないものばっかり。