How to create Makefile with includes and libraries? - c++

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)

Related

include DLIB and other header files in C++ project

I'm trying to get dlib library working in my C++ project from last 2 weeks and found some solution but still i'm facing errors which i can not understand. As i am newbie to the makefile and dlib guide me what to do with makefile.
The folder structure is like this:
projectDir
|-makefile
|-src
|-CDetector.cpp
|-CDetectot.h
|-CStreamReader.cpp
|-CStreamReader.h
|-include
|-darknet
|-(files).h (other .h files needed by src files)
|-dlib-19.6
|-all
|-source.cpp
|-lots of header files
|-...
|-external_libs
|-libdarknet.a
|-libdarknet.so
The makefile looks like this:
EXE = darknet
OBJ_DIR = obj
CXXFILES = $(shell find src -type f -name '*.cpp')
CXXOBJ = $(patsubst src/%.cpp,obj/%.o,$(CXXFILES))
INCLUDE = -I/include -I/include/darknet
LIBS = external_libs/libdarknet.a
CXXFLAGS = `pkg-config --cflags-only-I opencv` -Wall -Wno-unknown-pragmas -Wfatal-errors -Wwrite-strings -fPIC
LDFLAGS = -lm -pthread -lX11 -DDLIB_JPEG_SUPPORT -ljpeg
all: $(EXE)
$(EXE): $(CXXOBJ)
$(CXX) $(CXXOBJ) -o $(EXE) $(LIBS) $(LDFLAGS)
$(OBJ_DIR)/%.o: src/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -c -o $#
$(BUILD)
run: all
./$(EXE)
clean:
-rm -f $(EXE) $(CXXOBJ)
rmdir obj/
It needs some modification as INCLUDE, CXXFLAGS AND LDFLAGS will be
INCLUDE = -Iinclude -Iinclude/darknet `pkg-config --cflags-only-I opencv`
CXXFLAGS = -Wall -Wno-unknown-pragmas -Wfatal-errors -Wwrite-strings -fPIC
LDFLAGS = -lm -pthread -lX11 -DDLIB_JPEG_SUPPORT -ljpeg -lopencv_videoio `pkg-config --libs opencv`
and i'm now using darknet makefile to do it so my makefile looks like
VPATH = ./src/
ALIB = external_libs/libdarknet.a
EXEC = darknet
OBJDIR = ./obj/
CC = g++ -std=c++11
NVCC = nvcc
AR = ar
ARFLAGS = rcs
OPTS = -Ofast
LDFLAGS = -lm -pthread -lX11 -DDLIB_JPEG_SUPPORT -ljpeg -lopencv_videoio `pkg-config --libs opencv`
INCLUDE = -Iinclude -Iinclude/darknet `pkg-config --cflags-only-I opencv`
CFLAGS = -Wall -Wno-unknown-pragmas -Wfatal-errors -Wwrite-strings -fPIC
OBJ = CDetector.o CStreamReader.o
EXECOBJA = CDetector.o CStreamReader.o
EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA))
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet/darknet.h
all: obj results $(ALIB) $(EXEC)
$(EXEC): $(EXECOBJ) $(ALIB)
$(CC) $(INCLUDE) $(CFLAGS) $^ -o $# $(LDFLAGS) $(ALIB)
$(ALIB): $(OBJS)
$(AR) $(ARFLAGS) $# $^
$(OBJDIR)%.o: %.cpp $(DEPS)
$(CC) $(INCLUDE) $(CFLAGS) -c $< -o $#
obj:
mkdir -p obj
backup:
mkdir -p backup
results:
mkdir -p results
.PHONY: clean
clean:
rm -rf $(OBJS) $(ALIB) $(EXEC) $(EXECOBJ)

Adding c++ to complex C makefile

