* Makefile [#yaf1853d]
実際に目にする機会の多い Makefile は、GNU Make という拡張 Makefile 仕様のものだと思います。そこで、本文では GNU Make に絞ります。とりあえず使えそうな雛型をお探しの場合は、ページ最下部にあるソースをご覧ください。

** 基本 [#fb8e4a4d]
Makefile の基本的な記述方法は、以下の通りです。

 [作りたいファイル(ターゲット)]:[左のファイルを作るのに必要なファイル(依存ファイル)]
     実行する命令

具体的に書いてみます。同じ階層に main.c sub.c があり、そこに sample.exe を作る Makefile です。
 sample.exe:main.o sub.o
     gcc -o sample.exe main.o sub.o
 
 main.o:main.c
     gcc -o main.o -c main.c
 sub.o:sub.c
     gcc -o sub.o -c sub.c

少し楽してみます。
 sample.exe:main.o sub.o
     gcc -o $@ $<
 
 %.o:%.c
     gcc -o $@ -c $<

もっと楽をします。
 SRCS=main.c sub.c
 OBJS=$(SRCS:.c=.o)
 sample.exe:$(OBJS)
     gcc -o $@ $<
 
 %.o:%.c
     gcc -o $@ -c $<

gcc とかもマクロにします。
 CC=gcc
 SRCS=main.c sub.c
 OBJS=$(SRCS:.c=.o)
 sample.exe:$(OBJS)
     $(CC) -o $@ $<
 
 %.o:%.c
     $(CC) -o $@ -c $<

** 階層化したディレクトリ構成で使う [#f4ec3fa9]
平たいディレクトリではなく、階層化した構造でも使えるようにします。例として、以下のようなディレクトリ構造を考えます。
 project/
 project/Makefile
 project/src
 project/objs

以下のようになります。ちょっと複雑になってきました。
 CC=gcc
 OBJS_DIR=objs
 SRCS_DIR=src
 SRCS=main.c sub.c
 # *.cを*.oに変換して、先頭にobjs/を付けます
 # つまりOBJS=objs/main.o objs/sub.o になります
 OBJS=$(addprefix $(OBJS_DIR)/, $(SRCS:.c=.o))
 # サーチパスを指定します
 # .cを持つファイルをSRCS_DIR内で検索します
 vpath %.c $(SRCS_DIR)
 
 # 依存関係1
 sample.exe:$(OBJS)
     $(CC) -o $@ $<
 
 # 依存関係2
 $(OBJS_DIR)/%.o:%.c
     $(CC) -o $@ -c $<

sample.exe を作ろうとすると、OBJS=objs/main.o objs/sub.o が必要です(依存関係1)。objs/main.o には main.c が必要です(依存関係2)。vpath により、.c ファイルの検索場所として SRCS_DIR を指定しているので、そこを検索して、src/main.c を見つけます。以上で、main.* について、依存関係を解決できました。sub.* についても、同様に依存関係を解決できます。

※vpath は指定されたディレクトリを検索して、最初に一致したファイルを依存対象として認識します。つまり異なるディレクトリに同じファイル名があると、ややこしいことになりますので、注意が必要です。

後始末用の clean ターゲットも用意しましょう。*.o や *.exe を消すだけです。
 clean:
     # 余談ですが、*.o を一箇所にまとめておくと、こういうとき楽です
     rm $(OBJS_DIR)/*.o
     rm sample.exe

** ヘッダファイルディレクトリやライブラリがある場合 [#f92f2b3f]
以下のように、ヘッダファイルが別ディレクトリにあった場合は、-I で指定する必要があります。同様にライブラリをリンクしたい場合も、-L -l で指定する必要があります。そこで、コンパイラへのオプションもマクロにしておきましょう。後でいじるときに楽です。

 project/
 project/Makefile
 project/src
 project/src/include
 project/lib
 project/objs

 INCLUDE_DIRS=-I./include
 LIB_DIRS=-L./lib
 CFLAGS=$(INCLUDE_DIRS)
 LDFLAGS=$(LIB_DIRS) -lutil

** まとめ [#q8b3ef35]
以上を全部まとめてみます。ついでに sample.exe もターゲット名としてマクロにしておきます。

 TARGET=sample.exe 
 
 # コンパイラ関連
 CC=gcc
 INCLUDE_DIRS=-I./include
 LIB_DIRS=-L./lib
 CFLAGS=$(INCLUDE_DIRS)
 LDFLAGS=$(LIB_DIRS) -lutil
 
 # 配置関連
 OBJS_DIR=objs
 SRCS_DIR=src
 SRCS=main.c sub.c
 OBJS=$(addprefix $(OBJS_DIR)/, $(SRCS:.c=.o))
 vpath %.c $(SRCS_DIR)
 
 # 依存関係
 $(TARGET):$(OBJS)
     $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
 $(OBJS_DIR)/%.o:%.c
     $(CC) $(CFLAGS) -o $@ -c $<
 clean:
     rm $(OBJS_DIR)/*.o
     rm sample.exe

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS