I am trying to create Makefile for my C++ project.
My main.cpp contains this custom includes:
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
For compilation I use:
g++ -stdlib=libc++ -o app.cgi -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc -L/usr/local/mysql-connector-c++/lib64 main.cpp -lmysqlcppconn
Now I need to add
#include "tinyxml2/tinyxml2.hpp"
The most simple way is to create Makefile. I wrote:
CC = g++
CFLAGS = -Wall -g -std=c++11
INCLUDES = -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc
LDLIBS = -L/usr/local/mysql-connector-c++/lib64 -lmysqlcppconn
SRCS = main.cpp ./tinyxml2/tinyxml2.cpp
OBJS = $(SRCS:.cpp=.o)
MAIN = main.cgi
#
# The following part of the makefile is generic
#
.PHONY: depend clean
all: $(MAIN)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS)
.PRECIOUS: %.o
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -cpp $< -o $#
clean:
$(RM) *.o *~ $(MAIN)
depend: $(SRCS)
makedepend $(INCLUDES) $^
I got error:
main.cpp:21:10: fatal error: 'mysql_connection.h' file not found
#include <mysql_connection.h>
How to add includes to every .o? tinyxml2 doesn't use MySQL connector so I shouldn't add -lmysqlcppconn. How to do it?
You could build the makefile step by step. Start with the build command and make it a makefile target (I removed -stdlib=libc++):
app.cgi: main.cpp
g++ -o app.cgi -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc -L/usr/local/mysql-connector-c++/lib64 main.cpp -lmysqlcppconn
Next you can extract most elements into variables and add compiler flags:
CXX = g++
CXXFLAGS = -Wall -g -std=c++11
MAIN = app.cgi
CPPFLAGS = -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc
SRCS = main.cpp
LDFLAGS = -L/usr/local/mysql-connector-c++/lib64
LDLIBS = -lmysqlcppconn
$(MAIN): $(SRCS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(MAIN) $(SRCS) $(LDFLAGS) $(LDLIBS)
Add a clean and an all target:
CXX = g++
CXXFLAGS = -Wall -g -std=c++11
MAIN = app.cgi
CPPFLAGS = -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc
SRCS = main.cpp
LDFLAGS = -L/usr/local/mysql-connector-c++/lib64
LDLIBS = -lmysqlcppconn
.PHONY: all clean
all: $(MAIN)
$(MAIN): $(SRCS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(MAIN) $(SRCS) $(LDFLAGS) $(LDLIBS)
clean:
$(RM) *.o *~ $(MAIN)
Split into compiler step (implicit makefile rule) and linker step:
CXX = g++
CXXFLAGS = -Wall -g -std=c++11
MAIN = app.cgi
CPPFLAGS = -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc
SRCS = main.cpp
OBJS = $(SRCS:.cpp=.o)
LDFLAGS = -L/usr/local/mysql-connector-c++/lib64
LDLIBS = -lmysqlcppconn
.PHONY: all clean
all: $(MAIN)
$(MAIN): $(OBJS)
$(CXX) -o $(MAIN) $(OBJS) $(LDFLAGS) $(LDLIBS)
clean:
$(RM) *.o *~ $(MAIN)
Finally add ./tinyxml2/tinyxml2.cpp:
CXX = g++
CXXFLAGS = -Wall -g -std=c++11
MAIN = app.cgi
CPPFLAGS = -I/usr/local/include -I/usr/local/mysql-connector-c++-8.0.21/include/jdbc
SRCS = main.cpp ./tinyxml2/tinyxml2.cpp
OBJS = $(SRCS:.cpp=.o)
LDFLAGS = -L/usr/local/mysql-connector-c++/lib64
LDLIBS = -lmysqlcppconn
.PHONY: all clean
all: $(MAIN)
$(MAIN): $(OBJS)
$(CXX) -o $(MAIN) $(OBJS) $(LDFLAGS) $(LDLIBS)
clean:
$(RM) *.o *~ $(MAIN)
When I run make, I get the following error:
make: *** No rule to make target Menu.h', needed by Menu.o'. Stop.
Here is my Makefile:
PROG = sim
CURR_PATH = ~/Projects/restaurant/cpp/
CC = g++
CPPFLAGS = -g -v -Wall $(LOCAL_INCLUDES) -I$(BOOST_ROOT)
ODIR = ./bin
SDIR = ./src
LOCAL_INCLUDES = $(patsubst %,-I$(CURR_PATH)src/%,$(PKG_DIRS))
PKG_DIRS = $(shell ls $(SDIR))
FIND_SRC_FILES = $(notdir $(wildcard $(SDIR)/$(pkg)/*.cpp))
SRC_FILES = $(foreach pkg,$(PKG_DIRS),$(FIND_SRC_FILES))
OBJ_FILES = $(patsubst %.cpp,%.o,$(SRC_FILES))
MAIN_OBJ = main.o
.PHONY : prog
prog : $(PROG)
all : ; $(info $$CPPFLAGS is [${CPPFLAGS}])#echo Hello world
$(PROG) : $(OBJ_FILES)
$(CC) $(CPPFLAGS) -o $(PROG) $(MAIN_OBJ)
%.o : %.cpp
$(CC) $(CPPFLAGS) -c $< -o $#
$(OBJ_FILES) : %.o : %.h
$(CC) $(CPPFLAGS) -c $(patsubst %.h,%.cpp,$<) -o $#
BTW, in case you're wondering what LOCAL_INCLUDES looks like, the output for the 'all' recipe is the following:
$CPPFLAGS is [-g -v -Wall -I~/Projects/restaurant/cpp/src/concurrent -I~/Projects/restaurant/cpp/src/containers -I~/Projects/restaurant/cpp/src/data -I~/Projects/restaurant/cpp/src/loader -I~/Projects/restaurant/cpp/src/main -I~/Projects/restaurant/cpp/src/people -I~/Projects/restaurant/cpp/src/sim -I/usr/local/boost_1_72_0]
Hello world
Sorry for the single line output, I am unaware of how to format in a more readable fashion. But as you can see, the directory data, which contains Menu.h, is being properly included. But for some reason, make is unable to find it. What could possibly be going wrong here?
Let me know if you need more information.
Cheers
The compiler knows how to find that header file. Make does not know how to find it, and Make is the one producing that error message.
I suggest you make this modification:
INCLUDE_DIRS = $(addprefix $(CURR_PATH)src/,$(PKG_DIRS))
LOCAL_INCLUDES = $(addprefix -I,$(INCLUDE_DIRS))
vpath %.h $(INCLUDE_DIRS)
(P.S. Your use of CURR_PATH and . is confusing, and data/ is a terrible place to put header files.)
EDIT:
All right, let's take this in stages. Step 1, try this makefile:
OBJ_FILES = Menu.o
INCLUDE_DIRS = ~/Projects/restaurant/cpp/src/data
vpath %.h $(INCLUDE_DIRS)
Menu.o:
$(OBJ_FILES) : %.o : %.cpp %.h
#echo building $# from $^
and tell us what happens. (If it doesn't work, tell us what happens.)
As aforementioned, make's vpath did not like the absolute path that it was being given. See below for my modified Makefile:
PROG = sim
CURR_PATH = ~/Projects/restaurant/cpp/
CC = g++
CPPFLAGS = -g -v -Wall $(LOCAL_INCLUDES) -I$(BOOST_ROOT)
ODIR = bin
# vpath only needs SDIR and PKG_DIRS!
SDIR = src
PKG_DIRS = $(shell ls $(SDIR))
INCLUDE_DIRS = $(addprefix $(CURR_PATH)src/,$(PKG_DIRS))
LOCAL_INCLUDES = $(addprefix -I,$(INCLUDE_DIRS))
FIND_SRC_FILES = $(notdir $(wildcard $(SDIR)/$(pkg)/*.cpp))
SRC_FILES = $(foreach pkg,$(PKG_DIRS),$(FIND_SRC_FILES))
OBJ_FILES = $(patsubst %.cpp,%.o,$(SRC_FILES))
MAIN_OBJ = main.o
vpath %.h $(addprefix $(SDIR)/,$(PKG_DIRS))
.PHONY : all
prog : $(PROG)
all : ; $(info $$CPPFLAGS is [${CPPFLAGS}])#echo Hello world
$(PROG) : $(OBJ_FILES)
$(CC) $(CPPFLAGS) -o $(PROG) $(MAIN_OBJ)
%.o : %.cpp
$(CC) $(CPPFLAGS) -c $< -o $#
$(OBJ_FILES) : %.o : %.h
$(CC) $(CPPFLAGS) -c $(patsubst %.h,%.cpp,$<) -o $#
I hope this helps other people that come across similar issues.
1. My file structure is:
build/
include/
-Sort.h
src/
-Sort.cpp
-main.cpp
2. My Makefile:
C++ = g++
SRCPATH := ./src
BUILDPATH := ./build
SORTINCPATH := ./include
TARGET := $(BUILDPATH)/sort
CPPFLAGS := -c -g -Wall -O0
INCPATH := -I./ -I$(SORTINCPATH)
CPPFILES += $(wildcard $(SRCPATH)/*.cpp)
CFILES += $(wildcard $(SRCPATH)/*.c)
HEADFILES += $(wildcard $(SORTINCPATH)/*.h)
CPPOBJS += $(CPPFILES:.cpp=.o)
COBJS += $(CFILES:.c=.o)
.PHONY : all
all: $(TARGET)
$(TARGET): $(CPPOBJS) $(COBJS)
$(C++) $(CPPFLAGS) -o $# $(CPPOBJS) $(COBJS)
%.o : %.c $(HEADFILES)
$(C++) $(CPPFLAGS) $(INCPATH) $< -o $#
%.O : %.cpp $(HEADFILES)
$(C++) $(CPPFLAGS) $(INCPATH) $< -o $#
.PHONY : clean
clean:
-rm $(TARGET) $(COBJS) $(CPPOBJS)
3. Sort.h
sort.h
4. Sort.cpp
sort-1.cpp
sort-2.cpp
5. When I run make, it shows the following:
g++ -c -g -Wall -O0 -c -o src/Sort.o src/Sort.cpp
and says "src/Sort.cpp:3:18: fatal error: Sort.h: no such file or directory".
I hope you can help me find out where the problem is.
Thank you so much!
I'm trying to move the *.o-files into a separate folder (/objs). But I'm getting the following error:
"No rule to make target '../objs/main.o', needed by 'all'. Stop."
How do I have to define these rules?
My folder structure looks as follows:
model_1/
main.cpp
Model1.cpp
Model1.h
model_1.mk # Makefile
pub_sub/
...
objs/
My Makefile:
CC=gcc
CXX=g++
RM=rm -f
PROG = myProgram
INCLUDES = -I../pub_sub
CXXFLAGS := -std=c++1y -g -Wall ${INCLUDES}
LDFLAGS = -L/usr/local/lib
SRCS= main.cpp Model1.cpp ../pub_sub/Subscriber.cpp ../pub_sub/Publisher.cpp
OBJS= $(addprefix ../objs/, $(notdir $(subst .cpp,.o,$(SRCS))))
all: $(OBJS)
$(CXX) $(CXXFLAGS) -o $(PROG) $(OBJS) $(LDFLAGS)
.PHONY:
clean:
$(RM) $(OBJS)
distclean: clean
$(RM) $(PROG)
Simply put: It's not finding the include paths:
CC = g++
OBJS = *.o #*/*.o
DEBUG = -g
PNAME = game
INCLUDES = -Iheaders
CFLAGS = -Wall $(DEBUG)
LFLAGS = -Wall -lsfml-graphics -lsfml-window -lsfml-system $(DEBUG)
all: build
build: $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o $(PNAME)
clean:
\rm *.o *~ $(PNAME)
.cpp:
$(CC) $(CFLAGS) $(INCLUDES) -c $(.SOURCE)
Your makefile looks pretty broken to me. Firstly, you probably want:
OBJS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
Secondly, your final rule needs to be something more like:
%.o: %.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c $^ -o $#