Makefile, compilation and linking

I have a question regarding compilation and reference in a Makefile (and possibly in general).

I have a server.c file that consists of a main program that has a main() function. server.c includes rio.c. I have a module called rio , which consists of rio.c and rio.h It does not have a main() function.

I have two questions: how to write a Makefile and the best way to do such things.

Q1: How to write a Makefile

I have the following 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 

I am having problems with this. It says that I have several definitions of all the functions used in C. I'm not sure how this is possible, since server.c is compiled with the -c flag, so nothing is connected. He should know that some functions exist, but do not actually link them until the all rule compiles both object files and creates a single object file that has all the associated ones.

What is the problem?

Q2: Best practice Since I have a module, and then another file that contains the main program, you should compile the main server.c program as a separate module and then compile it together in all or compile server.c in all and add the rio module .o have? Please note that this still causes the same binding problem as mine, so I'm sure my problem lies somewhere else.

+8
c compilation linker makefile
source share
1 answer

You should review the structure a bit:

 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 

The difference is that the background rule all depends on sysstatd on relevance, and sysstatd updated when wrt updates it in object files.

Now it's just pretty verbose, writing compilation actions explicitly. It is enough to use:

 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 

You can also discuss: server.c not use rio.h ? If so, add dependency. If not, why does rio.h exist? make will assume that server.o dependent on server.c , so you don't need to specify this (but it will not make assumptions about headers). You can also use a macro to prevent the program name from repeating:

 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 

If you need other libraries, you can use:

 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 
+13
source share

All Articles