tags:

views:

890

answers:

5

Hi have three files. program.c, program.h, and headers.h

program.c #includes program.h and headers.h

I need to compile this on Linux using gcc compiler. I'm not sure how to do this. Netbeans created one for me, but it's empty.

+5  A: 

For example this simple Makefile should be sufficient:

CC=gcc 
CFLAGS=-Wall

all: program
program: program.o
program.o: program.c program.h headers.h

clean:
    rm -f program program.o
run: program
    ./program

Note there must be <tab> on the next line after clean and run, not spaces.

UPDATE Comments below applied

Viliam
That's missing the command to make the target.
Joey Adams
actually this is just fine
Amro
That looks good, but I get this error:Makefile:8: *** missing separator. Stop.
Note that the line below *clean* must start with a tab (not spaces)
Amro
great, I get the following when I type make:make: `program' is up to date.Is there a way so that the program starts running when I type make? Or how should I run it?
I can give you the answer but I suggest you read some tutorial on makefiles, plenty on the web..
Amro
change the first rule to read:program: program.o<enter><tab>./program
Alex Brown
A: 
gcc program.c -o program

no makefile necessary.

Alex Brown
Rather unmaintainable if your program gets any bigger, don't you think?
Chris Lutz
I know I can compile like that, but I must have a makefile.
Programs often don't get bigger than that. No sense building infrastructure when you don't need it.
Alex Brown
A: 
program: program.h headers.h

is enough. the rest is implicit

Elias Pipping
+5  A: 

Interesting, I didn't know make would default to using the C compiler given rules regarding source files.

Anyway, a simple solution that demonstrates simple Makefile concepts would be:

HEADERS = program.h headers.h

default: program

program.o: program.c $(HEADERS)
    gcc -c program.c -o program.o

program: program.o
    gcc program.o -o program

clean:
    -rm -f program.o
    -rm -f program

(bear in mind that make requires tab instead of space indentation, so be sure to fix that when copying)

However, to support more C files, you'd have to make new rules for each of them. Thus, to improve:

HEADERS = program.h headers.h
OBJECTS = program.o

default: program

%.o: %.c $(HEADERS)
    gcc -c $< -o $@

program: $(OBJECTS)
    gcc $(OBJECTS) -o $@

clean:
    -rm -f $(OBJECTS)
    -rm -f program

I tried to make this as simple as possible by omitting variables like $(CC) and $(CFLAGS) that are usually seen in makefiles. If you're interested in figuring that out, I hope I've given you a good start on that.

Here's the Makefile I like to use for C source. Feel free to use it:

TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)

%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) -c $< -o $@

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    -rm -f *.o
    -rm -f $(TARGET)

It uses the wildcard and patsubst features of the make utility to automatically include .c and .h files in the current directory, meaning when you add new code files to your directory, you won't have to update the Makefile. However, if you want to change the name of the generated executable, libraries, or compiler flags, you can just modify the variables.

In either case, don't use autoconf, please. I'm begging you! :)

Joey Adams
To be technically correct, I believe you should use `.PHONY: clean all default` for those targets that are meant to be used from the command line. Also, Autoconf/Automake aren't that bad. Sure, they feel awful, and getting used to them is about as fun as forcing your head through a brick wall, but they do work, and they're well developed, and they'll cover most of your bases as far as portability, and will make your life a lot easier in the end once you get used to their awful design.
Chris Lutz
I guess this works, but I thought if I typed "make" on the terminal the program should run. This is what I get:gcc statsh.o -Wall -lm -o progIs it possible to just type make and execute the program?
Thank you. This worked so great.
A: 

Depending on the number of headers and your development habits, you may want to investigate gccmakedep. This program examines your current directory and adds to the end of the makefile the header dependencies for each .c/cpp file. This is overkill when you have 2 headers and one program file. However, if you have 5+ little test programs and you are editing one of 10 headers, you can then trust make to rebuild exactly those programs which were changed by your modifications.