KDE Compile HOWTO David Lechnyr, MSW, MCSE+I, CNE
david@lechnyr.com
1.1 2003-06-02 drl Minor updates 1.0 2003-04-23 drl Initial draft Our goal is to optimize KDE for speed. Specifically, faster startup time, better response time and perceived better response. Typically, most distributions include pre-compiled binaries of KDE which are optimized for an Intel i386 computer. Chances are that you're running something faster than this.
Prerequisites For this article, we will assume that you are running a relatively recent version of Linux and have the following programs installed: Automake 1.5 or later Autoconf 2.5 or later make 3.8 or later gcc 3.2 or later Optionally (but strongly recommended) you can install: OpenSSL (if you want SSL support) Perl Compatible Regular Expressions (for better regular-expressions support in Javascript) LibXML2 (for the KDE help system; current is 2.5.7) LessTiff (for Netscape-plugin support in konqueror) You also need to determine which system you're going to be building KDE for. In this example, we'll compile it for a Pentium 3 (-march=pentium3) gnu-linux machine using -O3 code optimization. Note that if instead you have gcc 2.95, the maximum architecture you can specify is -march=i686. Building Qt Qt is a complete and well-developed object-oriented framework for developing graphical user interface (GUI) applications using C++. It is required in order to build KDE. We'll be downloading it directly into /usr/local, so make sure you've uninstalled any previous versions of Qt or archive it elsewhere. # cd /usr/local # wget ftp://ftp.trolltech.com/qt/source/qt-x11-free-[version].tar.bz2 # bunzip2 qt-x11-free-3.1.2.tar.bz2 # tar xvf qt-x11-free-3.1.2.tar # ln -s qt-x11-free-3.1.2 qt This next step assumes you're using the bash(1) shell. If you're not, see the file INSTALL in the Qt source directory. Create the following file, being sure to run it from your login script (.profile or whatever) and `chmod 0755` it: #!/bin/sh QTDIR=/usr/local/qt PATH=$QTDIR/bin:$PATH MANPATH=$MANPATH:$QTDIR/doc/man LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH export QTDIR PATH MANPATH LD_LIBRARY_PATH Next, you'll need to log out and log back in using the account that your ~/.profile is in otherwise the installation of Qt will fail. When compiling Qt, it will ignore the CFLAGS and CXXFLAGS variables (thanks to Wilco Beekhuizen for pointing this out!). Patch mkspecs/linux-g++/qmake.conf using the following (hint: `man patch`): --- ./mkspecs/linux-g++/qmake.conf.orig 2003-05-06 09:03:59.000000000 -0700 +++ ./mkspecs/linux-g++/qmake.conf 2003-05-06 09:04:14.000000000 -0700 @@ -18,7 +18,7 @@ QMAKE_CFLAGS_DEPS = -M QMAKE_CFLAGS_WARN_ON = -Wall -W QMAKE_CFLAGS_WARN_OFF = -w -QMAKE_CFLAGS_RELEASE = -O2 +QMAKE_CFLAGS_RELEASE = -O3 -march=pentium3 QMAKE_CFLAGS_DEBUG = -g QMAKE_CFLAGS_SHLIB = -fPIC QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses Additionally, if you want to enable built-in reading fo GIF images in Qt, you can use the following patch: --- ./src/kernel/qgif.h.orig 2003-05-06 09:07:32.000000000 -0700 +++ ./src/kernel/qgif.h 2003-05-06 09:08:02.000000000 -0700 @@ -50,7 +50,7 @@ #endif // QT_H #ifndef QT_BUILTIN_GIF_READER -#define QT_BUILTIN_GIF_READER 0 +#define QT_BUILTIN_GIF_READER 1 #endif bool qt_builtin_gif_reader(); Next, we can build Qt: ./configure \ -system-zlib \ -qt-gif \ -system-libpng \ -system-libjpeg \ -plugin-imgfmt-mng \ -thread \ -no-nis \ -no-stl \ -no-xinerama \ -no-g++-exceptions $ make Of specific interest, -thread is required for KDE, -no-xinerama is only if you're not using xinerama, and -no-g++-exceptions is recommended by the KDE team. There's no need to run "make install" since we are building this in the final destination directory, which reportedly avoids a lot of build problems with KDE. A brief word about xinerama: Xinerama is an extension introduced with XFree86 4.0 which allows applications and window managers to use the two (or more) physical displays as one large virtual display. Unless you have such use for a multihead setup, you'll want to disable xinerama. For additional details, see http://www.tldp.org/HOWTO/Xinerama-HOWTO/. It's worth noting that since Qt is a library used for building KDE, it's a myth that just optimizing Qt by itself will net you any speed benefits. Building KDE arts arts should be installed before any other KDE package due to dependency issues. $ CFLAGS="-O3 -march=pentium3" CXXFLAGS="-O3 -march=pentium3" ./configure \ --prefix=/opt/kde \ --without-xinerama \ --disable-debug $ make # make install kdelib kdelib should be installed next, also due to package dependencies. $ CFLAGS="-O3 -march=pentium3" CXXFLAGS="-O3 -march=pentium3" ./configure \ --prefix=/opt/kde \ --without-xinerama \ --disable-debug \ --enable-fast-malloc=full \ --disable-libfam \ --enable-dnotify \ --with-ssl-dir=/usr/local/ssl \ --enable-kernel-threads $ make # make install kdebase kdebase comes next. $ CFLAGS="-O3 -march=pentium3" CXXFLAGS="-O3 -march=pentium3" ./configure \ --prefix=/opt/kde \ --without-xinerama \ --disable-debug \ --with-shadow $ make # make install Compling the rest For each remaining package, the following configuration should work nicely. Note that kdeaddons, if installed, should be installed last due to package dependencies. $ CFLAGS="-O3 -march=pentium3" CXXFLAGS="-O3 -march=pentium3" ./configure \ --prefix=/opt/kde \ --without-xinerama \ --disable-debug $ make # make install Post Installation This ensures that nothing bad ever happens to your Qt library path. Modify the file /etc/ld.so.conf and at the top of the file add the following line: /usr/local/qt/lib And as root, rebuild the library cache by running: # ldconfig Finally, create the file /etc/X11/xinit/xinitrc.kde with the following contents (and `chmod 0755` it): #!/bin/sh userresources=$HOME/.Xresources usermodmap=$HOME/.Xmodmap sysresources=/usr/X11R6/lib/X11/xinit/.Xresources sysmodmap=/usr/X11R6/lib/X11/xinit/.Xmodmap # merge in defaults and keymaps if [ -f $sysresources ]; then xrdb -merge $sysresources fi if [ -f $sysmodmap ]; then xmodmap $sysmodmap fi if [ -f $userresources ]; then xrdb -merge $userresources fi if [ -f $usermodmap ]; then xmodmap $usermodmap fi # Start the window manager: startkde And create a link to it: # ln -s /etc/X11/xinit/xinitrc.kde /etc/X11/xinit/xinitrc To run KDE, use your favorite desktop session manager or simply run: $ startx If you run into build problems, try dropping the architecture specification down to an i686 (-march=i686) and/or dropping the optimization down to an -O2 (when in doubt, do both). Additional Tuning You can perform additional tuning (to increase speed) by compiling in AGP and DRI support in your Linux kernel and your XF86Config file. Recompiling XFree86 from scratch doesn't usually provide an increase in speed, although you should be running XFree86 4.3.0 if you're going to all this trouble anyways. As this article is specific to KDE, these steps are not covered here and are left as an exercise to the reader. (Hint: If you think you've got DRI installed, try running `glxinfo | grep render` to verify -- you might be suprised!) If you use -no-xinerama in one package, make sure to use it in all packages (and vice-versa) to prevent speed delays. For non-compiling performance tuning tips for KDE, see http://dforce.sh.cvut.cz/~seli/download/tips.html. Appendix Architecture The info page on gcc 3.2 has this to say about architecture: `-mcpu=CPU-TYPE' Tune to CPU-TYPE everything applicable about the generated code, except for the ABI and the set of available instructions. The choices for CPU-TYPE are `i386', `i486', `i586', `i686', `pentium', `pentium-mmx', `pentiumpro', `pentium2', `pentium3', `pentium4', `k6', `k6-2', `k6-3', `athlon', `athlon-tbird', `athlon-4', `athlon-xp' and `athlon-mp'. While picking a specific CPU-TYPE will schedule things appropriately for that particular chip, the compiler will not generate any code that does not run on the i386 without the `-march=CPU-TYPE' option being used. `i586' is equivalent to `pentium' and `i686' is equivalent to `pentiumpro'. `k6' and `athlon' are the AMD chips as opposed to the Intel ones. `-march=CPU-TYPE' Generate instructions for the machine type CPU-TYPE. The choices for CPU-TYPE are the same as for `-mcpu'. Moreover, specifying `-march=CPU-TYPE' implies `-mcpu=CPU-TYPE'. Optimization The info page on gcc 3.2 has this to say about optimization: `-O',`-O1' Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function. Without `-O', the compiler's goal is to reduce the cost of compilation and to make debugging produce the expected results. Statements are independent: if you stop the program with a breakpoint between statements, you can then assign a new value to any variable or change the program counter to any other statement in the function and get exactly the results you would expect from the source code. With `-O', the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time. `-O2' Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. The compiler does not perform loop unrolling or function inlining when you specify `-O2'. As compared to `-O', this option increases both compilation time and the performance of the generated code. `-O2' turns on all optional optimizations except for loop unrolling, function inlining, and register renaming. It also turns on the `-fforce-mem' option on all machines and frame pointer elimination on machines where doing so does not interfere with debugging. Please note the warning under `-fgcse' about invoking `-O2' on programs that use computed gotos. `-O3' Optimize yet more. `-O3' turns on all optimizations specified by `-O2' and also turns on the `-finline-functions' and `-frename-registers' options. `-O0' Do not optimize. `-Os' Optimize for size. `-Os' enables all `-O2' optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size. If you use multiple `-O' options, with or without level numbers, the last such option is the one that is effective. Pipes The info page on gcc 3.2 has this to say about pipes: `-pipe' Use pipes rather than temporary files for communication between the various stages of compilation. This fails to work on some systems where the assembler is unable to read from a pipe; but the GNU assembler has no trouble. Frame Pointers The info page on gcc 3.2 has this to say about frame pointers: `-fomit-frame-pointer' Don't keep the frame pointer in a register for functions that don't need one. This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions. *It also makes debugging impossible on some machines.* About This Document Copyright (c) 2003 David Lechnyr. Redistribution and use, with or without modification, are permitted provided that the copyright notice, this list of conditions and the following disclaimer be included. THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This document was lovingly handcrafted on a Dell Latitude C400 laptop running Slackware Linux 9.0, in case anyone asks.