2012-12-01 24 views
8

Ho una domanda riguardante la compilazione e il collegamento in Makefile (e forse in generale).Makefile, Compiling e Linking

Ho un file server.c che consiste nel programma principale che ha una funzione main(). server.c include rio.c. Ho un modulo chiamato rio che consiste di rio.c e rio.h. Non ha la funzione main().

Ho due domande, come scrivere effettivamente il Makefile e le migliori pratiche per fare una cosa del genere.

Q1: Come scrivere il Makefile

Ho il seguente 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 

Sto avendo problemi con questo collegamento. Dice che ho più definizioni di tutte le funzioni utilizzate in C. Non sono sicuro di come sia possibile poiché server.c è compilato con il flag -c quindi niente è effettivamente collegato. Dovrebbe sapere che alcune funzioni esistono ma in realtà non le collegano fino a quando la regola all compila entrambi i file oggetto insieme e produce un singolo file oggetto che ha tutto collegato.

Qual è il problema qui?

Q2: Le migliori pratiche Dato che ho un modulo e poi un altro file che contiene il programma principale, dovrei compilare il programma principale, server.c, come un modulo separato e quindi compilare entrambi insieme in all, o compilare Server .c in tutto e aggiungi il modulo rio.o lì? Nota che questo produce ancora lo stesso problema di collegamento che ho sopra quindi sono abbastanza sicuro di avere il mio problema da qualche altra parte.

+0

Stai usando librerie esterne? – zeboidlund

+0

Sì. Ma chiama gli errori sulle mie funzioni dicendo che server.c li ha definiti per primi. server.c e rio.h entrambi importano: stdio.h, stdlib.h, unistd.h e errno.h – darksky

+3

Quando dici "server.c include rio.c", intendi quello nel file 'server.c', hai una riga come '#include" rio.c "'? Se è così, questo è l'approccio sbagliato da prendere e la probabile fonte di errore; dovresti includere 'rio.h'. –

risposta

13

Si dovrebbe rivedere la struttura un po ':

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 

La differenza è che la regola falsa all dipende sysstatd essere aggiornati, e sysstatd è aggiornata quando si è aggiornata WRT l'oggetto File.

Ora è solo piuttosto prolisso, scrivendo le azioni di compilazione in modo esplicito. Sarebbe sufficiente utilizzare:

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 

si potrebbe anche discutere: fa server.c Non usare rio.h? Se lo fa, la dipendenza dovrebbe essere elencata. In caso contrario, perché esiste rio.h? make assumerà che server.o dipende da server.c, quindi non è necessario specificarlo (ma non farà ipotesi sulle intestazioni). Si potrebbe anche usare una macro per impedire la ripetizione del nome del programma:

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 

Se avete bisogno di altre librerie, allora si potrebbe utilizzare:

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

Estremamente utile vederlo migliorare passo dopo passo in questo modo. Grazie. –