I have a set of makefiles I use to build a 'big' C project. I am now trying to reuse some in my C++ project and have run into this headache that I just cannot figure out.
The makefile looks like this
SOURCES = \
elements/blue.cpp
# Dont edit anything below here
VPATH = $(addprefix $(SOURCE_DIR)/, $(dir $(SOURCES)))
CXXFLAGS = $(OPT_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -D_LINUX -DNDEBUG -pipe
DCXXFLAGS = $(DEBUG_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -v -D_LINUX -D_DEBUG -pipe
OBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Release/%.o, $(notdir $(SOURCES)))
DOBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Debug/%.o, $(notdir $(SOURCES)))
$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp
+@[ -d $(dir $@) ] || mkdir -p $(dir $@)
$(CPP) $(INCLUDE) $(CXXFLAGS) $(DEFINES) -o $@ -c $<
Its a little complicated but what it does in C is build all the %.c files defined in SOURCES and put the object files in BUILD_DIR. It works great in c, but this does not work with cpp files. I get
make: *** No rule to make target `blue.cpp', needed by `build/Release/blue.o'. Stop.
Its like VPATH is not working at all. I tried
vpath %.cpp src/elements
but that does not work either.
Amazingly enough, renaming blue.cpp to blue.c and editing the makefile back to the %.c usage does work, it compiles just fine.
Am I going crazy here?
Do you really need VPATH - I've had nothing but trouble with it in the past. And in fact, I seem to remember that VPATH is dependent on extensions, so that would fit Aiden's theory. In my makefiles, I give the source directory SDIR explicitly:
.
Edit: If you are wedded to the use of VPATH, then you need to investigate the use of the vpath directive (note case difference). For example:
looks for .cpp fies in foo and bar directories. But as I said, I've had nothing but trouble using this.
Ok guys I figured it out here and its a big mess of a bug.
After some more experimentation I went to post a bug on the make-bugs list and turned on debug output to tell them exactly what was going on. Turns out I should have done this before because it led me right to the solution.
I use an automatic dependency generation scheme developed from http://mad-scientist.net/make/autodep.html and amazingly enough that was breaking make. Trouble occurred in with this line
I did not change that to %.cpp and for some reason trying to include blue.cpp caused make to not search for it using vpath when it tried to resolve
So the solution was just to port the makefile correctly, doh!
From your example, it looks like you don't have a Makefile rule being activated for compiling the C++ files. Maybe your
%
are expanding incorrectly?Try
And specify the destination in the rule part, using
$(basename ..)
where appropriate.It works for C for
blue.c
because Make has a built-in default rule for compiling C files. I suspect running Make with the--no-builtin-rules
option would cause theblue.c
file to stop working too.From the docs,
There is a default C++ rule, but it might not be kicking in for you because of another rule or bad variables. It is better to write the rule explicitly to be sure.
You need a rule such as:
For compiling your object files from source, then you have:
Where the objects of some format
%.o
trigger the dependency. Or use Autotools/Autoconf to build your Makefile for you. Here is an example I wrote that just builds C++ files into a directory of objects:Not a complete example by any means, but you get the idea. In the
final
rule, you copy the object files, but you can do whatever here or change the-o
option to plonk build files in a specific location.