Makefile not using include/library paths? - c++

Well, after 3 hours of researching, I'm about to go insane, so I figure it's time to pass it off to some new eyes.
CXXFLAGS = -g -Wall
OBJS = main.o
PROG = test
INCLUDES = -I /usr/include/mysql -I /usr/local/include
LIBS = -L /usr/lib/mysql -l libmysqlclient.so.15.0.0 -L /usr/local/lib -l libmysqlpp.so.3.1.0
all: $(PROG)
${PROG}: $(OBJS)
$(CXX) $(INCLUDES) -o $(PROG) $(OBJS) $(LIBS)
clean:; $(RM) -f $(PROG) core *.o
There's something wrong with the include paths, because I get errors that mysql_version.h does not exist when it clearly does exist in /usr/include/mysql.
Checking the first part out of the ouput, it says
g++ -g -Wall -c -o main.o main.cpp
which makes me think that I've formatted something in the Makefile wrong (due to the extra spaces and lack of include/library paths). However, I've looked at dozens of manuals and articles on Makefiles and the g++ options and... no progress.
I assume this should be a simple fix. Please, please help (do you sense my despair?).
On another note, do you think specifying the library specifically is necessary? I had this stuff running in XCode just fine, but I'm trying to migrate the code to my web server... the Makefile has stopped all progress, and I figure it's something I should learn from.

In your makefile, you have added your include directives to the linking stage, not the compiling stage.
The lines
${PROG}: $(OBJS)
$(CXX) $(INCLUDES) -o $(PROG) $(OBJS) $(LIBS)
Say to make the program in ${PROG} from object files in ${OBJS} by calling the compiler in ${CXX} passing the include folders (along with your other arguments). Instead, for your variable section, do this:
INCLUDES = -I /usr/include/mysql -I /usr/local/include
CXXFLAGS = -g -Wall ${INCLUDES}
OBJS = main.o
PROG = test
LIBS = -L /usr/lib/mysql -l libmysqlclient.so.15.0.0 -L /usr/local/lib -l libmysqlpp.so.3.1.0
This way your CXXFLAGS (which are used for the compile stage) should now pickup your include directives.

Related

How to make an object file in a different folder with c++ and a makefile

When I run my code I get the error
g++ -c -o main.o main.cpp
g++ -I -o obj/main.o -lm
g++ error: obj/main.o: No such file or directory
makefile:21: recipe for target 'main' failed
make: *** [main] Error 1
In my file structure I have a folder with everything in it so I am trying to make some subdirectories and organize everything a little bit. I am trying to get the object file (main.o) to go into an obj folder instead of staying in the base folder as it currently is.
I can't figure out what is going wrong in my makefile and can't find where some of this is being executed and am extremely new to c++ and make. My code is pasted below.
IDIR=../include
CC = g++
CFLAGS = -I
LDIR = ../lib
ODIR= obj
LIBS = -lm
_DEPS = add.h multiply.h
DEPS = $(patsubst %, $(IDIR)/%,$(_DEPS))
_OBJ = main.o
OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: $(OBJ)
$(CC) -c $(CFLAGS) $< -o $#
main: $(_OBJ)
$(CC) $(CFLAGS) -o$(OBJ) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
I haven't read any specific documentation as I have been teaching myself by simply searching the internet for tons of small bits from many different sources. I am using Windows 10 with visual studio code as my compiler and make g++ as my make utility. I apologize for commenting on my own question as this is my first time using Stack Overflow and didn't know I could get in trouble for commenting. I am sorry for causing a mess.
g++ -c -o obj/main.o main.cpp
you must provide the path for the output file

Shared libraries C++ Makefile

