BigBerger
BigBerger

Reputation: 1803

C++ - Makefile using g++

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.

Upvotes: 4

Views: 31714

Answers (2)

Benjamin Bannier
Benjamin Bannier

Reputation: 58547

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).

Upvotes: 4

toth
toth

Reputation: 2552

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.

Upvotes: 5

Related Questions