In an effort to try to learn makefiles I wrote this
C = $(CXX)
CFLAGS = -g -Wall -Wextra -I$(SRC_DIR) -std=c++0x
SRC_DIR = src
BIN_DIR = bin
OBJ_DIR = obj
vpath %.cpp $(SRC_DIR)
vpath %.h $(SRC_DIR)
vpath %.o $(OBJ_DIR)
GPATH = src obj
SRC = main.cpp resources.cpp ui.cpp
OBJ = $(SRC:.cpp=.o)
.PHONY: clean all
all: $(OBJ)
$C -o $(BIN_DIR)/exe $^
main.o: main.cpp defaults.h
$C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)
resources.o: resources.cpp resources.h
$C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)
ui.o: ui.cpp ui.h defaults.h
$C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)
clean:
rm -f $(OBJ_DIR)/*.o
When I run make and the obj directory is empty it compiles all the .cpp files and places them in $(OBJ_DIR)/$@ -> obj/file.o
However when it is time to execute the all target, g++ doesn't find .o files, because $^ contains only the files without the directory prepended
According to http://www.gnu.org/software/make/manual/make.html#Search-Algorithm this is the intended behavior (though not what I want at all) and it says I can modify it using the GPATH variable, which I set but seems to be ignored by make
Notes: if I run make again it finds the files in the obj directory, and since they don't need to be recompiled the path is preserved, so I can't even modify all to be
$C -o $(BIN_DIR)/exe $(addprefix $(OBJ_DIR)/$^)
A first invocation of make would build and link the files correctly, but the second time it would try to link obj/obj/file.o and fail
What am I doing wrong?