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

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!

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?

In addition to MadScientist's correct answer, there was another error in my Makefile introduced by renaming variables: mingw32-make couldn't find the -lglfw3 part because I used $(GLFW) in the definition of GLFW_INC and GLFW_LIB, but didn't define it. I wanted to have $(GLFW_DIR) instead.

Related

How can I avoid circular dependency in my Makefile compiling obj file with g++ and gcc?

I tried to create a makefile for a project that use c++ and c.
I need to compile those file in order to make de .o file, but when I compile using make I have circular dependency that is dropped.
I don't know why this error occurs as I tried to separate the building of .o files that comes from .c and .o files that comes froms .cpp files.
Here is my makefile :
SRC = $(wildcard *.c)
SRC++ = $(wildcard *.cpp)
OBJ = $(SRC++:.cpp=.o) $(SRC:.c=.o)
DEP = $(SRC:.c=.d) $(SRC++:.cpp=.d)
CC=gcc
CXX=g++
CFLAGS = -Wall
CXXFLAGS = -Wall
all: $(OBJ)
%.c : %.o
$(CC) -c $(CFLAGS) $< -o $#
%.cpp : %.o
$(CXX) -c $(CXXFLAGS) $< -o $#
# Clean the project
clean:
#rm -f $(OBJ) $(DEP)
-include $(DEP)
Do you have any idea of what I am doing wrong ?
The rules you wrote are %.cpp : %.o and %.c : %.o. You wrote those rules the wrong way around. The target being built must be to the left of the colon, and the things it depends on must be to the right.
The error message tells you about a circular dependency because GNU Make defines an implicit rule where the dependencies are defined in the correct direction.

C/C++ compilation. Having trouble with simple makefile for a project

