Before we get into a discussion of make, it would be good to review how to compile projects on Linux. Given three files: main.cpp, greet.cpp, and greet.h, we must undergo two steps to create the executable file "demo".
A044872% g++ -c greet.cpp A044872% g++ -c main.cpp A044872% g++ -o demo greet.o main.o A044872% demo
Note that after issuing the g++ -c greet.cpp command, the object file greet.o will be produced.
|Note: some content on make is copied from the 170 lab|
The idea behind make is that it simplifies the compilation of projects with multiple files. Consider the above example (with two .cpp files). Compared to a single file project, you must issue two additional commands. Now, think about what happens when your project consists of several more files. You will waste a lot of time typing.
This is where make comes in handy. It automates compilation. It checks which files have been modified and based on dependencies (or rules) determines which object files will need to be recompiled. In addition, it saves time by compiling only files that have changed since the last build.
make is a UNIX command that looks for a file called Makefile or makefile. (Makefile is typically preferred because it appears at the beginning of the directory listing). Within the Makefile, there are variables and things called dependencies. A simple make file for the project that we discussed above might look like this:
The red text highlights the explanations.
# leads comments in a line # Build all: default target all : demo # Separate compilation to build object files main.o : main.cpp greet.h g++ -c -ggdb main.cpp greet.o : greet.cpp greet.h g++ -c -ggdb greet.cpp # Linking #demo is a target which depends upon main.o and greet.o #"g++ main.o greet.o -o demo" is the command to produce the executable file #You need to use a TAB before g++ demo : main.o greet.o g++ main.o greet.o -o demo # Testing check : all ./demo # Clean up all build targets so that one may get a clean build clean : rm -f *.o demo
Information on how to use the make command:
main.cpp is the main program greet.cpp and greet.h contain the helper function Makefile contains the build script "make all" or simply "make" to build everything "make clean" to erase all the files built by make "make clean all" to get a clean build "make check" to run the "demo"
Makefile(s) may also contain variables. For instance, if you will be adding additional object files or changing the compiler, it will be easier to use variables and make modifications only in one place in the file. Variables are set using the equal sign as in
CXX=g++Note that by long standing convention, the variable CC is used to define the C compiler to be used. The variable CXX was added to this convention to define the C++ compiler.
To use the variable, it is prefixed by a $ and surrounded by parenthesis as
$(CXX). A Makefile with variables might look something
like the following:
# this is a comment # specify the object files ... OBJ= global.o access.o mem.o rungoal.o sup.o unify.o wexhdr.o # specify the compiler CC = cc # this is the cross platform standard C compiler CXX = g++ # this is the GNU C++ compiler #CXX = CC # Solaris C++ compiler # specify the compiler options CFLAGS = -g # specify compiler preprocessor options CPPFLAGS = -I/usr/local/include # specify linker options LDFLAGS = -L/usr/local/lib # specify the name of the ultimate executable file EXEC = runwex # create the executable $(EXEC): $(OBJ) $(CXX) $(LDFLAGS) -o $(EXEC) $(OBJ) @echo 'runwex has been created' access.o: access.cpp global.cpp globdefs.h allwexhdr.h $(CXX) $(CPPFLAGS) $(CFLAGS) -c access.cpp global.o: global.cpp global.h globdefs.h $(CXX) $(CPPFLAGS) $(CFLAGS) -c global.cpp mem.o: mem.cpp $(CXX) $(CPPFLAGS) $(CFLAGS) -c mem.cpp rungoal.o:rungoal.cpp rungoal.h global.h sup.h $(CXX) $(CPPFLAGS) $(CFLAGS) -c rungoal.cpp sup.o: sup.cpp sup.h $(CXX) $(CPPFLAGS) $(CFLAGS) -c sup.cpp unify.o: unify.cpp globdefs.h $(CXX) $(CPPFLAGS) $(CFLAGS) -c unify.cpp wexhdr.o: wexhdr.cpp $(CXX) $(CPPFLAGS) $(CFLAGS) -c wexhdr.cpp clean: -/bin/rm -f $(EXEC) $(OBJ)
Some comments on this Makefile:
You may have noticed the "@echo" command in the makefile. You can use this to direct, for example, informational or status messages to the console.
Some comments about make:
Some of the comments on this page are specific to the GNU make. The Linux systems only use the GNU version, which can be accessed using either the make command or the gmake command.
Like most UNIX commands, make has a number of command line options. A few of them are as follows:
You can try them out if you like!