Error: "Mixed implicit and static pattern rules" in my Makefile
c++, c++11, makefile, windows
Solution
In a static pattern rule, the words in the first section (the targets) have to be real files. None of them can contain patterns (`%`). You have:
CXX_SOURCES = $(SRC_DIR)/%.cpp
CXX_OBJS = $(addprefix $(BUILD_DIR)/, $(CXX_SOURCES:.cpp=.o))
$(CXX_OBJS): %.o: $(SRC_DIR)%.cpp
So `CXX_OBJS` is `$(BUILD_DIR)/$(SRC_DIR)/%.o`, which contains a pattern, so this is illegal.
I don't really know what you're trying to do with `CXX_SOURCES`. Maybe you wanted:
CXX_SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
instead?
Problem
I had a working `Makefile` for small C++ applications that just had a couple of source code files inside a single folder that was also the output folder. Now I am trying to separate source and object files and ran into a problem. This is how my makefile looks right now, I'll go into detail where the problem occurs below. ``` CC = gcc CXX = g++ RM = del TARGET = plox.exe CFLAGS = -Wall -ggdb -O3 $(INCLUDE) CXXFLAGS = -std=c++11 -Wall -ggdb -O3 $(INCLUDE) LDFLAGS = $(LIB) -lglfw3 -lopengl32 -lglu32 -lgdi32 INCLUDE = -I$(GLFW_INC) -I$(GLAD_INC) LIB = -L$(GLFW_LIB) SRC_DIR = src BUILD_DIR = build GLFW_DIR = d:/external/glfw-3.1 GLFW_INC = $(GLFW)/include GLFW_LIB = $(GLFW)/lib64 GLAD = d:/external/glad-c GLAD_INC = $(GLAD)/include CXX_SOURCES = $(SRC_DIR)/%.cpp CXX_OBJS = $(addprefix $(BUILD_DIR)/, $(CXX_SOURCES:.cpp=.o)) OBJS = $(CXX_OBJS) $(BUILD_DIR)/glad.o all: $(TARGET) $(TARGET): $(OBJS) $(CXX) -o $@ $^ $(LDFLAGS) $(CXX_OBJS): %.o: $(SRC_DIR)%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< $(BUILD_DIR)/glad.o: src/glad.c $(CC) -c $(CFLAGS) -c -o $(BUILD_DIR)/glad.o $(SRC_DIR)/glad.c .PHONY: clean clean: $(RM) $(TARGET) $(OBJS) ``` The problem is in the line: ``` $(CXX_OBJS): %.o: $(SRC_DIR)/%.cpp ``` Before my changes, it looked like this: ``` $(CXX_OBJS): %.o: %.cpp ``` A friend helped gave me a template and I never really knew what that line really does. In another thread I learned that this is a static pattern rule so I guess this is where I made the mistake. But writing it down just now, I think the error could be earlier already. I might have made a mistake when defining `$(CXX_OBJS)`. Could it be that the objects in that list are of the form `build/src/test.o` instead of `build/test.o`? But how can I fix the `addprefix` line to produce the correct output? And where does the error in the title come from; where am I mixing those? I thought it could be about the `$(SRC_DIR)` in the static pattern rule because I probably misunderstood how it worked, but omitting it doesn't make the error go away. Moreover (assuming `CXX_OBJS` is working correctly later), if the static pattern rule checks every file in the list `$(CXX_OBJS)` for a match with `%.o`, and then has a dependency on the same file with ending `.cpp`, then that is also not correct because of the `build` folder prefix. All in all, I'm very confused about how to handle the folder prefixes correctly and any advice is greatly appreciated!