GNU Make pattern to build output in different dire

2019-01-17 11:04发布

问题:

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 $@

回答1:

After re-reading the documentation on static pattern rules, I derived the following pattern rule which seems to work.

$(OBJ_DEBUG): $(OBJDIR_DEBUG)/%.o: %.cpp
    $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@

I'm not sure this is the best approach, and I'm open to suggestions.



回答2:

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.



回答3:

Makefile that "duplicates" source tree in separate build directory by running GCC on each source - https://stackoverflow.com/a/41924169/4224163