This is the documentation of version 1.18. You may want the documentation of the stable version (2.0) or of the well tested 2.1 development snapshot or our homepage.

Using Qt's moc preprocessor

This example shows a makefile for a utility that uses Troll Tech's Qt GUI library. The only thing that's slightly unusual about this is that you must run a preprocessor called moc on most .h files that contain widget definitions, but you don't want to run moc on any .h files that don't use the Q_OBJECT macro.

You could, of course, just list all of the .h files that need to have moc run on them. If you're rapidly developing new widgets, however, it may be something of a nuisance to keep updating the list in the makefile. You can get around the need to list the moc modules explicitly with something like this:

MOC	:= $(QTDIR)/bin/moc
MODULES	:= whatever modules you happen to have in your program
MOC_MODULES := $(patsubst %.h, moc_%, $(shell grep -l Q_OBJECT *.h))
			# Scans all the .h files for the Q_OBJECT macro.

my_program: $(MODULES).o $(MOC_MODULES).o
			# This puts a .o after every word in the two
			# variables; see variable substitution
			# in the manual for details.

	$(CXX) $(inputs) -o $(output)

moc_%.cxx: %.h		# Makes the moc files from the .h files.
	$(MOC) $(input) -o $(output)

%.o: %.cxx
	$(CXX) $(CXXFLAGS) -c $(input) -o $(output)

This approach scans each of your .h files every time makepp is run, looking for the Q_OBJECT macro. This sounds expensive, but it probably won't take long at all.

Another approach is to #include the output from the moc preprocessor in your widget implementation file. This means you have to remember to write the #include, but it has the advantage that there are fewer modules to compile, and so compilation goes faster. (For most C++ compilation, the majority of the time is spent reading the header files, and the output from the preprocessor needs to include almost as many files as your widget anyway.) For example:

// my_widget.h
class MyWidget : public QWidget { 
  Q_OBJECT
// ...
} 

// my_widget.cpp

#include "my_widget.moc"	// my_widget.moc is the output from the
				// moc preprocessor.
// Other implementation things here.
MyWidget::MyWidget(QWidget * parent, const char * name) :
  QWidget(parent, name)
{
 // ...
}

Now you need to have a rule in your makefile to make all the .moc files, like this:

MOC	:= $(QTDIR)/bin/moc
# Rule to make .moc files:
%.moc: %.h
	$(MOC) $(input) -o $(output)

Makepp is smart enough to realize that it needs to make my_widget.moc if it doesn't already exist, or if it's out of date.

This second approach is the one that I usually use because it speeds up compilation.


Gary Holt
Last modified: Wed Aug 23 19:49:21 PDT 2000