C.1.  make and Makefile

[ fromfile: makefile.xml id: makefile ]

You saw, earlier, that qmake (without arguments) reads a project file and builds a Makefile. Example C.1 is a slightly abbreviated look at the Makefile generated from a simple project called qapp.

Example C.1. src/qapp/Makefile-abbreviated

# Exerpts from a makefile

####### Compiler, tools and options

CC            = gcc     # executable for C compiler
CXX           = g++     # executable  for c++ compiler
LINK          = g++     # executable for linker

# flags that get passed to the compiler
CFLAGS        = -pipe -g -Wall -W -D_REENTRANT $(DEFINES)
CXXFLAGS      = -pipe -g -Wall -W -D_REENTRANT $(DEFINES)
INCPATH       = -I/usr/local/qt/mkspecs/default -I. \
                -I$(QT4)/include/QtGui -I$(QT4)/include/QtCore \
                -I$(QT4)/include

# Linker flags
LIBS          = $(SUBLIBS) -L$(QT4)/lib -lQtCore_debug -lQtGui_debug -lpthread
LFLAGS        = -Wl,-rpath,$(QT4)/lib

# macros for performing other operations as part of build steps:
QMAKE         = /usr/local/qt/bin/qmake

####### Files

HEADERS       =    # If we had some, they'd be here. 
SOURCES       = main.cpp
OBJECTS       = main.o
[snip]
QMAKE_TARGET  = qapp
DESTDIR       = 
TARGET        = qapp  # default target to build

first: all            # to build "first" we must build "all"

####### Implicit rules

.SUFFIXES: .c .o .cpp .cc .cxx .C

.cpp.o:
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<

## Possible targets to build

all: Makefile $(TARGET)  # this is how to build "all"

$(TARGET):  $(OBJECTS) $(OBJMOC)    # this is how to build qapp
	$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) \
    $(LIBS)

        qmake:  FORCE               # "qmake" is a target too! 
	@$(QMAKE) -o Makefile qapp.pro  # what does it do?

dist:                               # Another target 
	@mkdir -p .tmp/qapp \
    && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) \ 
       $(FORMS) $(DIST) .tmp/qapp/ \ 
    &&  (cd `dirname .tmp/qapp` \ && $(TAR) qapp.tar qapp \ 
         && $(COMPRESS) qapp.tar) \ 
    && $(MOVE) `dirname .tmp/qapp`/qapp.tar.gz . \ 
    && $(DEL_FILE) -r .tmp/qapp

clean:compiler_clean                # yet another target
	-$(DEL_FILE) $(OBJECTS)
	-$(DEL_FILE) *~ core *.core


####### Dependencies for implicit rules

main.o: main.cpp 

The command make checks the dependencies and performs each build step specified in the Makefile. The name and location of the final result can be set with the project variables, TARGET and target.path. If TARGET is not specified, the name defaults to the name of the directory in which the project file is located. If target.path is not specified, the location defaults to the directory in which the project file is located.

Cleaning Up Files

qmake produces a Makefile that enables make to issue several useful commands (sometimes called "phony" targets.[122] The first of these, make clean, removes any object files and core dump files that may have been produced in the process of building or executing the project.[123]

src/early-examples/example0> make clean
rm -f fac.o
rm -f *~ core *.core
src/early-examples/example0> ls
example0  example0.pro  fac.cpp  Makefile
src/early-examples/example0>
 

The second, make distclean, removes all the files that make clean removes, plus the Makefile and the executable, leaving only the files needed to build the project on a different machine.

src/early-examples/example0> make distclean
rm -f fac.o
rm -f *~ core *.core
rm -f example0
rm -f Makefile
src/early-examples/example0> ls
example0.pro  fac.cpp
src/early-examples/example0> 
 

qmake produces other "phony" targets in the Makefile but the two we just described will be the ones that you use most frequently. You can acquaint yourself with the other targets by examining the Makefile and looking for labels; i.e., lines that begin with an indentifier followed by a colon (e.g., clean: ). To learn more about make, we recommend the book [Rehman03].

[Note] Note

If you modify a project file after the last execution of make, you should run qmake to regenerate the Makefile before your next invocation of make.

[Tip] Tip

The command make dist creates a tarball (dirname.tar.gz) that contains all the source files that the project file knows about.



[122] They are called "phony" to distinguish them from "genuine" targets that are generally filenames such as the name of the executable that is to be produced by the build process.

[123] core dump files are sometimes produced when an executing program encounters a runtime error and is forced to abort. They give a snapshot of main memory at the moment of the crash which may help to identify the cause of the crash.