10

Makefile(そしておそらく一般的に)でのコンパイルとリンクに関して質問があります。

関数を持つメインプログラムで構成されるserver.cファイルがありmain()ます。server.crio.cを含みます。rioとで構成されるモジュールがrio.cありrio.hます。機能はありませんmain()

Makefileを実際に作成する方法と、そのようなことを行うためのベストプラクティスの2つの質問があります。

Q1:Makefileの書き方

私は次のMakefileを持っています:

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

私はこれとリンクの問題を抱えています。Cで使用されるすべての関数の定義が複数あると書かれています。server.cは-cフラグを使用してコンパイルされているため、実際には何もリンクされていないため、これがどのように可能かわかりません。all一部の関数は存在しますが、ルールが両方のオブジェクトファイルを一緒にコンパイルし、すべてがリンクされた単一のオブジェクトファイルを生成するまで、実際にはそれらをリンクしないことを知っておく必要があります。

ここでの問題は何ですか?

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

4

1 に答える 1

17

構造を少し修正する必要があります。

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

違いは、電話のルールは最新であることにall依存し、オブジェクトファイルが最新の場合は最新であるということです。sysstatdsysstatd

今ではかなり冗長で、コンパイルアクションを明示的に記述しています。以下を使用するだけで十分です。

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.c使用しませんrio.hか?含まれている場合は、依存関係をリストする必要があります。そうでない場合、なぜrio.h存在するのですか? はに依存makeすると想定するため、指定する必要はありません(ただし、ヘッダーについては想定しません)。マクロを使用して、プログラム名の繰り返しを防ぐこともできます。server.oserver.c

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

all: $(PROG)

$(PROG): $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o $@

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 $@ $(LDFLAGS) $(LDLIBS)

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

clean:
    rm -f *~ *.o $(PROG) core a.out
于 2012-12-02T21:14:08.543 に答える