2.2. Compiling a KDE Program

I am discussing compiling early on so that you may begin programming immediately. I hope that you will key in the source code that is presented, compile it, and play with it as you read. (You can also download the source code from the web site, but typing it in yourself will help familiarize you with class names and conventions that you may miss even in a careful reading.) The concepts that are presented will be clearer to you if you are programming them while you read.

The source code presented in Listing 2.1 is an example of a C++ program that depends on the KDE and Qt libraries. khello is a simple application that says "Hello!"

Example 2.1. khello is a Simple KDE Application that Says "Hello!"

   2  1: #include <qstring.h>
   3  2: #include <kapp.h>
   4  3: #include <klined.h>
   5  4:
   6  5: int main (int argc, char *argv[])
   7  6: {
   8  7: KApplication khello (argc, argv, "khello");
   9  8: KLineEdit *helloeditor = new KLineEdit (0);
  10  9: QString hellostring ("Hello!");
  11 10: helloeditor->setText (hellostring);
  12 11: helloeditor->show();
  13 12:
  14 13: khello.setMainWidget (helloeditor);
  15 14: return khello.exec();

To compile this code, you first need to set the environment variables KDEDIR and QTDIR. KDEDIR should be set to the path where KDE was installed. This is usually /opt/kde, but it is /usr on a Red Hat 6.x system. QTDIR may be /usr/local/lib, /usr/lib, or some other directory. The command to set environment variables differs from shell to shell. If you are using bash, for example, type

   2 QTDIR=/usr/local/libKDEDIR=/opt/kde

If you are using tcsh, type

   2 setenv QTDIR /usr/local/libsetenv KDEDIR /opt/kde

On typical systems, the command to compile the source code given in Listing 2.1 is

   2 g++  khello.cpp -I$KDEDIR/include -I$QTDIR/includeL$KDEDIR/lib -L$QTDIR/lib -lkdeui -lkdecore -ldl -lqt

On a Red Hat 6.x system, the Qt header files are in /usr/include/qt, and the libraries are in /usr/lib, which is checked by g++ by default. You should compile the program using the following command on a Red Hat 6.x system:

   2 g++  khello.cpp -I$KDEDIR/includeI/usr/include/qt -L$KDEDIR/lib -lkdeui -lkdecore -ldl -lqt

The compiler is the GNU C++ compiler, g++. khello.cpp is the name of the source-code file. Listing 2.1 shows that khello.cpp includes header files from the Qt (qlabel.h) and KDE (kapp.h and klined.h) library distributions.

The -I option tells g++ in what directory to look for header files. The -L option tells where, in addition to standard directories, to look for libraries.

   2 g++  khello.cpp -I$KDEDIR/include -I$QTDIR/includeL$KDEDIR/lib -L$QTDIR/lib -lkdecore –lkdeui

khello uses classes from the Qt library and from the KDE libraries libkdecore and libkdeui. The -l option specifies which libraries (in addition to default libraries, such as libc) to link to khello.

khello is shown in Figure 2.2. Its window contains only a line editor with the text "Hello!" in it. You can edit the text and click the close button (the X in the upper-right corner of the window) when you are through.

Figure 2.2. khello is a simple KDE application that says "Hello!"

2.2.1. Using make

The development process usually consists of the following steps:

  1. Edit the source code.

  2. Compile it.

  3. Test the program.

To minimize the overhead involved in compilation—especially on large projects—you can use the make utility. make will

  • Execute compilation commands, which can often be much longer than the one presented previously.

  • Compile only the files that need recompiling. This can save a lot of time when a project consists of more than one file.

By examining source files, make determines which files need recompiling; it checks whether the source files are newer than the object files that they get compiled to and whether the file depends on other files (such as header files) that have been updated. The drawback to using make is that it takes time to describe how the files in your project depend on each other. To see why this is necessary, consider a project that has a source file called mysource.cpp, which #includes a header called myheader.h. If you change mysource.cpp, you want it to be recompiled the next time you execute make. You also want it recompiled if you make any changes to myheader.h, because ultimately, myheader.h becomes part of mysource.cpp. You will see in Chapter 16, "Packaging and Distributing Code," how the standard KDE packaging automates the process of creating a Makefile.

Listing 2.2 gives the Makefile used for compiling Listings 2.3–2.5. This listings are the source code KSimpleApp, a simple KDE application. You should place all four of these files in the same directory and type make to compile the code and create an executable named ksimpleapp. When keying in the Makefile, you need to set the variables QTINC, KDEINC, QTLIB, and KDELIB to their correct values. Sample assignments of these variables are given in Listing 2.2, lines 1–4.Variable assignment in makefiles works the same as you might have guessed from looking at Listing 2.2:

   2 VARIABLE = value

For more information about make, see the man page (i.e., type man make).

From this point in the book, I won't present any more Makefiles. You can adapt this Makefile to compile later source code, or find prepared Makefiles with the source code on the World Wide Web support site.

Example 2.2. The Makefile Used as Input to the make Utility to Compile Listings 2.3–2.5

   2  1: QTINC = -I$(QTDIR)/include
   3  2: KDEINC = -I$(KDEDIR)/include
   4  3: QTLIB = -L$(QTDIR)/lib
   5  4: KDELIB = -L$(KDEDIR)/lib
   6  5: QTBIN = $(QTDIR)/bin
   7  6:
   8  7:  ksimpleapp : ksimpleapp.o main.o
   9  8:     g++ $(QTLIB) $(KDELIB) -lkdeui -lkdecore -lqt -ldl \
  10          main.o ksimpleapp.o -o ksimpleapp
  11  9:
  12 10:  main.o : main.cpp
  13 11:    g++ -c $(QTINC) $(KDEINC) main.cpp
  14 12:
  15 13:  ksimpleapp.moc : ksimpleapp.h
  16 14:  $(QTBIN)/moc ksimpleapp.h > ksimpleapp.moc
  17 15:
  18 16:  ksimpleapp.o : ksimpleapp.cpp ksimpleapp.moc
  19 17:    g++ -c $(QTINC) $(KDEINC) ksimpleapp.cpp