C++ - Makefile using g++
Solution 1
This Makefile uses implicit rules which are a great way to reduce duplication.
By default the first target will be built, here all
. It depends on a number
of object files listed in a variable $OBJECTS
, e.g. Proj2.o
who's
dependencies aren't listed in the Makefile. Now if make sees an input file in the current directory
with a matching name, e.g. Proj2.cpp
it will try
to build Proj2.o
from it (there are other implicit rules for sources in
other languages). Proj2.o
would then be built by default with the command
$(CXX) $(CXXFLAGS) -c -o Proj2.o
where $(CXX)
the name of the C++ compiler (g++
in your case).
The explicit build step for all
assembles all the object files into the
target executable.
Looking at above build command you'll notice a small problem in your Makefile. Since the flags to the C++ compiler are given in a variable FLAGS
and not the standard CXXFLAGS
no warnings will be emitted when building the object files. Using the standard name would fix this (you do want warnings, maybe even more than -Wall
gives you).
Solution 2
Make has a set of implicit rules (see here for a reference). For instance
Compiling C++ programs
`n.o' is made automatically from `n.cc' or `n.C' with a command of the form
`$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)'.
Most make's will also use this rule for .cpp files. When make sees there's a x.o requirement for one of your targets, it will try to see if it can generate x.o using implicit rules, and in your case find it can do it starting from a .cpp file.
BigBerger
Updated on March 22, 2020Comments
-
BigBerger about 4 years
I have made a Makefile for my CMSC 202 course project, 'Blackjack'. It does everything I need it to and it works perfectly. You may be asking why I posted here then, this is because I have no idea how it works and I didn't use any other resources but myself to create it.
Here is my Makefile code.
# Object files to either reference or create OBJECTS = Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o # The executable file that will be created at the end EXEC = Proj2.out # The flags to use for compilation FLAGS = -Wall # The code compiler to use for compilation CC = g++ # Perform action on all object files (May or may not exist) all: $(OBJECTS) $(CC) $(FLAGS) -o $(EXEC) $(OBJECTS)
Here is the terminal output when I call
make
in the terminal.g++ -c -o Proj2.o Proj2.cpp g++ -c -o Blackjack.o Blackjack.cpp g++ -c -o Deck.o Deck.cpp g++ -c -o Card.o Card.cpp g++ -c -o Hand.o Hand.cpp g++ -c -o Player.o Player.cpp g++ -Wall -o Proj2.out Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
Can anyone tell me how the .o files are being compiled? It does not look like they are being prompted to be compiled with that
g++ -c -o $.o $.cpp
command anywhere in the Makefile. Nor did I state to use any .cpp files.Thank you in advance for your help.
Edit
Thanks to all your great help, this is now the terminal output I receive when using make.
g++ -Wall -c -o Proj2.o Proj2.cpp g++ -Wall -c -o Blackjack.o Blackjack.cpp g++ -Wall -c -o Deck.o Deck.cpp g++ -Wall -c -o Card.o Card.cpp g++ -Wall -c -o Hand.o Hand.cpp g++ -Wall -c -o Player.o Player.cpp g++ -Wall -o Proj2.out Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
Thank you so much to all of you who have contributed.
-
user26347 about 10 yearsYou're -Wall flag isn't working by the way, you can see it's not being passed to g++ when compiling, which is when you need it.
-
DevSolar about 10 years...and putting it in
CFLAGS
instead ofFLAGS
fixes it. (Although it should beCXXFLAGS
, andCXX
, as it's C++, not C... strange.) -
BigBerger about 10 yearsThanks for the CXXFLAGS tip! Everything works even better now, the compiler links the CXXFLAGS just like you said :)
-
BigBerger about 10 yearsWill changing CC to CXX make the Makefile use the compiler linked in CXX instead of finding it's own? I know it works now, just wondering.
-
-
BigBerger about 10 yearsAwesome thank you for the comment! Aside from this, going on what you wrote "$(CC) $(CFLAGS) -c -o Proj2.o". I have changed my "FLAGS" variable to "CFLAGS" and I used the command "make" again, but the compiler did not use the CFLAGS flag's variables in making the .o objects. Is there a way to have it implicitly use flags without much overhead? Thank you in advance for your time.
-
Benjamin Bannier about 10 years@UnmercifulTurtle: I was editing in the meantime.
CFLAGS
is for the C compiler,CXXFLAGS
for the C++ compiler. Since you compile C++ sources you'll need the latter. Also interesting isLDFLAGS
which are the flags for the linker (but you have that step explicit in above example). -
BigBerger about 10 yearsThank you for the tip! Just made the changes and it works even better now, thanks :)
-
Benjamin Bannier about 10 yearsGreat it helped. Since you are cleaning up why not rename
CC
toCXX
as well since it points to a C++ compiler? With that I'd call that Makefile clean. -
BigBerger about 10 yearsAwesome, just did that! This Makefile is certainly the best I've used, I will be using this format from here on out. If I could check-mark everyone in this thread I would, best cooperation on StackOverflow I've seen in a while :)
-
DevSolar about 10 years@UnmercifulTurtle: If that's the best you've seen so far, you have seen nothing yet. If you excuse me shamelessly advertising my own work, take a look at OSDev Wiki: Makefile tutorial, and once you're done, switch to my preconfigured CMake setup and never look back. ;-)
-
doug65536 about 2 yearsHow does it know to use
$(CXX)
to link? Won't implicit rules just use$(CC)
? It's just a bunch of object files, right? -
Benjamin Bannier about 2 years@doug65536: The snippet in the answer is about the implicit rule creating the object files. The link step was explicit in the question and is using
$(CC)
(which is actuallyg++
).