views:

64

answers:

3

Hi everyone!

I'm having some trouble making a Makefile. Write now I just compile everything every time. Although, the professor is ok with that, I do want to get it working faster and to avoid unnecessary compiling.

Here's what I have.

FILES= p6.cpp SetIter.cpp Node.cpp Set.cpp
CFLAGS= -ansi -pendantic -Wall -Wextra
CC= g++

MakePg6: p6.cpp SetIter.cpp Node.cpp Set.cpp
   $(CC) $(CFLAGS) $(FILES) -o pg6

Node.cpp - node class

Set.cpp - uses nodes. Friend of Node.

SetIter.cpp - gets a set and uses a pointer to iterator through

I'm confused with some of the depencies arising from the friends thing and the point of lib.o being included in the Makefile as some sites have.

Any help is greatly appreciated. Thanks in advance.

+1  A: 

You can simplify you make file, but using the $(FILES) in the dependency of MakePg6 thus:

MakePg6: $(FILES)
   $(CC) $(CFLAGS) $(FILES) -o pg6

The friend part is resolved by each c++ is compiled independently, and the header files define all the information need to compile that one file. The compiler enforces the friend rules. The linker weaves the resulting object together to make the resulting executable.

The lib.o is include because people are making use of standard code provided by the base library. You get linking error's if you missing stuff.

Simeon Pilgrim
+1  A: 

What about trying to separate the making of files, so as to rebuild each one only if needed.

OBJECTS= p6.o SetIter.o Set.o Node.o

.cpp.o: $*.cpp
     $(CC) $(CFLAGS) -cpp $*.cpp
p6.o: p6.cpp SetIter.cpp // any file that it depends on
SetIter.o: SetIter.cpp Set.cpp //etc
Set.o: Set.cpp Node.cpp
Node.o: Node.cpp
p6: $(OBJECTS)
    $(CC) $(CFLAGS) $(OBJECTS) -o
MakePg6: p6

In doing that, it will build each object file only if the .o file is older than the .cpp file, and I think that's what you are trying to accomplish.

aharazin
A: 

If your Makefile works as written, then you must have the header files (e.g. Node.h) set up correctly. So the different files can be compiled separately and linked, but whether you do that or not you must account for dependencies on the header files.

OBJECTS= p6.o SetIter.o Node.o Set.o
CFLAGS= -ansi -pendantic -Wall -Wextra
CC= g++

# This will compile any object file (something.o) that is called for
# Note that I am using automatic variables-- "$<" means the first prerequisite
# (the .cpp file), "$^" means all the prerequisites, and "$@" means the target.
%.o: %.cpp
    $(CC) $(CFLAGS) -c $< -o $@

# If A.cpp (or A.h) includes B.h, then if you change B.h you must recompile A.o,
# So A.o depends on B.h.
# I will make some educated guesses about how you include header files:

SetIter.o Node.o Set.o: Node.h
Set.o: Set.h
SetIter.o p6.o: Set.h SetIter.h

# This will link the object files together to make pg6.
# Notice that the target is the name of thing actually made, a good practice.
pg6: $(OBJECTS)
    $(CC) $(CFLAGS) $^ -o $@

You have to work out those .h dependencies by looking at the code. There are ways to have g++ and Make do it automatically, but that's an advanced technique.

Beta