I'm trying to create a Makefile which places my .o
files in a different directory than my source files. I'm trying to use a pattern rule so I don't have to create identical rules for each source & object file.
My project structure looks something like:
project/
+ Makefile
+ src/
+ main.cpp
+ video.cpp
+ Debug/
+ src/ [contents built via Makefile:]
+ main.o
+ video.o
My Makefile looks something like:
OBJDIR_DEBUG = Debug
OBJ_DEBUG = $(OBJDIR_DEBUG)/src/main.o $(OBJDIR_DEBUG)/src/video.o
all: $(OBJ_DEBUG)
$(OBJ_DEBUG): %.o: %.cpp
$(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@
This doesn't work, because it looks for my source files at Debug/src/*.cpp
.
I've tried the following:
# Broken: make: *** No rule to make target `Debug/src/main.cpp', needed by `Debug/src/main.o'. Stop.
# As a test, works if I change "%.cpp" to "Debug/src/main.cpp", though it obv. builds the wrong thing
# Strip OBJDIR_DEBUG from the start of source files
$(OBJ_DEBUG): %.o: $(patsubst $(OBJDIR_DEBUG)/%,%,%.cpp)
$(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@
# Broken:
# Makefile:70: target `src/main.o' doesn't match the target pattern
# Makefile:70: target `src/video.o' doesn't match the target pattern
# Add OBJDIR_DEBUG in target rule
OBJ = src/main.o src/video.o
$(OBJ): $(OBJDIR_DEBUG)/%.o: %.cpp
$(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@
After re-reading the documentation on static pattern rules, I derived the following pattern rule which seems to work.
I'm not sure this is the best approach, and I'm open to suggestions.
Instead of building objects in another directory, you could try building objects from sources in another directory: put your makefile in the directory where the objects are going to be and tell make to look for sources elsewhere using VPATH. This works best if all object files are supposed to end up in the same directory.
Makefile that "duplicates" source tree in separate build directory by running GCC on each source - https://stackoverflow.com/a/41924169/4224163