Makefile for a C++ SDL project - c++

I'm still learning how to set up a Makefile and I'm kind of lost here. I'm using windows and currently trying to fire up my Makefile for small C++ SDL project.
I have 3 .cpp files:
main.cpp
window.cpp
rect.cpp
As well as 2 extra header files:
Window.h
rect.h
So having trouble setting up everything on a Makefile
This is what i currently have:
CXXFLAGS = -Ideps/include -std=c++0x
LXXFLAGS = -Ldeps/lib -lmingw32 -lSDL2main -lSDL2
cup: main.o
g++ main.o -o cup $(LXXFLAGS)
main.o: main.cpp
g++ main.cpp -c $(CXXFLAGS)
window.o: window.cpp
g++ window.cpp -c
rect.o: rect.cpp
g++ rect.cpp -c
But I'm getting a bunch of undefined reference errors for my constructors on my command prompt.
Help please!

From the Makefile contents I read that cup binary is only created from main.o and it does not link window.o nor rect.o, which is where probably those missing references are defined. At the very least I would update the primary rule to say:
cup: main.o window.o rect.o
g++ $(LXXFLAGS) -o cup $^
Thus said, you could make even more use from implicit rules that are built into make, and, if following the standard naming for linking flags, the Makefile could be reduced even further to just a linking line (as compilation rules are implicit), e.g.:
$ cat Makefile
CXXFLAGS = -Ideps/include -std=c++0x
LDFLAGS = -Ldeps/lib
LDLIBS = -lmingw32 -lSDL2main -lSDL2
cup: main.o window.o rect.o
$(LINK.cc) $^ $(LDLIBS) -o $#
Output:
$ make
g++ -Ideps/include -std=c++0x -c -o main.o main.cpp
g++ -Ideps/include -std=c++0x -c -o window.o window.cpp
g++ -Ideps/include -std=c++0x -c -o rect.o rect.cpp
g++ -Ideps/include -std=c++0x -Ldeps/lib main.o window.o rect.o -lmingw32 -lSDL2main -lSDL2 -o cup

Related

Makefile doesn't find libs

I'm trying to write Makefile for my project.
Here is the file structure:
Makefile:
CXXFLAGS = -ISDL2/include -std=c++11
LXXFLAGS = -lSDL2/lib/x86 -lSDL2main -lSDL2 -lSDL2_image
main.exe: main.o BoardField.o ChessPiece.o Game.o
g++ main.o BoardField.o ChessPiece.o Game.o -o main.exe $(LXXFLAGS) -std=c++11
main.o: main.cpp
g++ main.cpp -c $(CXXFLAGS)
BoardField.o: BoardField.cpp
g++ BoardField.cpp -c $(CXXFLAGS)
ChessPiece.o: ChessPiece.cpp
g++ ChessPiece.cpp -c $(CXXFLAGS)
Game.o: Game.cpp
g++ Game.cpp -c $(CXXFLAGS)
And I get these errors:
g++ main.o BoardField.o ChessPiece.o Game.o -o main.exe -lSDL2/lib/x86
-lSDL2main -lSDL2 -lSDL2_image -std=c++11 c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe:
cannot find -lSDL2/lib/x86
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe:
cannot find -lSDL2main
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe:
cannot find -lSDL2
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe:
cannot find -lSDL2_image
Where is the problem?
-lSDL2/lib/x86 is incorrect. You use the lower-case -l option, which is used to add a library to link with, not a path to search for libraries.
To add a path use the upper-case -L option: -LSDL2/lib/x86

Makefile to support c++11

I recently started a small project in C++. I created a simply Makefile:
output: main.o google_api.o
g++ main.o google_api.o -o output
rm *.o
clear
./output
main.o: main.cpp
g++ -c main.cpp
test.o: google_api.cpp google_api.h
g++ -c google_api.cpp
And when I compile my code I get the next error -
non-aggregate type 'vector' cannot be initialized
with an initializer list
I am check for this issue and find that I need to add -std=c++11 support to my makefile to fix the problem. I add this command to the code:
g++ -std=c++11 main.o google_api.o -o output
But this is not make any change. I would love if someone can help me to fix this problem. Thanks
change this:
main.o: main.cpp
g++ -c main.cpp
to:
main.o: main.cpp
g++ -std=c++11 -c main.cpp
You may as well use something like this as basis for your Makefile:
CXX=g++
CXXFLAGS=-g -Wall -MMD -std=c++11
LDLIBS=-lm # list libs here
output: main.o google_api.o
clean:
$(RM) *.o *.d output
-include $(wildcard *.d)
There are also similar questions on stackoverflow: Makefile c++11 support

Create a debug file when compiling each source file separately using makefile

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.

This makefile only creates .o files

I'm trying to practice using Makefiles for a very simple program. The program files are:
main.cpp
other.cpp
other.h
I want the final executable to be Prog.
What happens when I run this is I get a main.o and other.o but no Prog.
What am I missing here?
## file Makefile
CXXOBJECTS= %.o
CXX= g++
CXXSOURCES= main.cpp other.cpp
CXXFLAGS= -std=c++11 -O2
Prog : main.o other.o
main.o : main.cpp
other.o : other.cpp other.h
## eof Makefile
You're almost there. You have the following:
Prog: main.o other.o ## these are your dependencies
g++ main.o other.o -o Prog
This should give you an executable called Prog. Though actually, a better makefile would be this:
CXXOBJECTS= %.o
CXX= g++
CXXSOURCES= main.cpp other.cpp
CXXFLAGS= -std=c++11 -O2
Prog: main.o other.o ## these are your dependencies
CXX main.o other.o -o Prog
main.o : main.cpp
CXX CXXFLAGS -c main.cpp
other.o : other.cpp
CXX CXXFLAGS -c other.cpp
Actually, you can make it even better, but I don't remember the syntactic sugar of makefiles off the top of my head (IDE's :P)

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.