make argument
In this form, make does the following
make
When used with no argument, make does the following
make -f myMakefile
will cause make to use the targets in myMakefile rather than Makefile
Makefile - which has two targets prog1 and prog2
prog1.cc
prog2.cc
prog3.cc
then the following commands will cause the associated action
make will build the target prog1 in the Makefile
make prog1 will build the target prog1 in the Makefile
make prog2 will build the target prog2 in the Makefile
make prog3 will compile and link the file prog3.cc
make prog4 will result in an error message
If there is no Makefile in the directory
make will result in an error message
make prog1 will compile and link the file prog1.cc
make prog2 will compile and link the file prog2.cc
make prog3 will compile and link the file prog3.cc
make prog4 will result in an error message
file1.h file1.cc
file2.h file2.cc
client.cc
Then to accomplish this we could use the following commands
g++ -c file1.cc generates file1.o
g++ -c file2.cc generates file2.o
g++ -c client.cc generates client.o
g++ file1.o file2.o client.o -o mine generates executable mine
rm file1.o file2.o client.o removes object files
Notes:
Simple makefiles consist of 3 kinds of statements
VARIABLE_NAME = <value>
CC = g++
CCFLAGS = -Wall
LDFLAGS = -lm
PRJ = mine
OBJS = file1.o file2.o client.o
HEAD = file1.h file2.h
Dependencies are those files or actions that must be in place prior to using the target. In the example above, mine depends on the object codes and the object codes depend on the header files.
Targets have the following syntax
target name : dependency list
The dependency list may be empty.
We may use the definitions that we created to build these targets and dependencies.
%.o : %.ccNote: the % symbol is a wild card. The above target is used to indicate that .o files, are created from .cc files.
$(PRJ) : $(OBJS)Note: to use the value stored in a definition instead of its name, we enclose the variable in ( ) and precede it with a $.
The above target line could be read as:
mine depends on file1.o file2.o and client.o
file.o : file.h
This indicates that file.o depends on file.h
clean :This is a target without any dependencies.
clean-all : cleanThis target depends on the clean target and so the clean target will be done prior to doing this target
all : prog1 prog2 prog3This target depends on 3 other targets and so all three will be done prior to this target being done
$(CC) -c $(CCFLAGS) $<
Note: g++ -c -Wall XXXX.cc
$(CC) $^ -o $@
Note: g++ file1.o file2.o client.o -o mine
rm -f *.o
rm -f *~ *# .#*
rm -f mine
## definitions
CC = g++
CCFLAGS = -Wall
## targets and dependencies
mine: lib.o class.o client.o ## next line must begin with a TAB
$(CC) $^ -o $@
# rule for compiling .cc to .o
%.o : %.cc ## next line must begin with a TAB
$(CC) -c $(CCFLAGS) $<
lib.o : lib.h
class.o : class.h
client.o : lib.h class.h
clean: ## next lines must begin with a TAB
rm -f *.o
rm -f *~ *% *# .#*
clean-all : clean
rm -f mine
makewith no arguments
make will find the Makefile and execute the first target which is mine.
It will note that this depends on the .o files listed
So it will check each .o file in turn
It will check to see if lib.o exists and is newer than lib.cc and
lib.h. If so no action is taken. If not then lib.cc is compiled
using the executable under the %.o target.
It will do the same for class.o and client.o
Once these are all present and up to date it will perform the executable
that follows this target which will create the executable program mine.
make cleanmake will find the Makefile and the target named clean. Since there are no dependencies, it will immediately execute those executables that follow this target. It will remove all files ending in .o and then remove all temporary files.
make clean-allmake will find the Makefile and the target clean-all. Since this depends on the target clean, it will do the clean target and then remove the executable program mine.
## definitions
CC = g++
CCFLAGS = -Wall
## targets and dependencies
all : prog1 prog2 prog3
prog1 :prog1.o lib1.o class1.o class2.o ## next line must begin with a TAB
$(CC) $^ -o $@
prog2 :prog2.o lib2.o class1.o class3.o ## next line must begin with a TAB
$(CC) $^ -o $@
prog3 : prog3.o lib1.o class2.o ## next line must begin with a TAB
$(CC) $^ -o $@
# default rule for compiling .cc to .o
%.o: %.cc ## next line must begin with a TAB
$(CC) -c $(CCFLAGS) $<
lib1.o : lib1.h ## no executables, the previous rule is used
lib2.o : lib2.h
class1.o : class1.h
class2.o : class2.h class1.h
class3.o : class3.h class1.h lib1.h lib2.h
prog1.o : lib1.h class1.h class2.h
prog2.o : lib2.h class1.h class3.h
prog3.o : lib1.h class2.h
clean: ## next lines must begin with a TAB
rm -f *.o
rm -f *~ *# .#*
clean-all : clean ## next line must begin with a TAB
rm -f prog1 prog2 prog3
makewith no arguments
make will find the Makefile and execute the first target which is all.
It will note that this depends on the prog1 prog2 and prog3 targets
So it will check each of these targets in turn
It will check to see if prog1.o exists and is newer than prog1.cc and
lib1.h, class1.h and class2.h. If so no action is taken. If not then
prog1.cc is compiled using the default rule specified for a .cc file.
It will then check if lib1.o exists and is newer than lib1.cc and lib1.h
and respond as above.
It will then check if lib2.o exists and is newer than lib2.cc and lib2.h
and respond.
It will then check if class1.o exists and is newer than class1.cc and
class1.h and respond.
Finally it will check if class2.o exists and is newer than class2.cc and
class2.h and class1.h and respond as needed.
Once these are all present and up to date it will perform the executable
that follows the prog1 target which will create the executable program prog1
Then it will do the same with the prog2 target and prog3 target.
Note that there is no executable following the all target so once all 3 targets have been done, make terminates. If you had specific test data in files that you wished to use, you could put these tests as executables after the all target. eg
prog1 < datafile
prog2 < datafile1
prog3 < datafile2
make cleanmake will find the Makefile and the target named clean. Since there are no dependencies, it will immediately execute those executables that follow this target and remove all .o files and all temporary files
make prog2make will find the Makefile and the target named prog2. So it will check the dependencies and once everything is up to date, it will create the executable program prog2.
make prog4make will find the Makefile but will not find a target named prog4. So it will look in the current directory for a file named prog4.cc and if found, will use default rules to compile and link it and create the executable program. If not found, an error message is given.
make clean-allmake will find the Makefile and the target clean-all. Since this depends on the target clean, it will do the clean target and then remove all the executable programs listed.