I need to compile fat binary file to be able use it on another linux machine. But there are some libraries missing so as I understand I should compile it with some -shared options. But I don't understand how to configure a Makefile for that. Currently my makefile looks like this:
CC = g++
CC_FLAGS = -std=c++11 -O2 -static -Wall
EXEC = cpp_server
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
LIBS = -lpthread -lmicrohttpd -lz
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC) $(LIBS)
%.o: %.cpp
$(CC) -c $(CC_FLAGS) $< -o $#
clean:
rm -f $(EXEC) $(OBJECTS)
You'll better take advantage of the many built-in rules of GNU make. Run once make -p to learn them. So you should use CXX instead of CC and replace CC_FLAGS with CXXFLAGS.
You may want to build a statically linked executable. Then you should pass -static into your linking command, using LINKFLAGS
So try with
## untested Makefile for GNU make
# variables known to make
CXX= g++
CXXFLAGS= -std=c++11 -O2 -Wall -Wextra
LINKFLAGS= -static
LIBS= -lpthread -lmicrohttpd -lz
# this project needs:
MYEXEC= cpp_server
MYSOURCES= $(wildcard *.cpp)
MYOBJECTS= $(SOURCES:.cpp=.o)
.PHONY: all clean
all: $(MYEXEC)
$(MYEXEC): $(MYOBJECTS)
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $#
clean:
rm -f $(MYEXEC) $(MYOBJECTS)
AFAIK you don't need anything more in your Makefile (provided you use a GNU make, not e.g. a BSD one). Of course you need appropriate TAB characters in your Makefile (so you need to use some editor able to insert them).
You could want to statically link only -lmicrohttpd (and dynamically link the other libraries; however, you might want to also statically link the C++ standard library, which depends upon the compiler and could change when the compiler changes; linking also the C++ library statically is left as an exercise). You could do that with removing the LINKFLAGS line and using
LIBS= -Bstatic -lmicrohttpd -Bdynamic -lz -lpthread
BTW the -shared linker option is need to build from position-independent code object files a shared library (not to use one). See this and that.
You may want to use make --trace (or remake -x, using remake) to debug your Makefile
If you want to understand what actual files are linked, add -v -Wl,--verbose to LINKFLAGS perhaps by running make 'LINKFLAGS=-v -Wl,--verbose' on your terminal.
You might want to make clean before anything else.

How to do makefile to compile multiple .cpp files in different directories using a single makefile?

