Simple Makefile Problem (with a dependency)

Hi all,

I have 4 '.cpp' files and 1 header files:

Tools.cpp
Code1.cpp
Code2.cpp
Code3.cpp

and Tools.hh

Now all

Code1.cpp, Code2.cpp, Code3.cpp

use functions stored in

Tools.cpp

.

Currently, what I do to compile all of them is using
this simple shell script:

#!/bin/bash
echo "compiling Code1.cpp";
g++ Code1.cpp Tools.cpp -o Code1

echo "compiling Code2.cpp";
g++ Code2.cpp Tools.cpp -o Code2 

echo "compiling Code3.cpp";
g++ Code3.cpp Tools.cpp -o Code3

It all works fine.

Now I want to do that using a standard makefile.
But why this doesnt' work:

XX = g++

TOOLSRC = Tools.cpp Code1.cpp Code2.cpp \
Code3.cpp    

TOOLSINC = Tools.hh      

all: Code1 Code2 Code3

Code1: $(TOOLSRC) $(TOOLSINC) makefile
                $(CXX)   

Code2: $(TOOLSRC) $(TOOLSINC) makefile
                $(CXX)   

Code3: $(TOOLSRC) $(TOOLSINC) makefile
                $(CXX)   

The error I got is this:

g++
i686-apple-darwin9-g++-4.0.1: no input files
make: *** [Code1] Error 1

You need to think about what the chain of dependencies really are:

The executable Code1 depends on the object files Code1.o and Tools.o
The object file Code1.o depends on the source files Code1.cpp and Tools.hh and the makefile
The object file Tools.o depends on the source files Tools.cpp and Tools.hh and the makefile.

So a simple makefile could be something like

%.o: %.c Tools.hh makefile

Code1: Code1.o Tools.o
Code2: Code2.o Tools.o
Code3: Code3.o Tools.o

This uses

  • a pattern rule to say that any .o depends on the corresponding .cpp and the header and the makefile
  • rules to say that Code1 depends on Code1.o and Tools.o
  • implicit rules to do the compilation and linking (make knows it needs to use g++ to compile, and so on)

If you want to specify the compilation or linking rules yourself, then you have to specify the complete command. You had

Code3: $(TOOLSRC) $(TOOLSINC) makefile
                $(CXX)

where your rule is just "g++" with no arguments. That's like typing just g++ on the command line, hence the error message, You need to have the same thing as you would type on the command line, e.g.

        $(CXX) Code3.o Tools.o -o Code3

or if you want to be fancy and more general with automatic variables

        $(CXX) $^ -o $@