人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Makefileについて教えてください

以下のMakefileでmakeすると

------- ここから -----------

CC = gcc
INCLUDE = -I/opt/fm/include
CFLAGS = -O4 -Wall $(INCLUDE)
LDFLAGS = -L/opt/fm/lib
LIBS = -lfmlog
OBJS = test.o
PROGRAM = test

all: $(PROGRAM)

$(PROGRAM): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM)

clean:; rm -f *.o *~ $(PROGRAM)


------------ ここまで -------------------

以下のように2回 gccが実行されるのですが
なぜでしょうか

gcc -O4 -Wall -I/opt/fm/include -c -o test.o test.c
gcc test.o -L/opt/fm/lib -lfmlog -o test

もしありましたら
参考サイトについても
紹介いただけると助かります

●質問者: QUWE
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● うぃんど
●15ポイント

gccは、オブジェクトファイル生成と、
オブジェクトファイルを結合しての実行ファイル生成の2ステップで使われるため、
gccの実行回数は生成するオブジェクトの数+1。

ステップ1:オブジェクトファイル生成
gcc -O4 -Wall -I/opt/fm/include -c -o test.o test.c

ステップ2:実行ファイル生成
gcc test.o -L/opt/fm/lib -lfmlog -o test


より深い知識を得たいならば、
Makefileについて調べるよりもgccの処理の流れとコマンドオプションについて学んだほうが良いでしょう。


a-kuma3さんのコメント
gcc でリンクまでするときには 2ステップで実行されるのは、その通りですが、質問にあるケースは make コマンドの挙動です。 Makefile に、以下のような行を足して、暗黙のルールを書き換えてみると、何が起きているのか分かります。 >|| %.o: %.c echo "Oops" ||<

QUWEさんのコメント
回答いただきありがとうございます

2 ● a-kuma3
●85ポイント ベストアンサー
gcc test.o -L/opt/fm/lib -lfmlog -o test

↑のコマンドは、↓のルールで実行されている、ということは分かりますか?

$(PROGRAM): $(OBJS)
 $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM)

不思議に思っているのは、↓のコマンドがどんな仕組みによって起動されているか、ということだと思います。

gcc -O4 -Wall -I/opt/fm/include -c -o test.o test.c

make には「暗黙のルール」というのがあります。
質問にある Makefile だと、test と test.o を比較して、必要があれば gcc ($(CC)) を実行する、というルールが書いてあります。
では、test.o というのは、どうやって作るの、というのがあらかじめ決められたルールがあります。
使われている暗黙のルールは、↓のような感じです。

%.o: %.c
 $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

これに、.SUFFIXES の指定が関係してきます(これも、デフォルトがあります)。
test.o は、test.c から作る可能性があって、そのソースがあるなら、このコマンドを使う、というのを、あらかじめ make が持っていて、そのルールに従って実行されます。

質問のケースだと、*.o がひとつだけなので、自分でルールを書いてもたいしたことはありませんが、ソースが増えてきたり、c言語だけじゃなくて、他の言語も混ぜて作ったり、ということがあると単純な内容でも自分で書いていくのは大変です。
暗黙のルールは、そういったありがちなルールを書かなくて済むようにしてくれます。


因みに、*.c から *.o を経由しない暗黙のルールもありますので、以下のような Makefile だけで test.c から test を生成することができます。

CC = gcc
INCLUDE = -I/opt/fm/include
CFLAGS = -O4 -Wall $(INCLUDE)
LIBS = -lfmlog
LDFLAGS = -L/opt/fm/lib $(LIBS)

PROGRAM = test

all: $(PROGRAM)


clean:; rm -f *.o *~ $(PROGRAM)

GNU の環境であれば、CC = gcc も要らない。
暗黙のルールは GNU make であれば -p オプションを指定すると、全ての暗黙のルールが出力されます。


ちょっと内容が難しいですが、make コマンドのマニュアルに詳細が書いてあります。
http://quruli.ivory.ne.jp/document/make_3.79.1/make-jp_9.html


QUWEさんのコメント
詳しく回答いただきありがとうございます 大変参考になりました
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