I have the following files in my proj2 directories and need to compile them together to have one executable file.
proj2/main.cpp
proj2/model/Player.cpp
proj2/model/gameBoard.cpp
proj2/controller/TTTController.cpp
proj2/Makefile
I'm using the following command inside my makefile, but it is not working.
all:
g++ /project2_p1/main.cpp /project2_p1/controller/TTTController.cpp /model/gameBoard.cpp /model/Player.cpp -o ttt
clean:
-rm ttt
Can anybody help me please.Thank you
I strongly recommend you start learning make as it is one of the fundamental tools that programmers use. And, if you can learn C++, you can definitely learn make.
In your project you have source files buried in their own subdirectories so in order to find them all you can use the $(shell find...) command. Same with any header files in your project.
By making all: the direct target it gets executed unconditionally and you lose the benefits of using make - only compile when you change something.
Having said that the basic template I am providing here could be improved to recompile only those source files that have changed but that's an exercise for the reader.
I think this should work in your case:
# set non-optional compiler flags here
CXXFLAGS += -std=c++11 -Wall -Wextra -pedantic-errors
# set non-optional preprocessor flags here
# eg. project specific include directories
CPPFLAGS +=
# find cpp files in subdirectories
SOURCES := $(shell find . -name '*.cpp')
# find headers
HEADERS := $(shell find . -name '*.h')
OUTPUT := ttt
# Everything depends on the output
all: $(OUTPUT)
# The output depends on sources and headers
$(OUTPUT): $(SOURCES) $(HEADERS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(OUTPUT) $(SOURCES)
clean:
$(RM) $(OUTPUT)
thats my minGW project's makefile codes:
hepsi: derle calistir
Nesneler := ./lib/Hata.o ./lib/Hatalar.o ./lib/Dugum.o ./lib/ListeGezici.o ./lib/BagilListe.o
derle:
g++ -I ./include/ -o ./lib/Hata.o -c ./src/Hata.cpp
g++ -I ./include/ -o ./lib/Hatalar.o -c ./src/Hatalar.cpp
g++ -I ./include/ -o ./lib/Dugum.o -c ./src/Dugum.cpp
g++ -I ./include/ -o ./lib/ListeGezici.o -c ./src/ListeGezici.cpp
g++ -I ./include/ -o ./lib/BagilListe.o -c ./src/BagilListe.cpp
g++ -I ./include/ -o ./bin/test $(Nesneler) ./src/test.cpp
calistir:
./bin/test
In your project I think this will work;
all: compile run
Objects := ./lib/Player.o ./lib/gameBoard.o ./lib/TTTController.o
compile:
g++ -I ./include/ -o ./lib/Player.o -c ./model/Player.cpp
g++ -I ./include/ -o ./lib/gameBoard.o -c ./model/gameBoard.cpp
g++ -I ./include/ -o ./lib/TTTController.o -c .controller/TTTController.cpp
g++ -I ./include/ -o ./bin/main $(Objects) ./main.cpp
run:
./bin/main
lib folder contains .o files. You can chance it if you want.
include folder refers your header .h or .hpp files. You can change every one of them according to your headers location.
bin folder contains your .exe file called main.exe. You can change or remove it like that
run:
./main
I hope it'll work.
#Galik has right. if you want to learn C++, you should definitely learn make.

Makefile to build shared library

I've been building a C++11 library, and the number of header/source files has grown to the point where compiling programs invoking it, entails passing 20+ .cpp files to g++. I've been reading up on shared libraries and it seems to be the best solution.
However, as headers/source change frequently, I'm hoping to create a makefile that would automatically generate all the .so files from the headers and source.
To better demonstrate what I'm trying to do, I'll take one of my sub-libraries, Chrono and show how I would do this manually.
I first create the object files like so,
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/DateTime.cpp
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/Schedule.cpp
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/Duration.cpp
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/DayCount.cpp
So that I now have DateTime.o, Schedule.o, Duration.o, and DayCount.o in the current directory. I then create the .so file,
$ g++ -shared -Wl,-soname,libChrono.so.1 -o libChrono.so.1.0.1 DateTime.o Schedule.o Duration.o DayCount.o -lc
I then go,
$ rm ./*.o && ldconfig -n ./
So that my working directory now contains, libChrono.so.1.0.1 and the symlink libChrono.so.1.
There are quite a few subdirectories I need to do this for, so you can see that this quickly grows inefficient whenever changes to headers/source are made. I would be grateful if anyone can help me design a makefile that accomplishes all this simply by invoking make.
Thanks!
UPDATE:
Based on goldilock's advice and some digging, I managed to bang together:
CXX=g++
CFLAGS=-std=c++11
TARGET=./lib/libChrono.so.1.0.1
CHRONODIR=./src/Chrono
CHRONOSRC=$(wildcard $(CHRONODIR)/cpp/*.cpp)
CHRONOOBJ=$(join $(addsuffix ../obj/, $(dir $(CHRONOSRC))), $(notdir (CHRONOSRC:.cpp=.o)))
all: $(TARGET)
#true
clean:
#-rm -f $(TARGET) $(CHRONOOBJ)
./lib/libChrono.so.1.0.1: $(CHRONOOBJ)
#echo "======================="
#echo "Creating library file $#"
#echo "======================="
#$(CXX) -shared -Wl,-soname,$(join $(basename $#), .1) -o $# $^ -l
#echo "-- $# file created --"
$(CHRONODIR)/cpp/../obj/%.o : $(CHRONOSRC)
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CXX) $(CFLAGS) -fPIC -g -Wall -c $< -o $#
4 .o files are produced in lib/ but I get multiple definition complaints from ld. Before I was compiling the object files separately, but this unwinds CHRONOOBJ on one line. Any ideas?
Fortunately you included the origin of your problem:
I've been building a C++11 library, and the number of header/source files has grown to the point where compiling programs invoking it, entails passing 20+ .cpp files to g++.
Because this reveals a potential XY problem. The straightforward solution to this is to put object files into an archive (aka. a static library) and use that.
GNU make has an implicit rule for creating C++ .o files. It amounts to this:
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
Meaning, if you make DateTime.o in a directory with a makefile that doesn't redefine this, it will make DateTime.o. You may want to add things to $(CXXFLAGS) however, e.g.:
CXXFLAGS += -Wall -Wextra --std=c++11
If you intend to stick with the shared lib route, -fPIC can go there too. That one line could be your entire makefile.
However, you also want to put these together, so you must first declare all the objects and a rule for combining them:
OBJS = DateTime.o Schedule.o Duration.o
libChrono.a: $(OBJS)
ar crvs $# $^
This last line (see man ar) creates the archive (libChrono.a) containing all the objects in $(OBJS). You can then use this with whatever program by placing it in the same directory (or a directory in the library path) and linking -lChrono. Only the necessary parts will be extracted and compiled in. This saves you having to maintain a shared lib in a system directory.
If you still think you need a shared lib, $# and $^ are automatic variables; you can use similar methodology to create a .so, something along the lines of:
SO_FLAGS = -shared
libChrono.so.1.0.1: $(OBJS)
$(CXX) $(SO_FLAGS) -Wl,-soname,libChrono.so.1 -o $# $^ -lc
If that is your first rule, make will take care of everything: building first the objects and then the library. Notice this one has excluded your normal $(CXXFLAGS) to duplicate exactly the compiler line from the question.

How to link jsoncpp?

How can I link jsoncpp with a C++ program using g++? I tried:
g++ -o program program.cpp -L/path/to/library/files -ljsoncpp, -ljson, -llibjsoncpp
but g++ keeps saying:
/usr/bin/ld: cannot find -lsomething
You could also try using the new Amalgamated version of jsoncpp, which is new as of version 0.6.0.
The Amalgamated version allows you to use jsoncpp by adding just one directory with a couple of header files and one .cpp file to your project. You then can directly compile jsoncpp into your program with no worries about having to link to any jsoncpp libraries.
Look in /path/to/library/files to see what your *.a file is really named. On my system, I link with:
-ljson_linux-gcc-4.4.3_libmt
Some libraries will create a link from lib<name>.a to lib<name>-<version>.a for you, but I don't think that jsoncpp does this automatically. Therefore, you need to specify the complete name when linking.
You basically need to tell the path and the library.
jsoncpp library has pkg-config and you can use the command
`pkg-config --cflags path/to/jsoncpp/build/pkg-config/jsoncpp.pc`
for the include path and
`pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc`
for linking (when running the command with g++ use the ). To see the single commands which is -L/libraryPath -ljsoncpp) run the commands above in the terminal without the ``.
It is easier to use this commands in a Makefile. As example my Makefile is:
CXX = g++
CXXFLAGS = -std=c++11
INC_PATH = `pkg-config --cflags ../jsoncpp/build/pkg-config/jsoncpp.pc`
LIBS = `pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc`
SOURCES := $(wildcard *.cpp)
OBJDIR=obj
OBJECTS := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SOURCES))
DEPENDS := $(patsubst %.cpp,$(OBJDIR)/%.d,$(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: yourProjectExecutableName
clean:
$(RM) $(OBJECTS) $(DEPENDS) parking
# Linking the executable from the object files
yourProjectExecutableName: $(OBJECTS)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $# $(LIBS)
-include $(DEPENDS)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: %.cpp Makefile $(OBJDIR)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) -MMD -MP -c $< -o $#
and then in the directory of the file I run make. The final command(s) will be printed out in the Terminal