I would like to add a cpp file to use the c functions. I made the file but the problem becomes how to include the file in the makefile.All I know is that I should compile with c++ after C. and then link it together.
May someone point me in the right direction.
This is a snippet of testcpp.cpp
extern "C" {
#include "darknet.h"
}
Below is the makefile but i keep getting No rule to make target 'obj/test.cpp', needed by 'darknet'.
GPU=0
CUDNN=0
OPENCV=0
NNPACK=1
NNPACK_FAST=1
ARM_NEON=1
OPENMP=0
DEBUG=0
QPU_GEMM=1
ARCH= -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=[sm_50,compute_50] \
-gencode arch=compute_52,code=[sm_52,compute_52]
# -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?
# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52
VPATH=./src/:./examples
SLIB=libdarknet.so
ALIB=libdarknet.a
EXEC=darknet
OBJDIR=./obj/
CC=gcc
NVCC=nvcc
AR=ar
ARFLAGS=rcs
OPTS=-Ofast
LDFLAGS= -lm -pthread
COMMON= -Iinclude/ -Isrc/
#CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC
#CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC -march=native -mfpmath=sse
CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC -mcpu=cortex-a53
ifeq ($(OPENMP), 1)
CFLAGS+= -fopenmp
endif
ifeq ($(DEBUG), 1)
OPTS=-O0 -g
endif
CFLAGS+=$(OPTS)
ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv`
COMMON+= `pkg-config --cflags opencv`
endif
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
ifeq ($(CUDNN), 1)
COMMON+= -DCUDNN
CFLAGS+= -DCUDNN
LDFLAGS+= -lcudnn
endif
ifeq ($(QPU_GEMM), 1)
COMMON+= -DQPU_GEMM
CFLAGS+= -DQPU_GEMM
LDFLAGS+= -lqmkl
endif
ifeq ($(NNPACK), 1)
COMMON+= -DNNPACK
CFLAGS+= -DNNPACK
LDFLAGS+= -lnnpack -lpthreadpool
endif
ifeq ($(NNPACK_FAST), 1)
COMMON+= -DNNPACK_FAST
CFLAGS+= -DNNPACK_FAST
endif
ifeq ($(ARM_NEON), 1)
COMMON+= -DARM_NEON
CFLAGS+= -DARM_NEON -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize
endif
OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o
EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o attention.o darknet.o
EXECOBJA1=testcpp.cpp
ifeq ($(GPU), 1)
LDFLAGS+= -lstdc++
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o avgpool_layer_kernels.o
endif
EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA))
EXECOBJ1 = $(addprefix $(OBJDIR), $(EXECOBJA1))
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h
CPP=g++
#all: obj backup results $(SLIB) $(ALIB) $(EXEC)
all: obj results $(SLIB) $(ALIB) $(EXEC)
$(EXEC): $(EXECOBJ) $(ALIB)
$(CC) $(COMMON) $(CFLAGS) $^ -o $# $(LDFLAGS) $(ALIB)
$(EXEC): $(EXECOBJ1)
$(CPP) -Wall $^ -o $# $(LDFLAGS)
$(ALIB): $(OBJS)
$(AR) $(ARFLAGS) $# $^
$(SLIB): $(OBJS)
$(CPP) $(CFLAGS) -shared $^ -o $#
$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $#
$(OBJDIR)%.o: %.cu $(DEPS)
$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $#
obj:
mkdir -p obj
backup:
mkdir -p backup
results:
mkdir -p results
.PHONY: clean
clean:
rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ)
I thought
$(EXEC): $(EXECOBJ1)
$(CPP) -Wall $^ -o $# $(LDFLAGS)
would compile the cpp file and
$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $#
would link it
I think you need a recipe to compile object files from .cpp file:
$(OBJDIR)%.o: %.cpp $(DEPS)
$(CXX) $(COMMON) $(CFLAGS) -c $< -o $#
The error you describe probably comes from an incorrect usage of vpath: I don't think its usage is necessary here.
But basically I agree with #Basile Starynkevitch : you might be better rewriting from scratch. I have a few suggestions:
1 - Clearly separate in different folders programs (C or C++ files that hold a main() function) and library files (C or C++ files that hold functions). This will be useful for linking.
For example:
|
+--lib // holds "library" code
+--app // holds programs
+--headers
+--BUILD
|
+-- obj
| |
| +-- app
| +-- lib
|
+-- bin
2 - Automatically generate both object files and programs from source files:
SRC_FILES_LIB = $(wildcard lib/*.cpp)
SRC_FILES_APP = $(wildcard app/*.cpp)
OBJ_FILES_LIB = $(patsubst lib/%.cpp,BUILD/obj/lib/%.o,$(SRC_FILES_LIB))
OBJ_FILES_APP = $(patsubst app/%.cpp,BUILD/obj/app/%.o,$(SRC_FILES_APP))
EXEC_FILES = $(patsubst app/%.cpp,BUILD/bin/%,$(SRC_FILES_APP))
3 - add a target that builds the programs:
all: $(EXEC_FILES)
#echo "done"
After that, its just a matter of providing the sufficient pattern rule.
(sorry, no more time for that)

Confused by a Makefile error "src/Sort.cpp:3:18: fatal error: Sort.h: no such file or directory"

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!

Makefile: No rule to make target 'xyz', needed by 'all'

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)

My makefile isn't finding my include paths

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