I have several files to include from a subfolder and I just can't get this to work. I'm propably missing something here...

The Makefile and .cpp with main function are located at /path/to/ and files to be included are at /path/to/src/buffer and /path/to/src/hash. Both of these folders have .cpp and .h for respective class. I've had no problems compiling until I put this whole project together and made a single Makefile for them.

Here's my try on the Makefile:

objects = delta.o hash.o buffer.o
buffer_dir = path/to/src/buffer
hash_dir = path/to/src/hash

delta:  $(objects)
    g++ -g -o $(objects)

delta.o: delta.cpp buffer.o hash.o
    g++ -g -c delta.cpp buffer.o hash.o

buffer.o: buffer.cpp buffer.h
    g++ -g -c -I$(buffer_dir) buffer.cpp

hash.o: hash.cpp hash.h sha2.o sha4.o buffer.o
    g++ -g -c -I$(hash_dir) -I$(buffer_dir) hash.cpp

sha2.o: sha2.c  sha2.h config.h
    g++ -g -c -I$(hash_dir) sha2.c

sha4.o: sha4.c sha4.h config.h
    g++ -g -c -I$(hash_dir) sha4.c

I have obviously missunderstood how to use the -I(capital i) flag. The compiler (g++) gives me this short answer:

make: *** No rule to make target `buffer.cpp', needed by `buffer.o'.  Stop.

I would appreciate a little help with this. I've gone through a bunch of googles for "Makefile examples", but still can't figure out what's the problem.
I'm on Linux by the way...

This is a dependency error from make. buffer.o needs buffer.cpp but make cannot find buffer.cpp and therefor looks for a rule that can generate buffer.cpp (which fails). The dependencies must point to the actual files.

buffer.o: /path/to/buffer.cpp /path/to/buffer.h
    g++ -c $< -o $@

You can also make a more generic target for all .o files like this:

%.o: %.cpp
    g++ -c $< -o $@

The < variable equals the first dependency and the @ variable equals the target. $^ would equal all dependencies.

Since the -c flag skips the link step I assume you can also skip the .o dependencies for hash.o and delta.o.

Another tip is to use gcc -MM <file> to generate the .h dependencies for each .cpp file. Here is a short example:

target = program
src = main.cpp

all: program
objs = $(src:.cpp=.o)
deps = $(objs:.o=.d)

-include $(deps)

%.d: %.cpp
    g++ -MM $< > $*.d

%.o: %.cpp
    g++ -c $< -o $@

$(target): $(objs)
    g++ $^ -o $@

    rm -f $(objs) $(target) $(deps)
This article has been dead for over six months. Start a new discussion instead.