C++のための即席Makefile

最低限だけ書くと次のようになる。

CXXFLAGS = -O2 -Wall
LDFLAGS = -lm
all: hello # In Windows, it may be "hello.exe"

clean:
    $(RM) hello
  • CXXFLAGSは、C++コンパイラに対する引数。Cコンパイラに対する引数はCFLAGS。最適化や警告、インクルードディレクトリや準拠する標準仕様の設定などを書く。
    • ここでは最適化オプション-O2と警告オプション-Wallをつけている。
  • LDFLAGSは、リンカに対する引数。ライブラリディレクトリやリンクしたいライブラリを書く。
    • ここではmath.hを使うため、-lmをつけてlibm.aをリンクしている。
  • allは、デフォルトで実行されるターゲット(といってもallという名前だからではなく、先頭にあるからだが)。ここでは実行ファイルhelloをビルドしている。Windowsだったらhello.exeにするといいかもしれない。
  • cleanは、ビルドしたファイルを消して元の状態に戻すためのターゲット。$(RM)はrmとかdelとか、消去用のコマンドになる。ここもWindowsだったらhello.exeを消すといいと思う。
  • cleanは改行しているが、allは改行していない。これは意味が違う。
    • allが言っているのは、「allはhelloに依存する。helloをビルドした後に実行するべきコマンドは特にない。」ということなので、その行に書く。
    • cleanが言っているのは、「cleanは特に何かに依存しない。とにかく以下のコマンドを実行する。」ということなので、下の行に書く。

さらに

さらに僕の場合、以下のようにして書いている。

#!/bin/make
CXX = g++
CXXFLAGS = -O2 -Wall
LDFLAGS = -lm
OBJS = hello
all: $(OBJS)

clean:
    $(RM) $(OBJS)
  • 最初の#!/bin/makeは、shebang。特に目的はないが何となく書いてる。
  • CXXは、C++コンパイラの指定。デフォルトでg++なので特に意味はない。
  • OBJSは、さっき直に書いていたhelloの指定をまとめたもの。

さらにさらに

依存関係もちゃんと自分で書いてしっかりさせると下みたいなかんじになる。

#!/bin/make
CC = gcc
CFLAGS = -O2 -Wall
CXX = g++
CXXFLAGS = -O2 -Wall
LDFLAGS = -lm
OBJS = hello

.PHONY: all clean
.SUFFIXES: .c .cpp .o

all: $(OBJS)

clean:
    $(RM) $(OBJS)

.c.o:
    $(CC) $(CFLAGS) -o $@ -c $^
.cpp.o:
    $(CXX) $(CXXFLAGS) -o $@ -c $^
.c:
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
.cpp:
    $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
  • 説明は面倒くさくなったのでやめた。