2013年9月9日月曜日

Makefile の作成

こんにちは。
 今日は、ロボットのプログラムのコンパイル用の Makefile を作成したので、投稿します。
まず、ファイル構造を示します。
Makefile main.c main.h /SUB_A /SUB_B
             |    |
             |      | --sub_b.c sub_b.h _sub_.h
             |
             | --sub_a.c sub_a.h _sub_a.h


次に、依存関係を示します。

main.c
---------------------------------------------------------------------
 #include "./main.h"
#include "./SUB_A/sub_a.h"
#include "./SUB_B/sub_b.h"
.
.
.
.
---------------------------------------------------------------------

./SUB_A/sub_a.c
---------------------------------------------------------------------
#include "./sub_a.h"
#include "./_sub_a.h"
.
.
.
.
----------------------------------------------------------------------

./SUB_B/sub_b.c
----------------------------------------------------------------------
#include "./sub_b.h"
#include "./_sub_b.h"
.
.
.
.
-----------------------------------------------------------------------

main.out は main.o sub_a.o sub_b.o に依存
main.o は main.c main.h に依存
sub_a.o は sub_a.c sub_a.h _sub_a.h に依存
sub_b.o は sub_b.c sub_b.h _sub_b.h に依存 しているとします。

こんな感じだったとき、main.c のあるディレクトリと同じ所にMakefileを作成します。

Makefile
-----------------------------------------------------------------------------------------------------------------
#マクロ定義
 CC = gcc #コンパイラはgccを使用

.PHONY : clean #本当のファイル名ではないターゲットをフォニーターゲット
                                (Phony target=偽のターゲット)といい、
                                明示的にコマンドを実行させたい時にこの名前を利用します #===============================================================
# 何かソースを更新したら...
#
#  1. VPATH にそのソースの置いてあるディレクトリの相対パスを追加する。
#      追加するときは : をつけて追加すること。
#
#  2. SUB_SRC に追加したソースの.cファイルを追加する。
#      追加するときはスペースを開けて追加すること。
#
# 以上が、ソースを追加した時の使い方である。
# デバッグをしたい時は DEBUG のコメントアウトをとる。
# オプションを付けたい時は OPTION のコメントアウトをとる。
# どちらも何か追加したければ、スペースを開けて追加すること。 #===============================================================
PROG        = main

#OPTION  = -Wall
#DEBUG   = -g -O0

VPATH = ./SUB_A:./SUB_B #makeの変数、VPATHの値にはmakeがサーチするディレクトリの
                                                      リストを指定します。ほとんどの場合、
                                                      指定するディレクトリは依存関係にあるが、
                                                      カレントディレクトリにはないファイルを含むディレクトリになります

MAIN_SRC = main.c
SUB_SRC   = sub_a.c sub_b.c
SRCS           = $(MAIN_SRC) $(SUB_SRC)
OBJS           = $(SRCS:%.c=%.o)
HEADS        = $(SRCS:%.c=%.h) $(SUB_SRC:%.c=_%.h)

all: $(PROG)

$(PROG) : $(OBJS) $(HEADS)
              $(CC) -o $@ $(OPTION) $(DEBUG) $(OBJS)

$(PROG).o : $(PROG).c $(PROG).h
              $(CC) -c $(OPTION) $(DEBUG) $<

%.o : %.c %.h _%.h
              $(CC) -c $(OPTION) $(DEBUG) $<

clean : rm $(OBJS) -----------------------------------------------------------------------------------------------------------------------

こんな感じです。詳細を説明するのは骨が折れるので勘弁してください。
もしわからないことがあったら、コードをググったら大概の物は出てきます。
Makefile には色んなオプションや、マクロ定義があるので、調べてみてください。

 Makefileについて参考にさせていただいたサイト↓
GNUMake3.77/make_4.jp

 今載せているコードで何か質問がある場合は、投稿で聞いてください。
できる限り答えます!

 次回は、TCP/IPの通信プログラムを投稿しようと思っているので、宜しくおねがいします。