2012-12-01 18 views
8

Makefile'de (ve belki de genel olarak) derleme ve bağlama ile ilgili bir sorum var.Makefile, Derleme ve Bağlama

main() işlevine sahip ana programdan oluşan bir server.c dosyası var. server.c, rio.c dosyasını içerir. rio.c ve rio.h'dan oluşan rio adlı bir modülüm var. main() işlevine sahip değil.

Makefile yazmayı ve böyle bir şey yapmak için en iyi uygulamayı nasıl yazacağım konusunda iki sorum var.

S1:

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 

Bununla bağlama sorunlarına yaşıyorum: Makefile'a

Aşağıdaki Makefile var yazma. Bu, C.'de kullanılan tüm işlevlerin birden çok tanımlamasının olduğunu söylüyor. Bunun nasıl mümkün olabileceğinden emin değilim, çünkü server.c, -c bayrağı ile derlendiğinden, aslında hiçbir şey gerçekten bağlantılı değil. Bazı işlevlerin var olduğunu bilmeli, ancak aslında her ikisi de nesne dosyalarını bir araya toplayıp all kuralı birbirine bağlayana kadar her şeyi birbirine bağlamaz.

Buradaki sorun nedir?

S2: En iyi uygulama Ben ana programı içeren bir modül ve ardından başka bir dosya olduğundan, ben ayrı bir modül olarak, ana program server.c derlemek gerekir, ardından all birlikte hem derleme veya sunucuyu derlemek .c tümünde ve rio.o modülünü oraya ekleyin? Bunun hala yukarıda gördüğüm aynı bağlantı sorununu oluşturduğuna dikkat edin, bu yüzden sorunumun başka bir yerde olduğunu biliyorum.

+0

Eğer herhangi bir harici kütüphaneleri kullanıyor musunuz Ayrıca programın adının tekrarını önlemek için bir makro kullanabilir? – zeboidlund

+0

Evet. Ama kendi işlevlerimde hataları çağırıyor, ilk önce server.c onları tanımladı. server.c ve rio.h her ikisi de içe aktarılır: stdio.h, stdlib.h, unistd.h ve errno.h – darksky

+3

"server.c rio.c içerir" derken, bunu "server" dosyasında kastediyorsunuz.c', #include "rio.c" 'gibi bir satır var? Eğer öyleyse, bu yanlış bir yaklaşımdır ve hatanın muhtemel kaynağıdır; bunun yerine rio.h' içermelisiniz. –

cevap

13

Biraz yapısını revize edilmelidir:

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 

fark sahte kural allsysstatd güncel olmasına bağlıdır ve bu tarih wrt nesne kadar olduğunda sysstatd güncel olmasıdır Dosyalar.

Şimdi, derleme eylemlerini açıkça yazarak, yalnızca oldukça ayrıntılı bir işlemdir. Bu yeterli kullanmak olacaktır:

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 

Ayrıca tartışabildiler: server.crio.h kullanmıyor? Eğer varsa, bağımlılık listelenmelidir. Değilse, neden rio.h var? make, server.o öğesinin server.c numaralı telefona bağımlı olduğunu varsayar, dolayısıyla bunu belirtmeniz gerekmez (ancak üstbilgiler hakkında varsayımlarda bulunmaz).

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 

diğer kütüphaneleri Gerekirse, ardından kullanmak olabilir:

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

Bunu görerek adım adım ilerlediğini görmek oldukça faydalıdır. Teşekkür ederim. –