Alternate Makefiles can be specified using -f as follows:
make -f Makefile.new
Other targets within a Makefile can be specified by listing them
on the command line:
make clean
make prog1
target: dependency1 dependency2 commandNote that the second line of the rule starts with a single TAB character. Spaces cannot be used instead. If a TAB character is not used at the beginning of the second line of a rule, then make will fail.
make works by executing any rules that it requires to build the target, regardless of the order in which they appear in the Makefile. When it attempts to build a target, it does the following:
clean: /bin/rm -f *.oThis deletes intermediate object (.o) files, and allows the user to clean things up by running make clean.
hw1: hw1.c gcc hw1.c -o hw1Now, any time that they want to compile hw1, they simply type make at the command prompt:
[student@localhost tutorial]$ make gcc hw1.c -o hw1 [student@localhost tutorial]$While this may look simple, make did the following:
[student@localhost tutorial]$ make make: `hw1' is up to date. [student@localhost tutorial]$That is, make found that hw1's dependencies hadn't changed, so hw1 did not need to be rebuilt.
# Primary target: hw2 hw2: main.o Player.o Board.o g++ main.o Player.o Board.o -o hw2 # main program that plays a game main.o: main.cpp g++ -c main.cpp # Class describing a player Player.o: Player.cpp Player.h g++ -c Player.cpp # Class describing the game board Board.o: Board.cpp Board.h g++ -c Board.cppHere is how it looks when the student runs make:
[student@localhost tutorial]$ make g++ -c main.cpp g++ -c Player.cpp g++ -c Board.cpp g++ main.o Player.o Board.o -o hw2 [student@localhost tutorial]$When the student runs make, it finds the first target (hw2), then checks whether the object files main.o, Player.o, and Board.o exist. Since they do not, make recurses: it makes main.o its new target and goes about building it (just like in Example 1), then does the same with Player.o and Board.o. Once these dependencies are satisfied, it runs the command to build hw2.
Suppose that the student identifies a bug in the code, and edits Board.h. When they run make again, here is the result:
[student@localhost tutorial]$ make g++ -c Board.cpp g++ main.o Player.o Board.o -o hw2 [student@localhost tutorial]$That is, make did not recompile main.cpp or Player.cpp because their intermediate .o files were still up to date. make did the minimum amount of work necessary to rebuild hw2.
# Rule to build all targets all: hw1 hw2 # Homework 1: hw1 hw1: hw1.c gcc hw1.c -o hw1 # Homework 2: hw2 hw2: main.o Player.o Board.o g++ main.o Player.o Board.o -o hw2 # main program that plays a game main.o: main.cpp g++ -c main.cpp # Class describing a player Player.o: Player.cpp Player.h g++ -c Player.cpp # Class describing the game board Board.o: Board.cpp Board.h g++ -c Board.cppThe student can now build a particular program by name:
[student@localhost tutorial]$ make hw1 gcc hw1.c -o hw1 [student@localhost tutorial]$...or all targets at once:
[student@localhost tutorial]$ make gcc hw1.c -o hw1 g++ -c main.cpp g++ -c Player.cpp g++ -c Board.cpp g++ main.o Player.o Board.o -o hw2Note that make all would have had the same effect above; the all target was the default because it was found first.
CFLAGS=-Wall -Wunused -ggdb3These flags tell gcc to turn on all standard warnings, plus warnings for unused variables, and to store debugging information for gdb. The variable can be expanded as follows:
hw1: hw1.c
gcc ${CFLAGS} hw1.c -o hw1
This produces the following when executed:
[student@localhost tutorial]$ make hw1 gcc -Wall -Wunused -ggdb3 hw1.c -o hw1 hw1.c: In function `c': hw1.c:25: warning: format argument is not a pointer (arg 2) [student@localhost tutorial]$Note that all such variables must be defined before they are referenced. Also, note that if a variable is not defined in the Makefile, then make will look for an environment variable of that name from your shell. This can be useful, as ${HOME} will expand to your home directory, which can be used to refer to files relative to any user's home.
hw2: main.o Player.o Board.o
g++ main.o Player.o Board.o -o hw2
The result is this:
[student@localhost tutorial]$ make g++ -c -o main.o main.cpp g++ -c -o Player.o Player.cpp g++ -c -o Board.o Board.cpp g++ main.o Player.o Board.o -o hw2 [student@localhost tutorial]$In other words, make successfully guessed how to build each of hw2's dependencies. However, it could have guessed wrong, and probably didn't check whether the .h files had changed, so use this feature sparingly. For more about make and how to make it even more useful, see the complete manual.