I been working on this makefile for hours and it seems like no changes are working, but it seems totally fine to me. Maybe I am missing something fundamental?
Here is how the directory looks:
project
makefile
\obj
checkInput.cpp
olend.cpp
\include
checkInput.h
Here is makefile:
I_DIR = include
OBJ_DIR = obj
CXX = g++
CXXFLAGS = -I$(I_DIR)
MAIN = olend
SRCS = checkInput.cpp
OBJ_SRCS = $(subst .cpp, .o, $(SRCS)), $(MAIN).o
OBJS = $(patsubst %, $(OBJ_DIR)/%, $(OBJ_SRCS))
DEP_SRCS = $(subst .cpp,.h,$(SRCS))
DEPS = $(patsubst %,$(I_DIR)/%,$(DEP_SRCS))
all: $(MAIN)
$(MAIN): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(MAIN) $(OBJS)
$(OBJ_DIR)/%.o: %.cpp $(DEPS)
$(CXX) $(CXXFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f $(OBJ_DIR)/*.o $(MAIN)
I'm looking to get an executable "olend", and the error I am currently getting is,
"No rule to make target 'obj/olend.o,', needed by `olend'. Stop."
Which is very straight forward error, but I don't understand how that could be happening,
$(OBJ_DIR)/%.o
should include obj/olend.o as a target. Any help would be greatly appreciated!
If you look closely at the error message, it says that the target it can't find is 'obj/olend.o,' - notice the extra comma at the end. This comes from the way you defined your OBJ_SRCS variable. It should look like this:
OBJ_SRCS = $(subst .cpp,.o, $(SRCS)) $(MAIN).o
Notice there is no space before .o (this caused it to generate filenames like checkInput .o) and there is no comma before the $(MAIN) part (this caused it to generate something like this: checkInput.o, olend.o).

Makefile pattern rule with mixed dependencies

I've coded the following lines in my Makefile:
PROJECTS = ExamsGenerator ExercisesImporter
VERSION = .v0.0
EXTENSION = .Exe
BINDIR = ../bin
CONFDIR = ../config
DATADIR = ../data
DOCDIR = ../doc
INCDIR = ../include
LIBDIR = ../lib
OBJDIR = ../obj
SRCDIR = ../src
INCDIRS = $(INCDIR:%=-I%)
CC = g++
CCVAR = -D__DATADIR__=\"$(DATADIR)\"
CFLAGS = -g -Wall $(shell root-config --cflags) $(INCDIRS)
LDFLAGS = -g -Wall $(shell root-config --ldflags)
LDLIBS = $(shell root-config --glibs)
MEG_DEP = Functions.h Parser.h Test.h
MEG_DEPS = $(patsubst %,$(INCDIR)/%,$(MEG_DEP))
MEI_DEP = Functions.h Parser.h Exercise.h
MEI_DEPS = $(patsubst %,$(INCDIR)/%,$(MEI_DEP))
MEG_OBJ = mainExamsGenerator.o Parser.o Test.o
MEG_OBJS = $(patsubst %,$(OBJDIR)/%,$(MEG_OBJ))
MEI_OBJ = mainExercisesImporter.o Parser.o Exercise.o
MEI_OBJS = $(patsubst %,$(OBJDIR)/%,$(MEI_OBJ))
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(MEG_DEPS) $(MEI_DEPS)
#echo "\nCreating object: $#"
$(CC) $(CCVAR) $(CFLAGS) -c -o $# $<
all: $(PROJECTS)
#echo "\n"
ExamsGenerator: $(MEG_OBJS)
#echo "\nLinking $#"
$(CC) $(CCVAR) $(CFLAGS) $(LDLIBS) -o $(BINDIR)/$(#)$(VERSION)$(EXTENSION) $^
ExercisesImporter: $(MEI_OBJS)
#echo "\nLinking $#"
$(CC) $(CCVAR) $(CFLAGS) $(LDLIBS) -o $(BINDIR)/$(#)$(VERSION)$(EXTENSION) $^
.SILENT:
.PHONY: clean
clean:
\rm -f $(BINDIR)/*$(EXTENSION) $(OBJDIR)/*.o *~ $(INCDIR)/*~ $(SRCDIR)/*~
I'm a Makefile newbie so I've picked up hints from several places and I'm probably not writing it in the most elegant way. I have few questions to improve them:
Do I really need to add $(OBJDIR)/%.o into the dependencies ?
Written in this way Parser.h is listed twice. Is it possible to rewrite this pattern rule to avoid it ? E.g., I don't want to recompile MEG stuff if Exercise.h is modified. New dependencies will be added and I'd like to manage them in a smart way.
Any other suggestion?
Thanks in advance for any help.
Bye...
No, you don't need (and don't want) to list a target as its own prerequisite. That doesn't make sense and cannot work.
$(patsubst %,prefix/%,$(var)) can be written as $(addprefix prefix,$(var)).
You might want to read Auto-Dependency Generation for a method to automatically generate the correct dependencies for .o files. It will help solve some of your problems.
If, however, you don't want to get that fancy then what you need to remember is that you need to list, for each target, all the files that that target depends on and no other files.
So
Parser.o presumably depends on (at least) Parser.h
So add $(OBJDIR)/Parser.o: $(INCDIR)/Parser.h
Exercise.o presumably depends on (at least) Exercise.h (and possibly also Parser.h?)
So add $(OBJDIR)/Exercise.o: $(INCDIR)/Exercise.h (or possibly $(OBJDIR)/Exercise.o: $(INCDIR)/Exercise.h $(INCDIR)/Parser.h)
etc...
Note that prerequisites combine from wherever they are found so the above suggested lines will combine with a $(OBJDIR)/%.o: $(SRCDIR)/%.cpp rule to form a full set of prerequisites for the given .o file.

Makefile: no rule to make target

I was looking for a solution on this site and also tried google for some time now, but somehow I can't get it to work.
My source should be in the src directory and the object files would be in the obj directory. Now I try to create a simple makefie but I either get an error that there is no rule, or I can't make it work to use the directories.
CC = /usr/bin/gcc
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
SRC:= nohupshd.cpp \
task.cpp
OBJ:= nohupshd.o \
task.o
OBJDIR:= obj
SRCDIR:= src
DEP:= src/task.h
LIBS:=
TARGET:= nohupshd
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $(OBJ) $(LIBS)
clean:
rm -f $(OBJ) $(TARGET)
Variant 1:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -S $(SRCDIR)/$< -o $(OBJDIR)/$#
$(CC) -c $(SRCDIR)/$< -o $(OBJDIR)/$#
Variant 1a:
%.o: %.cpp
$(CC) -S $(SRCDIR)/$< -o $(OBJDIR)/$#
$(CC) -c $(SRCDIR)/$< -o $(OBJDIR)/$#
When I use this pattern I always get an error that there is no rule for nohupshd.o to build.
Variant 2:
$(OBJ) : $(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -S $(SRCDIR)/$< -o $(OBJDIR)/$#
$(CC) -c $(SRCDIR)/$< -o $(OBJDIR)/$#
When I use this variant, I can see that it tries to build, but I get errors saying that "file".o doesn't fit the target pattern.
Another issue is that "$<" doesn't give me the source name. According to several sites it should, but I can see in the output that there is nothing, so how can I fix this?
Update:
In the meantime my newest version looks like this:
$(OBJDIR)/$(OBJ) : $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) -S $< -o $(OBJDIR)/`basename $# .o`.asm
$(CC) -c $< -o $#
This now manages to compile the first objectfile (nohupshd.o) but when make tries to do the second file it fails again saying: target 'task.o' doesn't match a pattern.
You actually have a couple if incorrect things above.
First you write My error was, that I was assuming that the pattern %.o matches ANY pattern ending with .o which it doesn't; that's not true. The pattern does match any string ending in .o. However, the pattern character % that is matched on the target side is replaced on the prerequisite side with the identical string. So if you have a target obj/task.o and it matches the pattern %.o then the stem (what the manual calls it) will be obj/task, and when the prerequisite is %.c that means that make will look for a prerequisite obj/task.c. Since there isn't one, and make doesn't know how to build one, that rule is discarded as not applying. When writing pattern rules you must write them so ONLY the identical parts of the names match the pattern character (%). ALL non-identical parts, including directories, must be specified explicitly.
Second, the rule $(OBJ) : $(SRC) is really not right. That line says that each object file depends on all the source files, so whenever any single source file changes all the object files will be recompiled. That's really not what you want (if that IS what you want you don't need make: you can just write a simple shell script). I don't know what you mean by since the rules is empty it invokes the pattern rule; you don't need this to invoke the pattern rule. The target depends on $(OBJ), and each object file depends on its source file (due to the pattern). You don't need this line at all.
Third, I don't know why you are trying to construct .asm files rather than just compiling directly from source to object, but if you really want them it would be cleaner and more "make-like" to create a separate pattern rule to build them: create a pattern rule $(OBJDIR)/%.o : $(OBJDIR)/%.asm and a rule $(OBJDIR)/%.asm : $(SRCDIR)/%.c. If you want the ASM files to be products of the build you should declare them as a prerequisite of all or similar, otherwise they'll be deleted as intermediate files.
Fourth, using things like basename is unnecessary. There are lots of automatic make variables that can be used instead. For example, $* expands to the stem, so you could write $(OBJDIR)/$*.asm. Of course if you make a separate pattern rule for ASM files you can just use $# or $< directly. There are various make functions that can also be used; see the manual.
Fifth, you define a variable containing a header file, DEP, but then never use it. Because it's not used, if you change that file nothing would be rebuilt. If you know that all the source files include every header you can use $(OBJ) : $(DEP) to define that; but it does mean (as in the second point above) that any change to any header causes all objects to recompile. You would be better off auto-generating the prerequisites; since you're using GCC this is quite simple.
Sixth, you're using C++ files (xxx.cpp) but you're using the C compiler. This will not work (the link line will fail: although the compiler can see you're compiling a C++ file and do the right thing, even if you call gcc, when you link a bunch of objects together it has no idea if those were C objects or C++ objects (or FORTRAN or whatever) so you MUST use the C++ front-end to link or it won't pull in the right C++ libraries). You should be using the make variable CXX to build C++ code, not CC, and setting it to g++ not gcc.
Seventh, you don't need .SUFFIXES: .c .o to use pattern rules. They are only needed for suffix rules, which you don't have here. You can keep the plain .SUFFIXES: though to disable built-in pattern matching which is a slight performance improvement.
Finally, you'll note you don't actually need the $(SRC) variable because make can infer it from the pattern rules. However, if you wanted to have your makefile less onerous to change, you could construct the contents of the OBJ variable from the SRC variable, like SRC = nohupshd.cpp task.cpp then OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(SRC)).
So, all-in, this is how I would recommend you write your makefile (I don't include the auto-generated dependencies here though):
.SUFFIXES:
CXX := g++
CXXFLAGS := -O2 -g -Wall -fmessage-length=0
OBJDIR := obj
SRCDIR := src
TARGET := nohupshd
SRC := nohupshd.cpp task.cpp
DEP := src/task.h
LIBS :=
# ----
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SRC))
ASM := $(patsubst %.cpp,$(OBJDIR)/%.asm,$(SRC))
.PHONY: all clean
all: $(TARGET) $(ASM)
$(TARGET): $(OBJ)
$(CXX) -o $# $^ $(LIBS)
clean:
rm -f $(OBJDIR)/* $(TARGET)
$(OBJDIR)/%.o : $(SRCDIR)/%.asm
$(CXX) $(CXXFLAGS) -c -x assembler-with-cpp $< -o $#
$(OBJDIR)/%.asm : $(SRCDIR)/%.cpp
$(CXX) $(CPPFLAGS) -S $< -o $#
Don't repeat the directory names in the compiler line. $< and $# already have the directory names.
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -S $< -o $#
$(CC) -c $< -o $#
So finally I found the answer on how to write this makefile, for an exaplanation of my mistakes look at the posting I marked as correct answer:
The resulting makefile looks like this, and for completeness I post it here including dependencies for header files (remove the ASM parts if you don't need 'em):
.SUFFIXES:
.SUFFIXES: .o .cpp
.SUFFIXES: .o .d
CC := g++
LNK:= ar
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJDIR:= obj
SRCDIR:= src
HDIR:= include
INCLUDE_PATHS:= -Iinclude -Iinclude/interfaces -Iinclude/support
CPP_FILES := propertyfile/propertyfile.cpp \
propertyfile/propertyitem.cpp \
propertyfile/propertyfactory.cpp
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o, $(CPP_FILES))
SRC := $(patsubst %.cpp,$(SRCDIR)/%.o, $(CPP_FILES))
ASM := $(patsubst %.cpp, $(OBJDIR)/$*.asm, $(CPP_FILES))
LIBS:=
TARGET:= libsupport.a
all: $(TARGET)
$(TARGET): $(OBJ)
#echo "Linking..."
#$(LNK) rvs $(TARGET) $(OBJ)
#cp $(TARGET) ../lib
#cp -r include ..
clean:
rm -f $(OBJ) $(ASM) $(TARGET)
-include $(patsubst %.cpp,$(OBJDIR)/%.d, $(CPP_FILES))
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OBJDIR)/%.d
#mkdir -p `dirname $#`
$(CC) $(CXXFLAGS) -S $< -o $(OBJDIR)/$*.asm $(INCLUDE_PATHS)
$(CC) $(CXXFLAGS) -c $< -o $# $(INCLUDE_PATHS)
$(OBJDIR)/%.d: $(SRCDIR)/%.cpp
$(CC) $(CXXFLAGS) -MM -MT $# -MF $(OBJDIR)/$*.d -c $< $(INCLUDE_PATHS)
I hope this helps other user. All examples that I found were either extremly simple and listed multiple files individually and not part of a rule, but didn't really explain how it works, or were so complicated that I couldn't find out how it can help me.

Creating static library from multiple sources

I'm trying to create a Makefile that, among other things, outputs some library1.a, that I will reuse afterwards to create an executable. Now here's my dilemma: I want to make the this process generic, so that I don't have to edit the Makefile each time I add some files. Here's what I have in mind:
#Declare phony targets
.PHONY: all clean build_utils
#Compiler
CXX = g++
#Flags
CXXFLAGS = -Wall -Wextra -Wconversion -Werror -pedantic -std=c++0x -O2
#Directories
OUTPUT_DIR = _output/linux
INTERMEDIATE_DIR = _intermediate/linux
UTILS_DIR = utils
all: $(OUTPUT_DIR)/libUtils.a
$(OUTPUT_DIR)/libUtils.a:
ar rcs $# $(INTERMEDIATE_DIR)/utils/$(patsubst %.cpp, %.o, $(wildcard $(UTILS_DIR)/ *.cpp))
#create .o files in %INTERMEDIATE_DIR/utils
build_utils: $(UTILS_DIR)/ *.cpp $(UTILS_DIR)/ *.h
$(CXX) -c $(CXXFLAGS) $^ -o ## What must be placed here? ##
So, basically, I want all the object files to be created in a temporary directory and then to be archived in libUtils.a, but I can't figure out how to ask the compiler to output multiple object files based on the input files. Basically, my standards impose that for each .cpp file, I should get an object file, but I'm not sure how to do this. I don't want to create a separate target for each .o file, because it's too messy.
You can use a wildcard rule like the following to compile each C++ source file separately:
%.o: %.cpp
$(CXX) $< $(CXXFLAGS) $#
After adding -c -o at the end of your CXXFLAGS. Then capture the result of the patsubst expression somewhere, like:
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard $(UTILS_DIR)/*.cpp))
... and have the $(OUTPUT_DIR)/libUtils.a rule depend upon $(OBJECTS).
So, after many hours of digging, here's what I've managed to come up with:
#Build object files
$(INTERMEDIATE_DIR)/$(UTILS_DIR)/%.o: $(UTILS_DIR)/%.cpp $(UTILS_DIR)/%.h
mkdir -p $(INTERMEDIATE_DIR)/$(UTILS_DIR)
$(CXX) $< $(LIBCXXFLAGS) -o $#
$(INTERMEDIATE_DIR)/$(FUNCTIONS_DIR)/%.o: $(FUNCTIONS_DIR)/%.cpp $(FUNCTIONS_DIR)/%.h
mkdir -p $(INTERMEDIATE_DIR)/$(FUNCTIONS_DIR)
$(CXX) $< $(LIBCXXFLAGS) -o $#
#create the library archives
$(OUTPUT_DIR)/libUtils.a: $(patsubst %.cpp, $(INTERMEDIATE_DIR)/%.o, $(wildcard $(UTILS_DIR)/ *.cpp))
ar rcs $# $^
$(OUTPUT_DIR)/libFunctions.a: $(patsubst %.cpp, $(INTERMEDIATE_DIR)/%.o, $(wildcard $(FUNCTIONS_DIR)/ *.cpp))
ar rcs $# $^
#Builds the libraries
libs: $(OUTPUT_DIR)/libUtils.a $(OUTPUT_DIR)/libFunctions.a
#Main target
all: libs
The nice part about it is that I don't have to edit it each time I add a file. I think it can be made even more abstract than this, by having a single generic target which builds the object files, but that seems a bit too much.
PS: Thanks Martin for giving me a good idea on what to use! :)
LE: It seems that it's very hard to convince SO to not try to do syntax highlighting. Not even the <pre></pre> tag helps when dealing with /*...