I am learning how to make Makefile
in g++. I am using the following example The codes for the project is here .This is the Makefile
# Makefile for Writing Make Files Example
# *****************************************************
# Variables to control Makefile operation
CXX = g++
CXXFLAGS = -Wall -g
# ****************************************************
# Targets needed to bring the executable up to date
main: main.o Point.o Rectangle.o # ***Statement : 1
$(CXX) $(CXXFLAGS) -o main main.o Point.o Rectangle.o #Commands underneath dependencies have tabs before them
# The main.o target can be written more simply
main.o: Point.h Rectangle.h # ***Statement : 2
$(CXX) $(CXXFLAGS) -c main.cpp
Point.o: Point.h # ***Statement : 3
Rectangle.o: Rectangle.h Point.h # ***Statement : 4
Now I have some questions regarding this I have also referenced specific lines using the statement keyword for ease of questioning.
1- Is my understanding correct of statement 1. When g++ encounters main.o (which is a dependency for target main.o) after main: it jumps to target main.0 (statement 2) . It then checks the dependency of main.o if the dependency (the two header files are found) it then runs the command.then it comes back up to complete its task for the next dependency and so on ??
2-For dependency of Point.o which is Point.h why is there no command as such
$(CXX) $(CXXFLAGS) -c Point.cpp
and similarly for Rectangle.o why is there no command for its dependency as such
$(CXX) $(CXXFLAGS) -c Rectangle.cpp
I would appreciate it if someone could clarify this.
Correct. It is worth noting that gnu make
uses modification time to determine whether a dependencies are met.
make
has implicit rules for building .o
targets. These use variables such as $CXX
and $CXXFLAGS
. For a given target, say foo.o
, make
will apply a rule depending on the presence of a source file foo.<ext>
, creating a target-dependency pair foo.o : foo.<ext>
. If the extension is a C++ one (eg .cpp
, .cc
, .C
), then it will apply a rule along the lines of
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
You have specified extra dependency for Point.o
. This is added to the implicit dependency Point.cpp
. If the modification time of either Point.h
or Point.cpp
is newer than that of Point.o
, the rule will be run.
As @Basile has pointed out in comments, you can invoke make
with the -p
or --print-data-base
options to get information on the "state" of make, including the implicit rules. Using it with grep, for example, I can query the implicit rules for building .o
files from C++ files:
make -p | grep -A 1 -B 1 COMPILE.cc
Output:
# default
COMPILE.cpp = $(COMPILE.cc)
# makefile (from `Makefile', line 1)
--
--
# default
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
# environment
--
--
# default
COMPILE.C = $(COMPILE.cc)
# environment
--
--
# commands to execute (built-in):
$(COMPILE.cc) $(OUTPUT_OPTION) $<
--
--
# commands to execute (built-in):
$(COMPILE.cc) $(OUTPUT_OPTION) $<
Concerning the rule you extended, Point.o : Point.h
, this is what my version of make would produce:
make -p | grep -A 1 -B 1 Point
....
Point.o: Point.cpp Point.h
# Implicit rule search has been done.
....
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.