Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: "Mixed implicit and static pattern rules" in my Makefile

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!

like image 396
InvisiblePanda Avatar asked Oct 20 '22 16:10

InvisiblePanda


1 Answers

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?

like image 151
MadScientist Avatar answered Oct 31 '22 00:10

MadScientist