Create a debug file when compiling each source file separately using makefile - c++

I am doing a c++ project with multiple source files and trying to get used to using makefiles. I want to be able to debug this program with gdb. If I use the following command in Terminal to compile, it works fine:
g++ -o main -g *.cpp
But if I just call make it doesn't generate a debug file (the .dSYM file) even though it compiles the program fine. I assume this has something to do with creating the individual object files first. Here is my makefile:
all: main.o sort.o bubble.o quickSort.o rbs.o
g++ -g -o main *.o -Wall -O2
main.o: main.cpp
g++ -c main.cpp
sort.o: sort.cpp sort.h
g++ -c sort.cpp
bubble.o: bubble.cpp bubble.h
g++ -c bubble.cpp
quickSort.o: quickSort.cpp quickSort.h
g++ -c quickSort.cpp
rbs.o: rbs.cpp rbs.h
g++ -c rbs.cpp
clean:
rm *.o
How do I create the main.dSYM debug file when using a makefile like this?

If you want the debug files, you must compile all of the components with -g.
The crude way to do this would be to add -g to every object rule:
all: main.o sort.o bubble.o quickSort.o rbs.o
g++ -g -o main *.o -Wall -O2
main.o: main.cpp
g++ -c -g main.cpp
sort.o: sort.cpp sort.h
g++ -c -g sort.cpp
bubble.o: bubble.cpp bubble.h
g++ -c -g bubble.cpp
quickSort.o: quickSort.cpp quickSort.h
g++ -c -g quickSort.cpp
rbs.o: rbs.cpp rbs.h
g++ -c -g rbs.cpp
But that doesn't leave you the option of building without debug information. And there's a lot of redundancy in this makefile. Let's take this in stages. First, we put in automatic variables to simplify the rules:
all: main.o sort.o bubble.o quickSort.o rbs.o
g++ -g -o main $^ -Wall -O2
main.o: main.cpp
g++ -c -g $<
sort.o: sort.cpp sort.h
g++ -c -g $<
bubble.o: bubble.cpp bubble.h
g++ -c -g $<
quickSort.o: quickSort.cpp quickSort.h
g++ -c -g $<
rbs.o: rbs.cpp rbs.h
g++ -c -g $<
Now we see that all of the *.o rules have the same command, which reminds us that Make already knows how to build foo.o from foo.cpp, with a command that looks like:
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
So all we have to do is add -g to CXXFLAGS, and we can omit the commands entirely:
CXXFLAGS += -g
all: main.o sort.o bubble.o quickSort.o rbs.o
g++ -g -o main $^ -Wall -O2
sort.o: sort.h
bubble.o: bubble.h
quickSort.o: quickSort.h
rbs.o: rbs.h
Now that that's in order, we can set up two top-level targets, main and debug, and change CXXFLAGS only for the latter:
debug: CXXFLAGS += -g
main debug: main.o sort.o bubble.o quickSort.o rbs.o
g++ -g -o $# $^ -Wall -O2
sort.o: sort.h
bubble.o: bubble.h
quickSort.o: quickSort.h
rbs.o: rbs.h
You can improve this even more, but that should get you started.

Related

c++ makefile cant find directories

