以下の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
もしありましたら
参考サイトについても
紹介いただけると助かります
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
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の処理の流れとコマンドオプションについて学んだほうが良いでしょう。
gcc でリンクまでするときには 2ステップで実行されるのは、その通りですが、質問にあるケースは make コマンドの挙動です。
Makefile に、以下のような行を足して、暗黙のルールを書き換えてみると、何が起きているのか分かります。
%.o: %.c echo "Oops"
回答いただきありがとうございます
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
詳しく回答いただきありがとうございます
大変参考になりました
詳しく回答いただきありがとうございます
2014/02/10 12:33:29大変参考になりました