tags:

views:

300

answers:

3

I'm really confused at the moment.

So I have 5 files: main.c, flight.c, flight.h, passenger.c, and passenger.h

flight.h has function prototypes for flight.c, and passenger.h has function prototypes for passenger.c

flight.c and passenger.c have definitions for these functions.

main.c is the program I'll interact with, calling functions from both .c files

I'm not really sure what .o files are for, somebody please care to explain? Here is my Makefile:

flight.o: flight.c flight.h
    gcc -Wall -g -c flight.c    
passenger.o: passenger.c passenger.o
    gcc -Wall -g -c passenger.c    
main.o: main.c
    gcc -Wall -g -c main.c     
reservations.out: main.o flight.o passenger.o
    gcc -Wall -g flight.o passenger.o main.o -o reservations.out

EDIT: I then use the command "make Makefile", and get an error: make: Nothing to be done for `Makefile'.

In my file there is a tab before gcc. I'd appreciate any help, I'm sure there are lots of things I'm doing wrong. Thanks.

+2  A: 

I'm not really sure what .o files are for, somebody please care to explain?

.o are object files, the temporary files which are created by the compiler, which contains the object code for the class. The object codes will be linked by the linker to create an executable binary file.

Priyank Bolia
So how do I know how many .o files I need?
kevin
I guess there is one for every .cpp file
Priyank Bolia
anybody please correct me, If I am wrong, I am Windows guy and don't write makefiles.
Priyank Bolia
Windows has them also, but uses the .obj extension. If you're writing a library, you can distribute the .o and .h file to give people code they can use without giving away your source code. Dynamic libraries (.dll on Windows, .so on Unix) are usually distributed now instead - both ways work, and a comparison is too long for this (already long) comment.
Harold L
.o is a pretty standard extension for files that contain compiled but not linked code. You would then pass these .o files to the linker to end up with an executable file. In the OP's post, he appears to be calling the linker through the gcc interface, rather than calling it directly; that's fine for such a simple example. @Priyank has the fundamentals about right (though I think C programmers might take an issue with the use of the word 'class' in his answer).
Carl Norum
+9  A: 

Your problem is that you're using the wrong command. I would add the following line to the top of your makefile:

all: reservations.out

Then just type make at the command line. If you don't want to edit the file, just use make reservations.out and you should get the right behaviour.

As to what a .o file is: it's an 'object' file, meaning it contains compiled (but in this case not linked) code. Your final makefile rule takes the object files and links them together into a final executable called reservations.out.

Now that I look at it some more, it looks like you have some weird behaviour on your final rule. I think it should look more like:

reservations.out: main.o flight.o passenger.o
    gcc -Wall -g main.o flight.o passenger.o -o reservations.out

In addition, you have passenger.o as a prerequisite of passenger.o, which is for sure going to cause you problems. What I would do is something like this (it could be even tighter, but I'm trying to make this straightforward):

.PHONY: all clean

all: reservations.out

flight.o: flight.c flight.h
    gcc -Wall -g -c flight.c    

passenger.o: passenger.c passenger.h
    gcc -Wall -g -c passenger.c    

main.o: main.c
    gcc -Wall -g -c main.c     

reservations.out: main.o flight.o passenger.o
    gcc -Wall -g main.o flight.o passenger.o -o reservations.out

clean:
    rm -f *.o reservations.out

But what I would really do, if you want to get a bit more into the details, is below. It might be a bit overkill for such a small project, but it's also easier to tweak and fiddle with as necessary.

.PHONY: all clean

BIN = reservations
OBJ = flight.o passenger.o main.o

all: $(BIN)

%.o: %.c %.h
    gcc -Wall -g -c $<

main.o: main.c
    gcc -Wall -g -c $<

$(BIN): $(OBJ)
    gcc -Wall -g -o $@ $^

clean:
    rm -f $(OBJ) $(BIN)

I recommend checking out the GNU make manual to learn more about all of the fancy stuff you can do.

Carl Norum
Also, I get this message: "make: Circular passenger.o <- passenger.o dependency dropped."Is that significant? It is just a rule that I'm not supposed to have any warnings so I'm wondering what that message is about.
kevin
That message is because you have passenger.o as a prerequisite (right hand side of a rule) for itself.
Carl Norum
thank you, my mistake.
kevin
+1  A: 

make has implicit rules for making binaries out of C source, you don't need to specify explicit rules for this.

So your minimalistic Makefile would look like

CFLAGS = -Wall -g
.PHONY all clean

all: myprogram

myprogram: source1.c source2.c

clean:
    rm -f myprogram

It has one useful side effect - all intermediary files (*.o files in your case) will be deleted automatically after the compilation.

Options from CFLAGS will be added to gcc command line - make implicit rule does it.

qrdl