I am trying to run makefile but I cant make him find the files I add to it unless I put full path of the file: /home/"user_name"/CLionProjects/Ass1/src/main.cpp
I try to run the makefile when I am in Ass1 so as much that I understand the makefile should find the main.cpp .
Would love to know where I am wrong here, thank you.
what I write:
all: clean compile link
link:
g++ -o /bin/main /home/daniel/CLionProjects/Ass1/bin/main.o /home/daniel/CLionProjects/Ass1/bin/Workout.o /home/daniel/CLionProjects/Ass1/bin/Trainer.o /home/daniel/CLionProjects/Ass1/bin/Studio.o
compile:
g++ -g -Wall -Weffc++ -c -o bin/main.o /home/daniel/CLionProjects/Ass1/src/main.cpp
g++ -g -Wall -Weffc++ -c -o bin/Studio.o /home/daniel/CLionProjects/Ass1/src/Studio.cpp
g++ -g -Wall -Weffc++ -c -o bin/Workout.o /home/daniel/CLionProjects/Ass1/src/Workout.cpp
g++ -g -Wall -Weffc++ -c -o bin/Trainer.o /home/daniel/CLionProjects/Ass1/src/Trainer.cpp
clean:
rm -f bin/*
what I want to write and cant:
all: clean compile link
link:
g++ -o /bin/main /bin/main.o /bin/Workout.o /bin/Trainer.o /bin/Studio.o
compile:
g++ -g -Wall -Weffc++ -c -o bin/main.o /src/main.cpp
g++ -g -Wall -Weffc++ -c -o bin/Studio.o /src/Studio.cpp
g++ -g -Wall -Weffc++ -c -o bin/Workout.o /src/Workout.cpp
g++ -g -Wall -Weffc++ -c -o bin/Trainer.o /src/Trainer.cpp
clean:
rm -f bin/*
the error I get:
rm -f bin/*
g++ -g -Wall -Weffc++ -c -o bin/main.o /src/main.cpp
g++: error: /src/main.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
make: *** [makefile:7: compile] Error 1

Running HTTP server example from Boost Asio

I'm getting errors when trying to run the HTTP server example that comes with the source of the boost library, under the path: boost_1_59_0/libs/asio/example/cpp11/http/server/.
I already ran this following commands in the boost_1_59_0 directory:
$ ./bootstrap.sh
$ sudo ./bjam install
$ sudo ./b2 install
After installing all targets, i tried to compile the main.cpp and the server.cpp with this command: g++ -std=c++0x -o main main.cpp -I "/home/user/Desktop/boost_1_59_0" -L "/home/user/Desktop/boost_1_59_0/libs/" -lboost_system.
Any suggestion on how to compile this server example?
I linked all files from the boost_1_59_0/libs/asio/example/cpp11/http/server/ folder after the main.cpp, as #Richard Hodges suggested. It still didn't work, i got errors concerning lpthread, so i added it to the compiling options. The program compiled but it failed the execution, returning an error saying that it didn't find the library libboost_system.so.1.59.0. I tried linking the folders with -L /path/to/library but it didn't work.
Solution:
My compilation command:
g++ -std=gnu++0x -o main main.cpp server.cpp connection.cpp connection_manager.cpp reply.cpp mime_types.cpp request_handler.cpp request_parser.cpp -I "/home/user/Desktop/boost_1_59_0" -lboost_system -lpthread
I solved it with this commands:
$ LD_LIBRARY_PATH="/usr/local/lib/"
$ sudo ldconfig
And then I just ran the executable and it worked!
Here's a simple makefile I just concocted that works:
all:server
CPPFLAGS+=-std=c++11 -Wall -pedantic
CPPFLAGS+=-g -O2
CPPFLAGS+=-pthread
LDFLAGS+=-lboost_system
%.o:%.cpp
$(CXX) $(CPPFLAGS) $^ -c -o $#
server:$(patsubst %.cpp,%.o,$(wildcard *.cpp))
$(CXX) $(CPPFLAGS) $^ -o $# $(LDFLAGS)
It runs make:
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread connection.cpp -c -o connection.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread connection_manager.cpp -c -o connection_manager.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread main.cpp -c -o main.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread mime_types.cpp -c -o mime_types.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread reply.cpp -c -o reply.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread request_handler.cpp -c -o request_handler.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread request_parser.cpp -c -o request_parser.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread server.cpp -c -o server.o
g++ -std=c++11 -Wall -pedantic -g -O2 -pthread connection.o connection_manager.o main.o mime_types.o reply.o request_handler.o request_parser.o server.o -o server -lboost_system
And the test program runs:
$ ./server 0.0.0.0 9889 . &
$ GET http://localhost:9889/main.cpp > main.cpp.0
Check the files
$ md5sum main.cpp*
be5dc1c26b5942101a7895de6baedcee main.cpp
be5dc1c26b5942101a7895de6baedcee main.cpp.0
Don't forget to kill the server when you're done

Makefile: Object are not removed after compiling and linking

Following makefile works except cleaning the object files after compiling and linking. I tried make clean which does exactly what I want: deletes the executable and the object files in all folders. I also included the outputs of make and make clean. Any idea?
Makefile:
CC=g++
CFLAGS=-c -std=c++11 -O2 -O3
SOURCES=main.cpp\
BoundaryConditions/BoundaryConditions.cpp\
Cell/Cell.cpp\
Face/Face.cpp\
Formulation/Explicit/Explicit.cpp\
Formulation/Implicit/Implicit.cpp\
Grid/Grid.cpp\
Grid/ReadGrid.cpp\
Grid/SetGrid.cpp\
Init/Init.cpp\
InterFlux/Interflux.cpp\
InterFlux/Roe/Roe.cpp\
Matrix5/Operators.cpp\
Output/Output.cpp\
Solver/GaussSeidel.cpp\
Vector/Vector.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=codeBaku
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
.PHONY: clean
clean:
rm -rf $(OBJECTS) $(EXECUTABLE)
Output of make:
g++ -c -std=c++11 -O2 -O3 main.cpp -o main.o
g++ -c -std=c++11 -O2 -O3 BoundaryConditions/BoundaryConditions.cpp -o BoundaryConditions/BoundaryConditions.o
g++ -c -std=c++11 -O2 -O3 Cell/Cell.cpp -o Cell/Cell.o
g++ -c -std=c++11 -O2 -O3 Face/Face.cpp -o Face/Face.o
g++ -c -std=c++11 -O2 -O3 Formulation/Explicit/Explicit.cpp -o Formulation/Explicit/Explicit.o
g++ -c -std=c++11 -O2 -O3 Formulation/Implicit/Implicit.cpp -o Formulation/Implicit/Implicit.o
g++ -c -std=c++11 -O2 -O3 Grid/Grid.cpp -o Grid/Grid.o
g++ -c -std=c++11 -O2 -O3 Grid/ReadGrid.cpp -o Grid/ReadGrid.o
g++ -c -std=c++11 -O2 -O3 Grid/SetGrid.cpp -o Grid/SetGrid.o
g++ -c -std=c++11 -O2 -O3 Init/Init.cpp -o Init/Init.o
g++ -c -std=c++11 -O2 -O3 InterFlux/Interflux.cpp -o InterFlux/Interflux.o
g++ -c -std=c++11 -O2 -O3 InterFlux/Roe/Roe.cpp -o InterFlux/Roe/Roe.o
g++ -c -std=c++11 -O2 -O3 Matrix5/Operators.cpp -o Matrix5/Operators.o
g++ -c -std=c++11 -O2 -O3 Output/Output.cpp -o Output/Output.o
g++ -c -std=c++11 -O2 -O3 Solver/GaussSeidel.cpp -o Solver/GaussSeidel.o
g++ -c -std=c++11 -O2 -O3 Vector/Vector.cpp -o Vector/Vector.o
g++ main.o BoundaryConditions/BoundaryConditions.o Cell/Cell.o Face/Face.o Formulation/Explicit/Explicit.o Formulation/Implicit/Implicit.o Grid/Grid.o Grid/ReadGrid.o Grid/SetGrid.o Init/Init.o InterFlux/Interflux.o InterFlux/Roe/Roe.o Matrix5/Operators.o Output/Output.o Solver/GaussSeidel.o Vector/Vector.o -o codeBaku
Output of make clean:
rm -rf main.o BoundaryConditions/BoundaryConditions.o Cell/Cell.o Face/Face.o Formulation/Explicit/Explicit.o Formulation/Implicit/Implicit.o Grid/Grid.o Grid/ReadGrid.o Grid/SetGrid.o Init/Init.o InterFlux/Interflux.o InterFlux/Roe/Roe.o Matrix5/Operators.o Output/Output.o Solver/GaussSeidel.o Vector/Vector.o codeBaku
It is unusual to automatically remove the object files, since that would mean everything would have to be recompiled each time, even if you only change one source file. However, if you really want to do it, you could do something like this:
all: $(SOURCES) $(EXECUTABLE)
rm $(OBJECTS)

How do I use g++ to create object file with a specific name

I am making a makefile and one of the targets is exptrtest.o how do I use g++ to create an objectfile with that name, the name of my cpp file is exprtest.cpp not exptrtest.cpp?
exptrtest.o: exprtest.cpp
g++ -Wall -g -c exprtest.cpp
to make it more clear, this is my makefile:
all: exprtest
exprtest: exptrtest.o driver.o parser.tab.o scanner.o
g++ -Wall -g -o exprtest exptrtest.o driver.o parser.tab.o scanner.o
exptrtest.o: exprtest.cpp
g++ -Wall -g -c exptrtest.o exprtest.cpp
driver.o: driver.cpp scanner.hpp driver.hpp
g++ -Wall -g -c driver.cpp
parser.tab.o: parser.tab.hpp parser.tab.cpp
bison parser.ypp
g++ -Wall -g -c parser.tab.cpp
scanner.o: scanner.cpp scanner.hpp
flex -t scanner.ll > scanner.cpp
g++ -Wall -g -c scanner.cpp
clean:
rm parser.tab.hpp parser.tab.cpp scanner.cpp
I'm getting the error:
"g++: error: exptrtest.o: No such file or directory
make: * [exprtest] Error 1"
Use the -o option in conjunction with -c.
exptrtest.o: exprtest.cpp
g++ -Wall -g -c exprtest.cpp -o exptrtest.o

Problem with makefile making .gch files instead of.o files

So, I'm making a program to test the efficiency of certain data structures. I have all the .h files and I made a very terrible makefile that probably is wrong, although it seems to work up to a point. Instead of making .o files it makes .gch files, so when it tries to acces all the .o files they are not found. This is my makefile
prog1: main.o dsexceptions.o BinarySearchTree.o SplayTree.o RedBlackTree.o AvlTree.o
g++ -Wall -g -o prog1 main.o dsexceptions.h.gch BinarySearchTree.h.gch SplayTree.h.gch RedBlackTree.h.gch AvlTree.h.gch
main.o: main.cpp AvlTree.h RedBlackTree.h SplayTree.h BinarySearchTree.h dsexceptions.h
g++ -Wall -g -c main.cpp
#shape.o: shape.cpp shape.h grid.h
# g++ -Wall -g -c shape.cpp
dsexceptions.o: dsexceptions.h
g++ -Wall -g -c dsexceptions.h
BinarySearchTree.o: BinarySearchTree.h dsexceptions.h
g++ -Wall -g -c BinarySearchTree.h
SplayTree.o: SplayTree.h dsexceptions.h
g++ -Wall -g -c SplayTree.h
RedBlackTree.o: RedBlackTree.h dsexceptions.h
g++ -Wall -g -c RedBlackTree.h
AvlTree.o: AvlTree.h dsexceptions.h
g++ -Wall -g -c AvlTree.h
clean:
rm -f main main.exe main.o dsexceptions.o BinarySearchTree.o SplayTree.o RedBlackTree.o AvlTree.o *.gch
You don't want to feed your .h files to the compiler. Only compile the .cpp file, which should include your .h files. (The .gch files are precompiled headers.) You don't need .o files for your headers, just #include them in your .cpp file.
prog1: main.o
g++ -Wall -g -o prog1 main.o
main.o: main.cpp AvlTree.h RedBlackTree.h SplayTree.h BinarySearchTree.h dsexceptions.h
g++ -Wall -g -c main.cpp
clean:
rm -f prog1 main.o
You already have the solution from bstpierre, but just for fun here's my version of your makefile:
CC = g++ -Wall -g -o $#
MODULE = AvlTree BinarySearchTree RedBlackTree SplayTree
OBJECTS = $(addsuffix .o,$(MODULES))
prog1: main.o dsexceptions.o $(OBJECTS)
$(CC) $^
main.o: $(addsuffix .h,$(MODULES))
$(OBJECTS) main.o : %.cpp %.h dsexceptions.h
$(CC) -c $&lt
clean:
rm -f main main.exe *.o *.gch
And just for good measure, here is my SConstruct, because SCons's so much better :)
Program('main.cpp') # Yeah, it's that simple :)
You can look at SCons here.