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)
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)
This is how my makefile looks like, I have seperata cudaex.cu cudaaex.h plotter.c plotter.h and mainfn.cpp files. I compiled and created .o files separately. But I cant link them and make an executable file. If further informations needed I can post other codes also.
CUDA ?= /usr/local/cuda
CUDA_LIB :=-L $(CUDA)/lib64 -L $(CUDA)/lib -L /usr/lib64/nvidia -L /usr/lib/nvidia
CUDA_INC += -I $(CUDA)/include
program_INCLUDE_DIRS := ./src
program_LIBRARY_DIRS :=
LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir))
LDFLAGS += $(CUDA_LIB) -L $(CUDA)/lib64
LIBS += -lcudart -lcuda -lpthread -ldl
CC = gcc
NCC = nvcc
CPP = g++
CFLAGS = -O3 -I./src
RM = rm -f
program_OBJS:= gnuplot_i.o cudaex.o plotter.o mainfn.o
default: gnuplot_i.o cudaex.o plotter.o mainfn.o all
gnuplot_i.o: src/gnuplot_i.c src/gnuplot_i.h
$(CC) $(CFLAGS) -c -o gnuplot_i.o src/gnuplot_i.c
cudaex.o:
$(NCC) -c -o cudaex.o cudaex.cu
plotter.o: plotter.c gnuplot_i.o plotter.h
$(CC) $(CFLAGS) -c -o plotter.o plotter.c
mainfn.o: mainfn.cpp cudaex.h plotter.h plotter.o gnuplot_i.o
$(CPP) -c -o mainfn.o mainfn.cpp
all: mainfn
mainfn: $(program_OBJS)
g++ $(program_OBJS) -o mainfn $(LDFLAGS) $(LIBS)
clean:
$(RM) gnuplot_i.o cudaex.o plotter.o mainfn.o mainfn
this is the output of the make command
make: *** No rule to make target `glslshaders.o', needed by `openglframework'. Stop.
Who can help?!!
Here is my make file:
# GNU (everywhere)
CC = gcc -g -Wall
# GNU (faster)
#CPP = gcc -O5 -Wall -fomit-frame-pointer -ffast-math
UNAME := $(shell uname)
ifeq ($(UNAME),)
UNAME := MINGW
endif
EXECUTABLE = openglframework
OBJS = openglframework.o glslshaders.o glm.o
ifeq ($(UNAME),Darwin)
LIBS = -lm -framework OpenGL -framework GLUT
else
ifeq ($(findstring MINGW,$(UNAME)),MINGW)
CC += -Iincludes -DNEED_GLEW -DGLEW_STATIC
OBJS += glew.o
LIBS = -lm -lopengl32 -lglu32 -Llibs -lfreeglut
else
LIBS = -lm -lGL -lglut -lGLU
endif
endif
### TARGETS
$(EXECUTABLE): $(OBJS)
$(CC) $(OBJS) $(LIBS) -o $#
depend:
make.dep
clean:
- /bin/rm -f *.bak *~ $(OBJS) $(EXECUTABLE) $(EXECUTABLE).exe
make.dep:
$(CC) -MM $(OBJS:.o=.c) > make.dep
### RULES
.SUFFIXES:
.c .cpp .o .in .ppm .png .jpg .gif
.cpp.o:
$(CC) -c $< .c.o: $(CC) -c $<
### DEPENDENCIES
include make.dep
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 $#