2012-12-01 202 views
8

我有一個關於編譯和鏈接Makefile(也許一般)的問題。Makefile,編譯和鏈接

我有一個server.c文件,它由具有main()函數的主程序組成。 server.c包括rio.c.我有一個叫做rio的模塊,它由rio.crio.h組成。它沒有main()的功能。

我有兩個問題,如何實際編寫Makefile以及做這種事情的最佳實踐。

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編譯兩者一起,或編譯服務器.c在所有和添加rio.o模塊?請注意,這仍然會產生與上面相同的鏈接問題,所以我非常確定我的問題存在於其他地方。

+0

您是否使用任何外部庫? – zeboidlund

+0

是的。但它是在我自己的函數上調用錯誤,稱server.c首先定義它們。 server.c和rio.h都導入:stdio.h,stdlib.h,unistd.h和errno.h – darksky

+3

當你說「server.c包含rio.c」時,你的意思是在文件'server中。c',你有一行像'#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 

的區別是,騙子規則all取決於sysstatd是最新的,並且sysstatd是最新的,當它是最新的WRT對象文件。

現在,它只是非常冗長,明確地編寫了編譯操作。這將是足夠使用:

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.o取決於server.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

非常有益,看到它像這樣一步步改進。謝謝。 –