2012-12-01 18 views
8

メイクファイル(とおそらく一般的に)でコンパイルとリンクに関する質問があります。メイクファイル、コンパイルとリンク

私はmain()機能を持つメインプログラムからなるserver.cファイルを持っています。 server.cは、rio.cを含む。私はrio.crio.hからなるrioというモジュールを持っています。それにはmain()機能はありません。

私は実際にMakefileを書く方法とそのようなことをするためのベストプラクティスを持っています。

Q1:

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 

all: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o sysstatd 

server.o: server.c 
    $(CC) $(CFLAGS) -c server.c 

rio.o: rio.c rio.h 
    $(CC) $(CFLAGS) -c rio.c 

clean: 
    rm -f *~ *.o sysstatd 

私はこれで問題を結ぶ持っています:Makefileの

私は、次のMakefileを持っているの書き方を。私はC言語で使われているすべての関数の定義を複数持っていると言います。server.cが-cというフラグでコンパイルされているので、実際には何もリンクされていないので、 allルールが両方のオブジェクトファイルを一緒にコンパイルし、すべてがリンクされた1つのオブジェクトファイルを生成するまでは、いくつかの関数が存在するが実際にそれらをリンクしていないことを知っておく必要があります。

ここで問題は何ですか?

Q2:ベストプラクティス 私は、メインプログラムを含むモジュール、その後、別のファイルを持っているので、私は別のモジュールとして、メインプログラム、server.cをコンパイルする必要があり、その後allで一緒に両方をコンパイルする、またはサーバーをコンパイル.cをすべて追加し、そこにrio.oモジュールを追加しますか?これは私が上に持っているのと同じリンク問題を生成するので、私は私の問題が別の場所にあると確信していることに注意してください。

+0

あなたは、任意の外部ライブラリを使用していますか? – zeboidlund

+0

はい。しかし、それは、server.cが最初に定義した関数というエラーを呼び出しています。 server.cとrio.hはどちらもインポートします:stdio.h、stdlib.h、unistd.h、errno.h – darksky

+3

"server.c include rio.c"と言うとき、それはファイル 'server。あなたは '#include" rio.c "'のような行を持っていますか?もしそうなら、これは間違ったアプローチとエラーの原因である可能性があります。代わりに 'rio.h'をインクルードする必要があります。 –

答えて

13

あなたは少し構造を修正する必要があります

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 

all: sysstatd 

sysstatd: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o sysstatd 

server.o: server.c 
    $(CC) $(CFLAGS) -c server.c 

rio.o: rio.c rio.h 
    $(CC) $(CFLAGS) -c rio.c 

clean: 
    rm -f *~ *.o sysstatd 

違いは偽物ルールallsysstatdが最新のものに依存しており、それが日付WRTオブジェクトに任されたときにsysstatdが最新であることですファイル。

コンパイルアクションを明示的に記述するだけで、かなり冗長です。使用するのに十分である:

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 

all: sysstatd 

sysstatd: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o sysstatd 

server.o: server.c 
rio.o: rio.c rio.h 

clean: 
    rm -f *~ *.o sysstatd 

あなたはまた、議論ができます:server.crio.hを使用していませんか?存在する場合は、依存関係をリストアップする必要があります。そうでない場合、rio.hはなぜ存在するのですか? makeserver.oserver.cに依存していると仮定しますので、それを指定する必要はありません(ヘッダーについては仮定しません)。また、プログラム名の重複を防ぐために、マクロを使用することができます。

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 
PROG = sysstatd 

all: $(PROG) 

$(PROG): $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o [email protected] 

server.o: rio.h 
rio.o: rio.h 

clean: 
    rm -f *~ *.o $(PROG) core a.out 

あなたが他のライブラリを必要とした場合、その後、あなたが使用する可能性があります:

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 
PROG = sysstatd 
LOCALLIBDIR = /usr/local/lib 
LDFLAGS = -L$(LOCALLIBDIR) 
LDLIBS = -lone -ltwo 

all: $(PROG) 

$(PROG): $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o [email protected] $(LDFLAGS) $(LDLIBS) 

server.o: rio.h 
rio.o: rio.h 

clean: 
    rm -f *~ *.o $(PROG) core a.out 
+1

このようなステップで段階的に改善されていることが非常に有益です。ありがとうございました。 –

関連する問題