1
votes

I'm making a program in C and I want to know how to structure and run my program using a Makefile.

I have three files:

main.c
count.c
bin2csv.c

I also have these headers:

bin2csv.h
count.h
struct.h

This is my makefile:

CC = gcc
OBJS = main.o count.o bin2csv.o
HEADERS = struct.h count.h bin2csv.h
APP_NAME = project2

all:    $(APP_NAME)
$(APP_NAME):     $(OBJS) $(HEADERS)
       $(CC)  $(OBJS) -o $(APP_NAME)

main.o:
       $(CC) -c main.c
count.o:
       $(CC) -c count.c
bin2csv.o:
       $(CC) -c bin2csv.c
clean:
       rm -f *.o $(APP_NAME)

My questions are as follows: What is happening in this make file? It goes through the hierarchy and compiles these .c files into object files, including the headers?

How would I run and compile my program? I attempted to make a change in main.c, by adding a print statement, but I figure compiling using gcc would throw off the makefile. I know I can use the command make I don't believe anything changed.

2
Your .o targets aren't telling make what the prerequisites of those targets are so make doesn't know when to rebuild them (so it doesn't rebuild them). You need to tell it that the .o files depend on the matching .c files. (Actually make already knows that by default so you don't need those rules at all and can get rid of them entirely.)Etan Reisner

2 Answers

3
votes

You need to say that the .o files depend on the .c files:

main.o: main.c <---- HERE
       $(CC) -c main.c
count.o: count.c <---- HERE
       $(CC) -c count.c
bin2csv.o: bin2csv.c <---- HERE

Otherwise, make has no reason to think it needs to re-make the .o files.

1
votes

To prevent re-make (so add dependecies), I recomand you to use a variable to list your .c files instead of .o ones and deduce objects name:

 SRC=       main.c \
            count.c \
            bin2csv.c

 OBJS=      $(SRC:.c=.o)

OBJS will contain your .o filenames, and you can use it in same way that you're doing:

$(APP_NAME):        $(OBJS) $(HEADERS)
    $(CC) -o $(APP_NAME) $(OBJS)

And clean rule

clean:
    rm -f $(OBJS) $(APP_NAME)

If you want change headers files you can add -I to gcc to add specific headers directory:

HEADERS_DIR= $(PROJECT_ROOT)/include
$(CC) -I $(HEADERS_DIR) -o $(APP_NAME) $(OBJS)